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 6233b87b800335d55b2b2225afe3039286a07ee1..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 @@ -11,5 +18,51 @@ # 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..817e1d7489f3968c2a851e78b1728949776b544d 100644 --- a/CONTRIBUTING.adoc +++ b/CONTRIBUTING.adoc @@ -26,6 +26,7 @@ Merging pull requests once CI is successful: - it is an urgent fix with no large change to logic, then it may be merged after a non-author contributor has approved the review once CI is complete. . Once a PR is ready for review please add the https://github.com/paritytech/substrate/pulls?q=is%3Apr+is%3Aopen+label%3AA0-pleasereview[`pleasereview`] label. Generally PRs should sit with this label for 48 hours in order to garner feedback. It may be merged before if all relevant parties had a look at it. +. If the first review is not an approval, swap `A0-pleasereview` to any label `[A3, A7]` to indicate that the PR has received some feedback, but needs further work. For example. https://github.com/paritytech/substrate/labels/A3-inprogress[`A3-inprogress`] is a general indicator that the PR is work in progress and https://github.com/paritytech/substrate/labels/A4-gotissues[`A4-gotissues`] means that it has significant problems that need fixing. Once the work is done, change the label back to `A0-pleasereview`. You might end up swapping a few times back and forth to climb up the A label group. Once a PR is https://github.com/paritytech/substrate/labels/A8-looksgood[`A8-looksgood`], it is ready to merge. . PRs that break the external API must be tagged with https://github.com/paritytech/substrate/labels/B2-breaksapi[`breaksapi`], when it changes the SRML or consensus of running system with https://github.com/paritytech/substrate/labels/B3-breaksconsensus[`breaksconsensus`] . No PR should be merged until all reviews' comments are addressed. @@ -45,6 +46,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 f69b2f406369e6519d32937b5b303377281a21d3..c3c3e66c12e95e08a4d7012e19e05462e3baa8c4 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,13 @@ 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.12" +version = "0.2.16" 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)", @@ -46,7 +46,7 @@ dependencies = [ [[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)", @@ -54,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)", @@ -70,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]] @@ -96,27 +104,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "arrayvec" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "asn1_der" -version = "0.6.2" +version = "0.6.3" 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)", + "asn1_der_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "asn1_der_derive" -version = "0.1.1" +version = "0.1.2" 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]] @@ -129,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]] @@ -154,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]] @@ -169,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]] @@ -185,25 +193,25 @@ 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)", + "clap 2.33.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]] @@ -211,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" @@ -223,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]] @@ -237,8 +240,8 @@ name = "blake2-rfc" 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)", + "arrayvec 0.4.12 (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]] @@ -279,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]] @@ -303,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]] @@ -337,8 +340,8 @@ 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)", - "iovec 0.1.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.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -346,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)", ] @@ -357,14 +360,13 @@ 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_json 1.0.40 (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.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -374,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]] @@ -390,25 +393,27 @@ dependencies = [ [[package]] name = "cfg-if" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "chain-spec-builder" version = "2.0.0" dependencies = [ - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "node-cli 2.0.0", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-keystore 2.0.0", "substrate-primitives 2.0.0", - "substrate-service 2.0.0", ] [[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)", @@ -420,21 +425,21 @@ 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)", ] [[package]] name = "clap" -version = "2.32.0" +version = "2.33.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.13 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.1.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)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.11.0 (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)", ] @@ -444,7 +449,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]] @@ -452,15 +457,15 @@ 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.38 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -469,7 +474,7 @@ 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.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]] @@ -477,13 +482,13 @@ name = "const-random-macro" 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)", - "rand 0.7.0 (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]] @@ -492,7 +497,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]] @@ -505,7 +510,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]] @@ -515,21 +520,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", - "serde_json 1.0.40 (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.41 (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)", ] @@ -552,15 +557,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" @@ -575,10 +571,10 @@ name = "crossbeam-epoch" 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)", + "arrayvec 0.4.12 (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)", ] @@ -596,8 +592,8 @@ 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]] @@ -610,7 +606,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)", ] @@ -628,11 +624,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)", + "ryu 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -645,11 +641,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]] @@ -658,7 +654,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]] @@ -667,7 +663,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]] @@ -681,14 +677,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]] @@ -696,28 +692,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]] @@ -757,19 +742,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ed25519-dalek" -version = "1.0.0-pre.1" +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.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (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.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 = "ed25519-dalek" +version = "1.0.0-pre.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.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 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)", + "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)", ] [[package]] name = "either" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -786,15 +783,27 @@ 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 = "env_logger" +version = "0.7.0" +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.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]] @@ -802,7 +811,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]] @@ -810,7 +819,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)", ] @@ -819,28 +828,28 @@ 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)", ] [[package]] name = "failure" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (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.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "failure_derive" -version = "0.1.5" +version = "0.1.6" 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)", - "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (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)", + "synstructure 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -853,7 +862,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]] @@ -861,11 +870,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)", + "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.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)", + "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)", ] @@ -875,23 +884,39 @@ 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 = "fixed-hash" +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)", + "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)", + "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.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -917,7 +942,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]] @@ -925,10 +950,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]] @@ -936,8 +961,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]] @@ -950,7 +975,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)", ] @@ -961,21 +986,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]] @@ -983,66 +1008,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)", @@ -1058,8 +1080,8 @@ 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)", + "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1067,7 +1089,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]] @@ -1077,7 +1099,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)", ] @@ -1087,16 +1109,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]] @@ -1114,11 +1137,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]] @@ -1129,10 +1152,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)", @@ -1162,11 +1185,11 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ahash 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ahash 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1179,7 +1202,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]] @@ -1197,19 +1220,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]] @@ -1241,9 +1264,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)", @@ -1257,8 +1290,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)", ] @@ -1269,7 +1302,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)", @@ -1295,19 +1328,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)", + "iovec 0.1.4 (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)", @@ -1315,13 +1348,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" @@ -1332,34 +1377,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.2" 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.5 (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]] @@ -1374,16 +1430,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "iovec" -version = "0.1.2" +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)", - "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)", ] [[package]] name = "ipnet" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1391,7 +1446,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]] @@ -1399,114 +1454,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 = "13.0.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 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.0.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)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (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.41 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (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 = "13.0.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)", - "serde_json 1.0.40 (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.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-core-client" -version = "13.0.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-client-transports 13.0.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 = "13.0.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 = "13.0.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 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 13.0.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.9.0 (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-pubsub" -version = "13.0.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 13.0.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)", + "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.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 = "jsonrpc-server-utils" -version = "13.0.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 13.0.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 = "13.0.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 13.0.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)", + "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]] @@ -1560,10 +1626,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)", ] @@ -1574,11 +1640,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" @@ -1587,7 +1650,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]] @@ -1595,8 +1658,8 @@ 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]] @@ -1605,8 +1668,8 @@ 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)", + "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)", @@ -1634,7 +1697,7 @@ dependencies = [ "tokio-codec 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)", - "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1642,21 +1705,21 @@ name = "libp2p-core" 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)", + "asn1_der 0.6.3 (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)", + "ed25519-dalek 1.0.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (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.5.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)", @@ -1665,11 +1728,11 @@ dependencies = [ "smallvec 0.6.10 (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)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.3 (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)", - "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)", + "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1678,7 +1741,7 @@ 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]] @@ -1686,8 +1749,8 @@ name = "libp2p-deflate" 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)", + "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)", ] @@ -1697,9 +1760,9 @@ name = "libp2p-dns" 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)", + "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.7 (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)", ] @@ -1708,14 +1771,14 @@ name = "libp2p-floodsub" 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)", + "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.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)", @@ -1727,18 +1790,18 @@ 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)", "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.7 (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)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.3 (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)", + "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1746,26 +1809,26 @@ name = "libp2p-kad" 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)", + "arrayvec 0.4.12 (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)", + "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.7 (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.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (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.3 (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)", + "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1775,19 +1838,19 @@ 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)", + "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.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)", "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)", + "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1797,13 +1860,13 @@ 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)", + "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.7 (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)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1812,18 +1875,18 @@ 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)", + "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.7 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.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]] @@ -1832,15 +1895,15 @@ 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)", "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.7 (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)", "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)", + "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1848,7 +1911,7 @@ name = "libp2p-plaintext" 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)", + "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)", ] @@ -1858,11 +1921,11 @@ name = "libp2p-ratelimit" 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)", + "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.7 (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)", ] @@ -1875,14 +1938,14 @@ 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)", + "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.7 (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)", @@ -1890,9 +1953,9 @@ 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]] @@ -1900,12 +1963,12 @@ name = "libp2p-swarm" 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)", + "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)", - "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1914,11 +1977,11 @@ 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)", + "ipnet 2.0.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.7 (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)", @@ -1929,9 +1992,9 @@ name = "libp2p-uds" 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)", + "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.7 (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)", ] @@ -1940,13 +2003,13 @@ name = "libp2p-wasm-ext" 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)", + "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]] @@ -1955,9 +2018,9 @@ 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)", "libp2p-core 0.12.0 (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)", "rw-stream-sink 0.1.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)", @@ -1972,9 +2035,9 @@ name = "libp2p-yamux" 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)", + "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.7 (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)", ] @@ -1985,9 +2048,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]] @@ -2000,7 +2063,21 @@ 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.1" +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)", + "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2008,9 +2085,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)", ] @@ -2057,15 +2134,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]] @@ -2082,7 +2159,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)", ] @@ -2096,7 +2173,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]] @@ -2113,7 +2190,7 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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)", + "hashbrown 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2124,13 +2201,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]] @@ -2141,32 +2218,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.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)", - "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]] @@ -2176,10 +2233,10 @@ 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)", + "iovec 0.1.4 (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)", @@ -2192,7 +2249,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)", ] @@ -2202,8 +2259,8 @@ 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.60 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (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)", ] @@ -2218,17 +2275,22 @@ dependencies = [ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "multimap" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "multistream-select" -version = "0.5.0" +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-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)", + "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2244,13 +2306,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)", - "openssl 0.10.24 (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.25 (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.51 (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)", @@ -2261,9 +2323,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]] @@ -2271,10 +2333,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)", ] @@ -2283,17 +2345,18 @@ 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)", - "jsonrpc-core 13.0.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", @@ -2305,10 +2368,14 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", - "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "srml-transaction-payment 2.0.0", + "structopt 0.3.3 (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", @@ -2318,6 +2385,7 @@ 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", @@ -2336,7 +2404,7 @@ dependencies = [ "node-primitives 2.0.0", "node-runtime 2.0.0", "node-testing 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)", "sr-io 2.0.0", "sr-primitives 2.0.0", "srml-balances 2.0.0", @@ -2347,6 +2415,7 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", + "srml-transaction-payment 2.0.0", "srml-treasury 2.0.0", "substrate-executor 2.0.0", "substrate-primitives 2.0.0", @@ -2354,19 +2423,15 @@ dependencies = [ "substrate-test-client 2.0.0", "substrate-trie 2.0.0", "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wabt 0.7.4 (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)", "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)", "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", ] @@ -2375,21 +2440,12 @@ dependencies = [ name = "node-rpc" version = "2.0.0" dependencies = [ - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.0.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)", "node-primitives 2.0.0", - "node-runtime 2.0.0", - "node-testing 2.0.0", - "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)", "sr-primitives 2.0.0", + "srml-contracts-rpc 2.0.0", + "srml-system-rpc 2.0.0", "substrate-client 2.0.0", - "substrate-keyring 2.0.0", - "substrate-primitives 2.0.0", "substrate-transaction-pool 2.0.0", ] @@ -2397,11 +2453,11 @@ dependencies = [ 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.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 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (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", ] @@ -2412,10 +2468,11 @@ 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-io 2.0.0", "sr-primitives 2.0.0", "sr-staking-primitives 2.0.0", "sr-std 2.0.0", @@ -2426,8 +2483,9 @@ dependencies = [ "srml-balances 2.0.0", "srml-collective 2.0.0", "srml-contracts 2.0.0", + "srml-contracts-rpc-runtime-api 2.0.0", "srml-democracy 2.0.0", - "srml-elections 2.0.0", + "srml-elections-phragmen 2.0.0", "srml-executive 2.0.0", "srml-finality-tracker 2.0.0", "srml-grandpa 2.0.0", @@ -2435,13 +2493,18 @@ dependencies = [ "srml-indices 2.0.0", "srml-membership 2.0.0", "srml-offences 1.0.0", + "srml-randomness-collective-flip 2.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-system-rpc-runtime-api 2.0.0", "srml-timestamp 2.0.0", + "srml-transaction-payment 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", @@ -2449,7 +2512,7 @@ dependencies = [ "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.4", ] [[package]] @@ -2457,19 +2520,19 @@ 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-babe 2.0.0", - "substrate-consensus-babe-primitives 2.0.0", + "substrate-consensus-aura 2.0.0", + "substrate-consensus-aura-primitives 2.0.0", "substrate-executor 2.0.0", "substrate-finality-grandpa 2.0.0", "substrate-finality-grandpa-primitives 2.0.0", @@ -2487,28 +2550,30 @@ 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-babe 2.0.0", + "srml-aura 2.0.0", "srml-balances 2.0.0", "srml-executive 2.0.0", "srml-grandpa 2.0.0", "srml-indices 2.0.0", + "srml-randomness-collective-flip 2.0.0", "srml-sudo 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", + "srml-transaction-payment 2.0.0", "substrate-client 2.0.0", - "substrate-consensus-babe-primitives 2.0.0", + "substrate-consensus-aura-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.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2518,7 +2583,7 @@ dependencies = [ "node-executor 2.0.0", "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)", + "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", @@ -2530,23 +2595,24 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", + "srml-transaction-payment 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.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "nodrop" -version = "0.1.13" +version = "0.1.14" 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]] @@ -2560,9 +2626,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)", ] @@ -2572,7 +2639,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)", ] @@ -2581,8 +2648,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)", ] @@ -2592,7 +2659,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]] @@ -2600,7 +2667,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]] @@ -2620,22 +2687,27 @@ 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]] name = "openssl" -version = "0.10.24" +version = "0.10.25" 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.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2645,13 +2717,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl-sys" -version = "0.9.48" +version = "0.9.51" 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)", ] @@ -2660,15 +2732,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]] @@ -2684,30 +2748,20 @@ 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)", - "unsigned-varint 0.2.2 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2716,37 +2770,36 @@ 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)", "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)", + "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[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)", + "arrayvec 0.4.12 (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]] @@ -2759,27 +2812,23 @@ 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" +version = "0.32.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)", ] [[package]] -name = "parking_lot" -version = "0.5.5" +name = "parity-wasm" +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" @@ -2819,27 +2868,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]] @@ -2847,11 +2885,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]] @@ -2859,14 +2897,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]] @@ -2874,33 +2912,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.5 (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]] @@ -2912,6 +2950,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" @@ -2922,6 +2965,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" @@ -2929,7 +2985,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]] @@ -2943,20 +2999,30 @@ 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.2 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "primitive-types" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fixed-hash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-codec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2964,17 +3030,27 @@ 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-error" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.5 (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 = "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.5 (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]] @@ -2985,19 +3061,75 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro2" +version = "1.0.5" +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.6 (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]] @@ -3012,13 +3144,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]] @@ -3029,12 +3161,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.5 (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)", ] @@ -3044,10 +3184,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]] @@ -3057,9 +3197,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]] @@ -3067,28 +3207,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)", ] @@ -3097,7 +3237,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)", ] @@ -3107,7 +3247,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]] @@ -3115,20 +3255,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]] @@ -3144,7 +3284,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]] @@ -3160,9 +3300,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]] @@ -3172,10 +3312,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]] @@ -3183,8 +3323,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]] @@ -3206,23 +3346,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)", ] @@ -3246,14 +3386,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]] @@ -3266,18 +3405,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]] @@ -3286,9 +3422,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]] @@ -3296,12 +3432,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]] @@ -3309,23 +3445,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]] @@ -3347,26 +3482,36 @@ 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.5 (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)", ] [[package]] name = "ryu" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3379,7 +3524,7 @@ dependencies = [ [[package]] name = "safemem" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3392,26 +3537,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)", - "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)", + "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (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]] @@ -3440,7 +3586,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)", ] @@ -3466,7 +3612,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]] @@ -3481,30 +3627,30 @@ 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.5 (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 = "serde_json" -version = "1.0.40" +version = "1.0.41" 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)", + "ryu 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3515,7 +3661,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]] @@ -3543,7 +3689,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]] @@ -3555,7 +3701,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]] @@ -3596,10 +3742,10 @@ 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_json 1.0.40 (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.41 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3609,7 +3755,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)", ] @@ -3620,7 +3766,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]] @@ -3635,14 +3781,14 @@ 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.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)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 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)", "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]] @@ -3652,11 +3798,11 @@ 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)", @@ -3671,7 +3817,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]] @@ -3680,10 +3826,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", @@ -3691,21 +3838,35 @@ 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.17 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sr-arithmetic" +version = "2.0.0" +dependencies = [ + "integer-sqrt 0.1.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.6 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.6.0 (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-std 2.0.0", + "substrate-debug-derive 2.0.0", ] [[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.2 (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)", + "libsecp256k1 0.3.1 (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)", "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-externalities 2.0.0", "substrate-primitives 2.0.0", "substrate-state-machine 2.0.0", "substrate-trie 2.0.0", @@ -3716,18 +3877,18 @@ dependencies = [ name = "sr-primitives" version = "2.0.0" dependencies = [ - "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)", - "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)", - "serde_json 1.0.40 (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)", + "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)", + "paste 0.1.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)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-arithmetic 2.0.0", "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", ] @@ -3736,19 +3897,19 @@ 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.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", ] @@ -3764,9 +3925,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.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-primitives 2.0.0", "sr-std 2.0.0", ] @@ -3775,8 +3936,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", @@ -3789,10 +3950,10 @@ 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", @@ -3810,16 +3971,17 @@ dependencies = [ name = "srml-authority-discovery" 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-im-online 0.1.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", ] @@ -3827,7 +3989,8 @@ dependencies = [ 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", @@ -3841,15 +4004,16 @@ 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-support 2.0.0", "srml-system 2.0.0", @@ -3857,20 +4021,22 @@ dependencies = [ "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", "srml-support 2.0.0", "srml-system 2.0.0", + "srml-transaction-payment 2.0.0", "substrate-keyring 2.0.0", "substrate-primitives 2.0.0", ] @@ -3879,10 +4045,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", @@ -3898,31 +4064,59 @@ 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", "sr-std 2.0.0", "srml-balances 2.0.0", + "srml-randomness-collective-flip 2.0.0", "srml-support 2.0.0", "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-contracts-rpc" +version = "2.0.0" +dependencies = [ + "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)", + "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", + "srml-contracts-rpc-runtime-api 2.0.0", + "substrate-client 2.0.0", + "substrate-primitives 2.0.0", + "substrate-rpc-primitives 2.0.0", +] + +[[package]] +name = "srml-contracts-rpc-runtime-api" +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-primitives 2.0.0", + "sr-std 2.0.0", + "substrate-client 2.0.0", ] [[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", @@ -3936,10 +4130,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", @@ -3949,12 +4143,29 @@ 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", @@ -3968,9 +4179,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", @@ -3978,6 +4189,7 @@ dependencies = [ "srml-indices 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", + "srml-transaction-payment 2.0.0", "substrate-primitives 2.0.0", ] @@ -3985,8 +4197,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", @@ -4000,8 +4213,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", @@ -4014,8 +4227,8 @@ 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", @@ -4032,8 +4245,8 @@ 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", @@ -4042,6 +4255,7 @@ dependencies = [ "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", ] @@ -4049,10 +4263,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", @@ -4066,8 +4280,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", @@ -4080,8 +4294,8 @@ 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", ] @@ -4090,8 +4304,8 @@ dependencies = [ name = "srml-offences" version = "1.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", @@ -4102,12 +4316,26 @@ dependencies = [ "substrate-primitives 2.0.0", ] +[[package]] +name = "srml-randomness-collective-flip" +version = "2.0.0" +dependencies = [ + "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)", + "sr-io 2.0.0", + "sr-primitives 2.0.0", + "sr-std 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.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", @@ -4121,10 +4349,11 @@ 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", @@ -4141,10 +4370,9 @@ 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", @@ -4152,24 +4380,36 @@ dependencies = [ "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.5 (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", ] @@ -4179,11 +4419,13 @@ 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)", + "log 0.4.8 (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", @@ -4202,7 +4444,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]] @@ -4213,7 +4455,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]] @@ -4222,21 +4464,22 @@ 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", + "sr-primitives 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.17 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4244,9 +4487,10 @@ 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", @@ -4255,12 +4499,41 @@ dependencies = [ "substrate-primitives 2.0.0", ] +[[package]] +name = "srml-system-rpc" +version = "2.0.0" +dependencies = [ + "env_logger 0.7.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)", + "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)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "srml-system-rpc-runtime-api 2.0.0", + "substrate-client 2.0.0", + "substrate-primitives 2.0.0", + "substrate-test-runtime-client 2.0.0", + "substrate-transaction-pool 2.0.0", +] + +[[package]] +name = "srml-system-rpc-runtime-api" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-client 2.0.0", +] + [[package]] 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", @@ -4270,12 +4543,41 @@ dependencies = [ "substrate-primitives 2.0.0", ] +[[package]] +name = "srml-transaction-payment" +version = "2.0.0" +dependencies = [ + "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", + "srml-balances 2.0.0", + "srml-support 2.0.0", + "srml-system 2.0.0", + "substrate-primitives 2.0.0", +] + [[package]] 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", @@ -4302,7 +4604,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)", @@ -4318,27 +4620,28 @@ dependencies = [ [[package]] name = "strsim" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "structopt" -version = "0.2.18" +version = "0.3.3" 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.18 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "structopt-derive" -version = "0.2.18" +version = "0.3.3" 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.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-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (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]] @@ -4354,24 +4657,25 @@ 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]] name = "subkey" version = "2.0.0" dependencies = [ - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.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", "srml-system 2.0.0", + "srml-transaction-payment 2.0.0", "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-primitives 2.0.0", "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4382,7 +4686,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)", ] @@ -4391,20 +4695,45 @@ 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)", - "sr-io 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-io 2.0.0", + "sr-primitives 2.0.0", + "sr-std 2.0.0", + "substrate-primitives 2.0.0", + "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.41 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", - "sr-std 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.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", @@ -4414,9 +4743,9 @@ dependencies = [ 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", @@ -4434,33 +4763,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.41 (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.5 (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)", - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (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.7.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.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)", - "serde_json 1.0.40 (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.41 (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)", + "structopt 0.3.3 (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", @@ -4477,16 +4831,17 @@ dependencies = [ name = "substrate-client" version = "2.0.0" dependencies = [ - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.2 (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.7.0 (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)", + "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.0 (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", @@ -4494,8 +4849,10 @@ 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", @@ -4508,19 +4865,20 @@ dependencies = [ name = "substrate-client-db" version = "2.0.0" dependencies = [ - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.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", @@ -4533,12 +4891,13 @@ dependencies = [ name = "substrate-consensus-aura" 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)", - "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)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.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)", + "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", @@ -4567,7 +4926,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", @@ -4578,20 +4937,22 @@ dependencies = [ name = "substrate-consensus-babe" version = "2.0.0" dependencies = [ - "env_logger 0.6.2 (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.7.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)", - "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", @@ -4604,6 +4965,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", @@ -4620,8 +4982,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", @@ -4633,12 +4995,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)", + "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.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", "sr-std 2.0.0", @@ -4648,15 +5010,43 @@ dependencies = [ "substrate-test-runtime-client 2.0.0", ] +[[package]] +name = "substrate-consensus-pow" +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)", + "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.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", @@ -4676,10 +5066,10 @@ 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", @@ -4694,7 +5084,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", @@ -4703,23 +5093,32 @@ dependencies = [ "substrate-primitives 2.0.0", ] +[[package]] +name = "substrate-debug-derive" +version = "2.0.0" +dependencies = [ + "proc-macro2 1.0.5 (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-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.1 (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", "substrate-client 2.0.0", + "substrate-externalities 2.0.0", "substrate-offchain 2.0.0", "substrate-panic-handler 2.0.0", "substrate-primitives 2.0.0", @@ -4727,37 +5126,48 @@ 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]] +name = "substrate-externalities" +version = "2.0.0" +dependencies = [ + "environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 2.0.0", + "substrate-primitives-storage 2.0.0", ] [[package]] name = "substrate-finality-grandpa" version = "2.0.0" dependencies = [ - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (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)", - "serde_json 1.0.40 (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.41 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "srml-finality-tracker 2.0.0", "substrate-client 2.0.0", "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)", @@ -4770,19 +5180,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", @@ -4792,7 +5211,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)", @@ -4806,11 +5225,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)", - "serde_json 1.0.40 (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.41 (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)", ] @@ -4818,29 +5237,29 @@ 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)", - "env_logger 0.6.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.7.0 (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)", + "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_json 1.0.40 (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.41 (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)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4848,6 +5267,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", @@ -4857,20 +5277,28 @@ dependencies = [ "tempdir 0.3.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)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.3 (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 = [ - "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)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.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.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)", + "num_cpus 1.10.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)", "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", @@ -4880,6 +5308,8 @@ dependencies = [ "substrate-primitives 2.0.0", "substrate-test-runtime-client 2.0.0", "substrate-transaction-pool 2.0.0", + "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4894,21 +5324,32 @@ 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)", + "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)", - "serde_json 1.0.40 (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.41 (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]] @@ -4919,31 +5360,47 @@ 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)", + "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.2 (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.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)", "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-debug-derive 2.0.0", + "substrate-externalities 2.0.0", + "substrate-primitives-storage 2.0.0", "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)", + "tiny-keccak 1.5.0 (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]] +name = "substrate-primitives-storage" +version = "2.0.0" +dependencies = [ + "impl-serde 0.2.2 (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-debug-derive 2.0.0", ] [[package]] @@ -4951,19 +5408,16 @@ 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 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.0.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)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-version 2.0.0", @@ -4972,6 +5426,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", @@ -4979,16 +5435,46 @@ 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.41 (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-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-http-server 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-ws-server 13.0.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.41 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", ] @@ -4997,42 +5483,46 @@ 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.4", ] [[package]] name = "substrate-serializer" version = "2.0.0" dependencies = [ - "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)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] 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_json 1.0.40 (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.41 (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", @@ -5050,8 +5540,9 @@ dependencies = [ "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 0.1.22 (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)", ] @@ -5060,10 +5551,11 @@ dependencies = [ name = "substrate-service-test" version = "2.0.0" dependencies = [ - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (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", @@ -5088,9 +5580,9 @@ dependencies = [ 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)", + "env_logger 0.7.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)", "substrate-primitives 2.0.0", ] @@ -5100,11 +5592,13 @@ name = "substrate-state-machine" version = "2.0.0" dependencies = [ "hash-db 0.15.2 (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)", + "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-externalities 2.0.0", "substrate-panic-handler 2.0.0", "substrate-primitives 2.0.0", "substrate-trie 2.0.0", @@ -5117,14 +5611,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)", + "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.7 (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)", @@ -5137,9 +5631,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)", + "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.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-client 2.0.0", "substrate-client-db 2.0.0", @@ -5154,11 +5648,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)", + "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.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", @@ -5167,6 +5661,7 @@ dependencies = [ "srml-executive 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", + "srml-system-rpc-runtime-api 2.0.0", "srml-timestamp 2.0.0", "substrate-application-crypto 2.0.0", "substrate-client 2.0.0", @@ -5181,7 +5676,7 @@ 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", + "substrate-wasm-builder-runner 1.0.4", "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5189,7 +5684,7 @@ dependencies = [ 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", @@ -5201,13 +5696,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)", - "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)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.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)", - "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", @@ -5217,9 +5712,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)", - "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", @@ -5235,10 +5731,10 @@ version = "2.0.0" dependencies = [ "criterion 0.2.11 (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.0 (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.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-std 2.0.0", "substrate-primitives 2.0.0", "trie-bench 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5249,25 +5745,33 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" -version = "1.0.4" +version = "1.0.8" 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)", + "wasm-gc-api 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "substrate-wasm-builder-runner" -version = "1.0.2" +version = "1.0.4" [[package]] name = "substrate-wasm-builder-runner" -version = "1.0.2" +version = "1.0.4" 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" @@ -5275,12 +5779,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)", @@ -5288,6 +5792,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.5 (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" @@ -5295,20 +5809,31 @@ 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 = "synstructure" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.5 (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)", + "unicode-xid 0.2.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]] @@ -5335,12 +5860,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]] @@ -5348,15 +5873,15 @@ 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]] name = "textwrap" -version = "0.10.0" +version = "0.11.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]] @@ -5364,7 +5889,15 @@ 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]] +name = "threadpool" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5372,9 +5905,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]] @@ -5382,7 +5915,7 @@ 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)", + "failure 0.1.6 (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.1 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5404,8 +5937,8 @@ 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_json 1.0.40 (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.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5414,7 +5947,7 @@ 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)", @@ -5422,12 +5955,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-sync 0.1.6 (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.7 (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)", ] @@ -5437,8 +5970,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]] @@ -5447,7 +5980,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)", ] @@ -5456,7 +5989,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)", ] @@ -5465,9 +5998,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)", ] @@ -5477,7 +6010,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]] @@ -5485,9 +6018,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]] @@ -5496,26 +6029,26 @@ 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)", - "tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5524,8 +6057,8 @@ 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)", - "iovec 0.1.2 (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.4 (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)", "webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5533,11 +6066,11 @@ dependencies = [ [[package]] name = "tokio-sync" -version = "0.1.6" +version = "0.1.7" 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]] @@ -5546,25 +6079,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)", - "iovec 0.1.2 (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.4 (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)", ] @@ -5575,7 +6108,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)", ] @@ -5585,23 +6118,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]] @@ -5610,23 +6143,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)", - "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)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (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]] @@ -5638,8 +6171,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", @@ -5657,7 +6190,7 @@ dependencies = [ "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.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)", "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)", @@ -5670,8 +6203,8 @@ 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.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.7 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.6.1 (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)", ] @@ -5699,15 +6232,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "trybuild" -version = "1.0.9" +version = "1.0.17" 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)", - "serde_json 1.0.40 (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.41 (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]] @@ -5717,15 +6250,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.3.23 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5735,17 +6268,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)", @@ -5763,7 +6291,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)", @@ -5792,7 +6320,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]] @@ -5800,9 +6328,14 @@ 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" +version = "0.2.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)", @@ -5825,9 +6358,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" @@ -5839,24 +6377,14 @@ 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)", - "failure 0.1.5 (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.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5871,22 +6399,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_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)", + "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.41 (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)", ] @@ -5896,7 +6424,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)", ] @@ -5905,129 +6433,146 @@ 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.5 (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.5 (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)", + "failure 0.1.6 (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.5 (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)", ] +[[package]] +name = "wasm-gc-api" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "wasm-timer" -version = "0.1.2" +version = "0.1.3" 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)", + "failure 0.1.6 (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]] @@ -6054,17 +6599,17 @@ 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)", @@ -6084,8 +6629,8 @@ 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.60 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 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)", ] [[package]] @@ -6095,7 +6640,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)", @@ -6117,7 +6662,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]] @@ -6127,28 +6672,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]] @@ -6166,7 +6711,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)", ] @@ -6186,9 +6731,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)", @@ -6198,61 +6743,66 @@ 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 ahash 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "e96e12a0287c75063711e04484e9b140d4a59ec074d3fe5f0b1cc90e0e992665" -"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.16 (registry+https://github.com/rust-lang/crates.io-index)" = "b35dfc96a657c1842b4eb73180b65e37152d4b94d0eb5cb51708aee7826950b4" +"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" -"checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba" -"checksum asn1_der 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bea40e881533b1fe23afca9cd1c1ca022219a10fce604099ecfc96bfa26eaf1a" -"checksum asn1_der_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e7f92edafad155aff997fa5b727c6429b91e996b5a5d62a2b0adbae1306b5fe" +"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +"checksum asn1_der 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6fce6b6a0ffdafebd82c87e79e3f40e8d2c523e5fea5566ff6b90509bf98d638" +"checksum asn1_der_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" "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 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" @@ -6261,27 +6811,26 @@ 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 clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "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 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.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" +"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" @@ -6291,34 +6840,37 @@ dependencies = [ "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 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 ed25519-dalek 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d07e8b8a8386c3b89a7a4b329fdfa4cb545de2545e9e2ebbc3dd3929253e426" +"checksum ed25519-dalek 1.0.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)" = "845aaacc16f01178f33349e7c992ecd0cee095aa5e577f0f4dee35971bd36455" +"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 env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39ecdb7dd54465526f0a56d666e3b2dd5f3a218665a030b6e4ad9e70fa95d8fa" +"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" -"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 failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" +"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" "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.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 fixed-hash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6357b15872f8126e4ea7cf79d579473f132ccd2de239494ad1bf4aa892faea68" +"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" @@ -6327,22 +6879,22 @@ 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" @@ -6350,42 +6902,46 @@ dependencies = [ "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 hashbrown 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bcea5b597dd98e6d1f1ec171744cc5dee1a30d1c23c5b98e3cf9d4fbdf8a526" +"checksum hashbrown 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6587d09be37fb98a11cb08b9000a3f592451c1b1b613ca69d949160e313a430a" "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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a263dc95daa6c3788c8f7133d86dc2ad89ec5a0c56167f9e3441c5f7f33358c4" +"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 iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +"checksum ipnet 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc15ac2e0886d62ba078989ef6920ab23997ab0b04ca5687f1a9a7484296a48" "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 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0bb6fd4acf48d1f17eb7b0e27ab7043c16f063ad0aa7020ec92a431648286c2f" -"checksum jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34d379861584fe4e3678f6ae9ee60b41726df2989578c1dc0f90190dfc92dbe0" -"checksum jsonrpc-core-client 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6b0a3dc76953d88cdb47f5fe4ae21abcabc8d7edf4951ebce42db5c722d6698" -"checksum jsonrpc-derive 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9e2d4475549bc0126690788ed5107573c8917f97db5298f0043fb73d46fc498" -"checksum jsonrpc-http-server 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad55e8dd67c2c5b16436738b0baf319a6b353feba7401dbc1508a0bd8bd451f" -"checksum jsonrpc-pubsub 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "583f5930821dbc043236fe5d672d496ead7ff83d21351146598386c66fe8722a" -"checksum jsonrpc-server-utils 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04f18ca34046c249751fe90428e77e9570beaa03b33a108e74418a586063d07d" -"checksum jsonrpc-ws-server 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aee1265de937bd53ad0fc95ff5817314922ce009fa99a04a09fdf449b140ddf6" +"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.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" @@ -6393,9 +6949,9 @@ dependencies = [ "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.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" @@ -6420,6 +6976,7 @@ dependencies = [ "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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "63cc09b49bf0cc55885982347b174ad89855e97a12284d2c9dcc6da2e20c28f5" "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" @@ -6427,7 +6984,7 @@ 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" @@ -6435,85 +6992,93 @@ dependencies = [ "checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" "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.3 (registry+https://github.com/rust-lang/crates.io-index)" = "304f66c19be2afa56530fa7c39796192eef38618da8d19df725ad7c6d6b2aaae" "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.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51a032ec01abdbe99a1165cd3e518bdd4bd7ca509a59ae9adf186d240399b90c" +"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 nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +"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 openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)" = "8152bb5a9b5b721538462336e3bef9a539f892715e5037fda0f984577311af15" +"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.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2f372b2b53ce10fb823a337aaa674e3a7d072b957c6264d0f4ff0bd86e657449" "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.51 (registry+https://github.com/rust-lang/crates.io-index)" = "ba24190c8f0805d3bd2ce028f439fe5af1d55882bbe6261bed1dbc93b50dd6b1" "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.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ad52817c4d343339b3bc2e26861bd21478eda0b7509acf83505727000512ac" +"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 primitive-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97b5a08dda18910f056e5c2060c034e77cab18e0bd7d895e44f03207af4c71d5" "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-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aeccfe4d5d8ea175d5f0e4a2ad0637e0f4121d63bd99d356fb1f39ab2e7c6097" +"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.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90cf5f418035b98e655e9cdb225047638296b862b42411c4e45bb88d700f7fc0" +"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" @@ -6522,30 +7087,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 ryu 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19d2271fa48eaf61e53cc88b4ad9adcbafa2d512c531e7fadb6dc11a4d3656c5" "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" @@ -6555,9 +7121,9 @@ 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_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" +"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.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" "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" @@ -6574,31 +7140,34 @@ dependencies = [ "checksum snow 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5a64f02fd208ef15bd2d1a65861df4707e416151e1272d02c8faafad1c138100" "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" -"checksum structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" +"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +"checksum structopt 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4f66a4c0ddf7aee4677995697366de0749b0139057342eccbb609b12d0affc" +"checksum structopt-derive 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8fe0c13e476b4e21ff7f5c4ace3818b6d7bdc16897c31c73862471bc1663acae" "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.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bd48273fe9d7f92c1f7d6c1c537bb01c8068f925b47ad2cd8367e11dc32f8550" "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 synstructure 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203" +"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" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" -"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" +"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "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.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" @@ -6611,78 +7180,80 @@ 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-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" "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.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.17 (registry+https://github.com/rust-lang/crates.io-index)" = "e6851bf8351876984fbab8a2391de6378947b898410d8714edd12164d2137127" "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 unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2c64cdf40b4a9645534a943668681bcb219faf51874d4b65d2e0abda1b10a2ab" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +"checksum unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f0023a96687fe169081e8adce3f65e3874426b7886e9234d490af2dc077959" "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 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 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-gc-api 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c32691b6c7e6c14e7f8fd55361a9088b507aa49620fcd06c09b3a1082186b9" +"checksum wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aa3e01d234bb71760e685cfafa5e2c96f8ad877c161a721646356651069e26ac" +"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.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 048bfb7629060bf78327c008b5702eca3f54b685..8d3d04c4d0595efbb48f722186ff09959cdbf42b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,26 +11,32 @@ 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/externalities", "core/finality-grandpa", "core/finality-grandpa/primitives", "core/inherents", @@ -40,12 +46,14 @@ members = [ "core/panic-handler", "core/primitives", "core/rpc", + "core/rpc/primitives", "core/rpc-servers", "core/serializer", "core/service", "core/service/test", "core/session", "core/sr-api-macros", + "core/sr-arithmetic", "core/sr-io", "core/sr-primitives", "core/sr-staking-primitives", @@ -63,6 +71,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", @@ -76,6 +85,7 @@ members = [ "srml/collective", "srml/democracy", "srml/elections", + "srml/elections-phragmen", "srml/example", "srml/executive", "srml/finality-tracker", @@ -87,13 +97,18 @@ members = [ "srml/membership", "srml/metadata", "srml/offences", + "srml/randomness-collective-flip", "srml/scored-pool", "srml/session", "srml/staking", + "srml/staking/reward-curve", "srml/sudo", "srml/system", + "srml/system/rpc", "srml/timestamp", "srml/treasury", + "srml/transaction-payment", + "srml/utility", "node/cli", "node/executor", "node/primitives", diff --git a/Dockerfile b/Dockerfile index 0271db8d1461d7a8c58fb52f9f6306e5ca833e2e..7cba85c544afc2c8cc1ff56401b2172a01d30364 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,20 +5,21 @@ 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 && \ export PATH="$PATH:$HOME/.cargo/bin" && \ rustup toolchain install nightly && \ rustup target add wasm32-unknown-unknown --toolchain nightly && \ - cargo install --git https://github.com/alexcrichton/wasm-gc && \ rustup default nightly && \ rustup default stable && \ cargo build "--$PROFILE" 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..bb23958bced1e0fb2166a28bba738eb9468381cc 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. @@ -184,7 +184,6 @@ curl https://sh.rustup.rs -sSf | sh rustup update nightly rustup target add wasm32-unknown-unknown --toolchain nightly rustup update stable -cargo install --git https://github.com/alexcrichton/wasm-gc ---- You will also need to install the following packages: @@ -193,6 +192,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 @@ -226,13 +230,9 @@ If you are trying to set up Substrate on Windows, you should do the following: rustup update stable rustup target add wasm32-unknown-unknown --toolchain nightly -4. Next, you install wasm-gc, which is used to slim down Wasm files: - - cargo install --git https://github.com/alexcrichton/wasm-gc --force +4. Then, you need to install LLVM: https://releases.llvm.org/download.html -5. Then, you need to install LLVM: https://releases.llvm.org/download.html - -6. Next, you need to install OpenSSL, which we will do with `vcpkg`: +5. Next, you need to install OpenSSL, which we will do with `vcpkg`: mkdir \Tools cd \Tools @@ -241,14 +241,14 @@ If you are trying to set up Substrate on Windows, you should do the following: .\bootstrap-vcpkg.bat .\vcpkg.exe install openssl:x64-windows-static -7. After, you need to add OpenSSL to your System Variables: +6. After, you need to add OpenSSL to your System Variables. Note that in order for the following commands to work, you need to use Windows Powershell: $env:OPENSSL_DIR = 'C:\Tools\vcpkg\installed\x64-windows-static' $env:OPENSSL_STATIC = 'Yes' [System.Environment]::SetEnvironmentVariable('OPENSSL_DIR', $env:OPENSSL_DIR, [System.EnvironmentVariableTarget]::User) [System.Environment]::SetEnvironmentVariable('OPENSSL_STATIC', $env:OPENSSL_STATIC, [System.EnvironmentVariableTarget]::User) -8. Finally, you need to install `cmake`: https://cmake.org/download/ +7. Finally, you need to install `cmake`: https://cmake.org/download/ ==== Shared Steps @@ -277,13 +277,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 +294,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 +321,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 +335,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,12 +380,45 @@ 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 You can generate documentation for a Substrate Rust package and have it automatically open in your web browser using https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html#using-rustdoc-with-cargo[rustdoc with Cargo], -(of the The Rustdoc Book), by running the the following command: +(of the The Rustdoc Book), by running the following command: ``` cargo doc --package --open 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..b0113718b5ed0ab0048f064654af2f4781696b0e 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,26 @@ 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}; use test_client::{ TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, runtime::{TestAPI, app_crypto::ed25519::{AppPair, AppPublic}}, @@ -67,7 +67,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..b4ada5425b40042184c63c3b327febdea46a759b 100644 --- a/core/application-crypto/src/lib.rs +++ b/core/application-crypto/src/lib.rs @@ -21,7 +21,7 @@ #![cfg_attr(not(feature = "std"), no_std)] #[doc(hidden)] -pub use primitives::{self, crypto::{CryptoType, Public, Derive, IsWrappedBy, Wraps}}; +pub use primitives::{self, crypto::{CryptoType, Public, Derive, IsWrappedBy, Wraps}, RuntimeDebug}; #[doc(hidden)] #[cfg(feature = "std")] pub use primitives::crypto::{SecretStringError, DeriveJunction, Ss58Codec, Pair}; @@ -88,22 +88,13 @@ macro_rules! app_crypto { } fn derive< Iter: Iterator - >(&self, path: Iter) -> Result { - self.0.derive(path).map(Self) + >(&self, path: Iter, seed: Option) -> Result<(Self, Option), Self::DeriveError> { + self.0.derive(path, seed).map(|x| (Self(x.0), x.1)) } fn from_seed(seed: &Self::Seed) -> Self { Self(<$pair>::from_seed(seed)) } fn from_seed_slice(seed: &[u8]) -> Result { <$pair>::from_seed_slice(seed).map(Self) } - fn from_standard_components< - I: Iterator - >( - seed: &str, - password: Option<&str>, - path: I, - ) -> Result { - <$pair>::from_standard_components::(seed, password, path).map(Self) - } fn sign(&self, msg: &[u8]) -> Self::Signature { Signature(self.0.sign(msg)) } @@ -139,10 +130,12 @@ macro_rules! app_crypto { $crate::wrap!{ /// A generic `AppPublic` wrapper type over $public crypto; this has no specific App. #[derive( - Clone, Default, Eq, PartialEq, Ord, PartialOrd, $crate::codec::Encode, + Clone, Default, Eq, PartialEq, Ord, PartialOrd, + $crate::codec::Encode, $crate::codec::Decode, + $crate::RuntimeDebug, )] - #[cfg_attr(feature = "std", derive(Debug, Hash))] + #[cfg_attr(feature = "std", derive(Hash))] pub struct Public($public); } @@ -213,6 +206,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 { @@ -238,8 +232,12 @@ macro_rules! app_crypto { $crate::wrap! { /// A generic `AppPublic` wrapper type over $public crypto; this has no specific App. - #[derive(Clone, Default, Eq, PartialEq, $crate::codec::Encode, $crate::codec::Decode)] - #[cfg_attr(feature = "std", derive(Debug, Hash))] + #[derive(Clone, Default, Eq, PartialEq, + $crate::codec::Encode, + $crate::codec::Decode, + $crate::RuntimeDebug, + )] + #[cfg_attr(feature = "std", derive(Hash))] pub struct Signature($sig); } diff --git a/core/application-crypto/src/sr25519.rs b/core/application-crypto/src/sr25519.rs index af112dc70ee7e6b1c669dae7c5edd6e65dfa59e3..40f6c6b22ec0234030dd65d4fa00a68c3e694a4e 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,26 @@ 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}; use test_client::{ TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, runtime::{TestAPI, app_crypto::sr25519::{AppPair, AppPublic}}, @@ -67,7 +67,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..66e6cd6579b106aea5c75c4043394e642d9448f9 100644 --- a/core/application-crypto/src/traits.rs +++ b/core/application-crypto/src/traits.rs @@ -14,10 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use primitives::crypto::{KeyTypeId, CryptoType, IsWrappedBy, Public}; #[cfg(feature = "std")] use primitives::crypto::Pair; +use codec::Codec; +use primitives::crypto::{KeyTypeId, CryptoType, IsWrappedBy, Public}; +use rstd::fmt::Debug; + /// An application-specific key. pub trait AppKey: 'static + Send + Sync + Sized + CryptoType + Clone { /// The corresponding type as a generic crypto type. @@ -37,23 +40,25 @@ pub trait AppKey: 'static + Send + Sync + Sized + CryptoType + Clone { const ID: KeyTypeId; } -/// Type which implements Debug and Hash in std, not when no-std (std variant). +/// Type which implements Hash in std, not when no-std (std variant). #[cfg(feature = "std")] -pub trait MaybeDebugHash: std::fmt::Debug + std::hash::Hash {} +pub trait MaybeHash: std::hash::Hash {} #[cfg(feature = "std")] -impl MaybeDebugHash for T {} +impl MaybeHash for T {} -/// Type which implements Debug and Hash in std, not when no-std (no-std variant). +/// Type which implements Hash in std, not when no-std (no-std variant). #[cfg(not(feature = "std"))] -pub trait MaybeDebugHash {} +pub trait MaybeHash {} #[cfg(not(feature = "std"))] -impl MaybeDebugHash for T {} +impl MaybeHash for T {} /// A application's public key. -pub trait AppPublic: AppKey + Public + Ord + PartialOrd + Eq + PartialEq + MaybeDebugHash + codec::Codec { +pub trait AppPublic: + AppKey + Public + Ord + PartialOrd + Eq + PartialEq + Debug + MaybeHash + codec::Codec +{ /// The wrapped type which is just a plain instance of `Public`. type Generic: - IsWrappedBy + Public + Ord + PartialOrd + Eq + PartialEq + MaybeDebugHash + codec::Codec; + IsWrappedBy + Public + Ord + PartialOrd + Eq + PartialEq + Debug + MaybeHash + codec::Codec; } /// A application's key pair. @@ -64,15 +69,15 @@ pub trait AppPair: AppKey + Pair::Public> { } /// A application's signature. -pub trait AppSignature: AppKey + Eq + PartialEq + MaybeDebugHash { +pub trait AppSignature: AppKey + Eq + PartialEq + Debug + MaybeHash { /// The wrapped type which is just a plain instance of `Signature`. - type Generic: IsWrappedBy + Eq + PartialEq + MaybeDebugHash; + type Generic: IsWrappedBy + Eq + PartialEq + Debug + MaybeHash; } /// 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 + Debug + MaybeHash + Eq + PartialEq + Clone; /// Returns all public keys for the given key type in the keystore. fn all(key_type: KeyTypeId) -> crate::Vec; @@ -95,9 +100,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 + Debug + MaybeHash + Eq + PartialEq + Clone; /// Returns all public keys for this application in the keystore. fn all() -> crate::Vec; @@ -118,3 +126,4 @@ pub trait RuntimeAppPublic: Sized { /// Verify that the given signature matches the given message using this public key. fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool; } + diff --git a/core/authority-discovery/Cargo.toml b/core/authority-discovery/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..7283e07f89ca7878b2d69e356e7f63ca3547031b --- /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.41" +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/src/lib.rs b/core/authority-discovery/primitives/src/lib.rs index 556b758aa61fce4165875df1e5fd33eb04d3df7e..7c56dc6ca4ca6b26c97be661b36370a174a3916a 100644 --- a/core/authority-discovery/primitives/src/lib.rs +++ b/core/authority-discovery/primitives/src/lib.rs @@ -19,8 +19,15 @@ #![cfg_attr(not(feature = "std"), no_std)] use client::decl_runtime_apis; -use codec::Codec; use rstd::vec::Vec; +use sr_primitives::RuntimeDebug; + +#[derive(codec::Encode, codec::Decode, Eq, PartialEq, Clone, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] +pub struct Signature(pub Vec); +#[derive(codec::Encode, codec::Decode, Eq, PartialEq, Clone, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] +pub struct AuthorityId(pub Vec); decl_runtime_apis! { /// The authority discovery api. @@ -29,21 +36,15 @@ decl_runtime_apis! { /// 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 { - /// 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; - + 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, authority_id: AuthorityId) -> Option>; + 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: Vec, authority_id: AuthorityId) -> bool; + 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..1a3c56affb661dd5e4a2a4a93cf06000a7f6bffc --- /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.41" +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 60% rename from core/service/src/chain_spec.rs rename to core/chain-spec/src/chain_spec.rs index 1683876c3f86ff7bd5833a488f0b43c1e1fd04dc..0f69654b9e8f6cf217e1d54c8dbf8d0fb0ef03b3 100644 --- a/core/service/src/chain_spec.rs +++ b/core/chain-spec/src/chain_spec.rs @@ -20,18 +20,19 @@ use std::borrow::Cow; use std::collections::HashMap; use std::fs::File; use std::path::PathBuf; +use std::rc::Rc; 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; enum GenesisSource { File(PathBuf), Binary(Cow<'static, [u8]>), - Factory(fn() -> G), + Factory(Rc G>), } impl Clone for GenesisSource { @@ -39,7 +40,7 @@ impl Clone for GenesisSource { match *self { GenesisSource::File(ref path) => GenesisSource::File(path.clone()), GenesisSource::Binary(ref d) => GenesisSource::Binary(d.clone()), - GenesisSource::Factory(f) => GenesisSource::Factory(f), + GenesisSource::Factory(ref f) => GenesisSource::Factory(f.clone()), } } } @@ -53,14 +54,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,8 +70,8 @@ impl GenesisSource { } } -impl<'a, G: RuntimeGenesis> BuildStorage for &'a ChainSpec { - fn build_storage(self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { +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(), Genesis::Raw(map, children_map) => Ok(( @@ -82,7 +84,10 @@ 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()) } } @@ -98,28 +103,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(), @@ -128,7 +144,7 @@ impl Clone for ChainSpec { } } -impl ChainSpec { +impl ChainSpec { /// A list of bootnode addresses. pub fn boot_nodes(&self) -> &[String] { &self.spec.boot_nodes @@ -154,14 +170,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() } @@ -170,61 +182,73 @@ 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. - pub fn from_genesis( + pub fn from_genesis G + 'static>( name: &str, id: &str, - constructor: fn() -> G, + constructor: F, 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), + genesis: GenesisSource::Factory(Rc::new(constructor)), } } } -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, }; @@ -251,6 +275,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.iter().map(|(a, b)| (a.clone().into_bytes(), b.clone().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..a2723484ad4c11f39cbbd53b662b00c9ad1ba761 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.33.0" +derive_more = "0.15.0" +env_logger = "0.7.0" +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.41" 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.3.3" +rpassword = "4.0.1" [dev-dependencies] -tempdir = "0.3" +tempdir = "0.3.7" diff --git a/core/cli/src/execution_strategy.rs b/core/cli/src/execution_strategy.rs index bd3030906ec09fdea7d3707d0387926055cce96f..93236227e5d640983c58139f316afc81f003ab30 100644 --- a/core/cli/src/execution_strategy.rs +++ b/core/cli/src/execution_strategy.rs @@ -16,7 +16,7 @@ #![allow(missing_docs)] -use structopt::clap::{arg_enum, _clap_count_exprs}; +use structopt::clap::arg_enum; arg_enum! { /// How to execute blocks diff --git a/core/cli/src/informant.rs b/core/cli/src/informant.rs index b5a2f03d795461a75e2ad0f02084875fed395bcb..f7c23ba47918a42363c960ec1a3d4bef0f97accf 100644 --- a/core/cli/src/informant.rs +++ b/core/cli/src/informant.rs @@ -16,36 +16,29 @@ //! 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; +use std::time::Duration; 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(); - let display_notifications = service.network_status().for_each(move |(net_status, _)| { - let info = client.info(); - display.display(&info, net_status); - Ok(()) - }); + let display_notifications = service + .network_status(Duration::from_millis(5000)) + .for_each(move |(net_status, _)| { + let info = client.info(); + display.display(&info, net_status); + Ok(()) + }); let client = service.client(); let mut last_best = { @@ -57,19 +50,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..b49f686ae62f7c3f7e271229933d13e5e738bbe7 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; @@ -65,19 +68,15 @@ use substrate_telemetry::TelemetryEndpoints; /// The maximum number of characters for a node name. const NODE_NAME_MAX_LENGTH: usize = 32; -/// The file name of the node's Secp256k1 secret key inside the chain-specific -/// network config directory, if neither `--node-key` nor `--node-key-file` -/// is specified in combination with `--node-key-type=secp256k1`. -const NODE_KEY_SECP256K1_FILE: &str = "secret"; - /// The file name of the node's Ed25519 secret key inside the chain-specific /// network config directory, if neither `--node-key` nor `--node-key-file` /// is specified in combination with `--node-key-type=ed25519`. const NODE_KEY_ED25519_FILE: &str = "secret_ed25519"; /// Executable version. Used to pass version information from the root crate. +#[derive(Clone)] pub struct VersionInfo { - /// Implemtation name. + /// Implementaiton name. pub name: &'static str, /// Implementation version. pub version: &'static str, @@ -121,8 +120,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 +192,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 +264,25 @@ 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>, + E: Into, RP: StructOpt + Clone, C: Default, G: RuntimeGenesis, - E: IntoExit, - RS: FnOnce(E, RunCmd, RP, Configuration) -> Result<(), String> + CE: ChainSpecExtension, + Exit: IntoExit, + RS: FnOnce(Exit, RunCmd, RP, Configuration) -> Result<(), E> { - 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 +296,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 +324,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 +350,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,16 +363,22 @@ 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.wasm_method = self.params.wasm_method.into(); config.execution_strategies = ExecutionStrategies { importing: self.params.execution.into(), other: self.params.execution.into(), @@ -377,7 +394,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 +408,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 +460,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

) @@ -509,14 +489,6 @@ where P: AsRef { match params.node_key_type { - NodeKeyType::Secp256k1 => - params.node_key.as_ref().map(parse_secp256k1_secret).unwrap_or_else(|| - Ok(params.node_key_file - .or_else(|| net_config_file(net_config_dir, NODE_KEY_SECP256K1_FILE)) - .map(network::config::Secret::File) - .unwrap_or(network::config::Secret::New))) - .map(NodeKeyConfig::Secp256k1), - NodeKeyType::Ed25519 => params.node_key.as_ref().map(parse_ed25519_secret).unwrap_or_else(|| Ok(params.node_key_file @@ -539,14 +511,6 @@ fn invalid_node_key(e: impl std::fmt::Display) -> error::Error { error::Error::Input(format!("Invalid node key: {}", e)) } -/// Parse a Secp256k1 secret key from a hex string into a `network::Secret`. -fn parse_secp256k1_secret(hex: &String) -> error::Result { - H256::from_str(hex).map_err(invalid_node_key).and_then(|bytes| - network::config::identity::secp256k1::SecretKey::from_bytes(bytes) - .map(network::config::Secret::Input) - .map_err(invalid_node_key)) -} - /// Parse a Ed25519 secret key from a hex string into a `network::Secret`. fn parse_ed25519_secret(hex: &String) -> error::Result { H256::from_str(&hex).map_err(invalid_node_key).and_then(|bytes| @@ -556,8 +520,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 +551,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 +596,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 +613,14 @@ fn fill_config_keystore_password( Ok(()) } -fn create_run_node_config( - cli: RunCmd, spec_factory: S, impl_name: &'static str, version: &VersionInfo -) -> error::Result> +fn create_run_node_config( + cli: RunCmd, spec_factory: S, impl_name: &'static str, version: &VersionInfo, +) -> 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()); @@ -690,13 +656,6 @@ where config.database_path = db_path(&base_path, config.chain_spec.id()); config.database_cache_size = cli.database_cache_size; config.state_cache_size = cli.state_cache_size; - 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()))? - ), - }; let is_dev = cli.shared_params.dev; @@ -709,6 +668,30 @@ where service::Roles::FULL }; + // by default we disable pruning if the node is an authority (i.e. + // `ArchiveAll`), otherwise we keep state for the last 256 blocks. if the + // node is an authority and pruning is enabled explicitly, then we error + // unless `unsafe_pruning` is set. + config.pruning = match cli.pruning { + Some(ref s) if s == "archive" => PruningMode::ArchiveAll, + None if role == service::Roles::AUTHORITY => PruningMode::ArchiveAll, + None => PruningMode::default(), + Some(s) => { + if role == service::Roles::AUTHORITY && !cli.unsafe_pruning { + return Err(error::Error::Input( + "Validators should run with state pruning disabled (i.e. archive). \ + You can ignore this check with `--unsafe-pruning`.".to_string() + )); + } + + PruningMode::keep_blocks(s.parse() + .map_err(|_| error::Error::Input("Invalid pruning mode specified".to_string()))? + ) + }, + }; + + config.wasm_method = cli.wasm_method.into(); + let exec = cli.execution_strategies; let exec_all_or = |strat: params::ExecutionStrategy| exec.execution.unwrap_or(strat).into(); config.execution_strategies = ExecutionStrategies { @@ -792,15 +775,16 @@ 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() { + if spec.boot_nodes().is_empty() && !cli.disable_default_bootnode { let base_path = base_path(&cli.shared_params, version); let storage_path = network_path(&base_path, spec.id()); let node_key = node_key_config(cli.node_key_params, &Some(storage_path))?; @@ -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); @@ -930,7 +915,9 @@ fn init_logger(pattern: &str) { writeln!(buf, "{}", output) }); - builder.init(); + if builder.try_init().is_err() { + info!("Not registering Substrate logger, as there is already a global logger registered!"); + } } fn kill_color(s: &str) -> String { @@ -944,7 +931,7 @@ fn kill_color(s: &str) -> String { mod tests { use super::*; use tempdir::TempDir; - use network::config::identity::{secp256k1, ed25519}; + use network::config::identity::ed25519; #[test] fn tests_node_name_good() { @@ -967,7 +954,6 @@ mod tests { NodeKeyType::variants().into_iter().try_for_each(|t| { let node_key_type = NodeKeyType::from_str(t).unwrap(); let sk = match node_key_type { - NodeKeyType::Secp256k1 => secp256k1::SecretKey::generate().to_bytes().to_vec(), NodeKeyType::Ed25519 => ed25519::SecretKey::generate().as_ref().to_vec() }; let params = NodeKeyParams { @@ -976,9 +962,6 @@ mod tests { node_key_file: None }; node_key_config(params, &net_config_dir).and_then(|c| match c { - NodeKeyConfig::Secp256k1(network::config::Secret::Input(ref ski)) - if node_key_type == NodeKeyType::Secp256k1 && - &sk[..] == ski.to_bytes() => Ok(()), NodeKeyConfig::Ed25519(network::config::Secret::Input(ref ski)) if node_key_type == NodeKeyType::Ed25519 && &sk[..] == ski.as_ref() => Ok(()), @@ -1004,8 +987,6 @@ mod tests { node_key_file: Some(file.clone()) }; node_key_config(params, &net_config_dir).and_then(|c| match c { - NodeKeyConfig::Secp256k1(network::config::Secret::File(ref f)) - if node_key_type == NodeKeyType::Secp256k1 && f == &file => Ok(()), NodeKeyConfig::Ed25519(network::config::Secret::File(ref f)) if node_key_type == NodeKeyType::Ed25519 && f == &file => Ok(()), _ => Err(error::Error::Input("Unexpected node key config".into())) @@ -1038,8 +1019,6 @@ mod tests { let typ = params.node_key_type; node_key_config::(params, &None) .and_then(|c| match c { - NodeKeyConfig::Secp256k1(network::config::Secret::New) - if typ == NodeKeyType::Secp256k1 => Ok(()), NodeKeyConfig::Ed25519(network::config::Secret::New) if typ == NodeKeyType::Ed25519 => Ok(()), _ => Err(error::Error::Input("Unexpected node key config".into())) @@ -1053,9 +1032,6 @@ mod tests { let typ = params.node_key_type; node_key_config(params, &Some(net_config_dir.clone())) .and_then(move |c| match c { - NodeKeyConfig::Secp256k1(network::config::Secret::File(ref f)) - if typ == NodeKeyType::Secp256k1 && - f == &dir.join(NODE_KEY_SECP256K1_FILE) => Ok(()), NodeKeyConfig::Ed25519(network::config::Secret::File(ref f)) if typ == NodeKeyType::Ed25519 && f == &dir.join(NODE_KEY_ED25519_FILE) => Ok(()), diff --git a/core/cli/src/params.rs b/core/cli/src/params.rs index 72adc552b9ecd86d6f5dfcff1f37989e2075bff7..4480736066400805036575c893b6ebfc0717b30e 100644 --- a/core/cli/src/params.rs +++ b/core/cli/src/params.rs @@ -17,8 +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 client; +use structopt::{StructOpt, clap::{arg_enum, App, AppSettings, SubCommand, Arg}}; pub use crate::execution_strategy::ExecutionStrategy; @@ -44,6 +43,24 @@ impl Into for ExecutionStrategy { } } +arg_enum! { + /// How to execute Wasm runtime code + #[allow(missing_docs)] + #[derive(Debug, Clone)] + pub enum WasmExecutionMethod { + // Uses an interpreter. + Interpreted, + } +} + +impl Into for WasmExecutionMethod { + fn into(self) -> service::config::WasmExecutionMethod { + match self { + WasmExecutionMethod::Interpreted => service::config::WasmExecutionMethod::Interpreted, + } + } +} + arg_enum! { /// Whether off-chain workers are enabled. #[allow(missing_docs)] @@ -58,11 +75,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 +87,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 +101,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, @@ -122,7 +150,6 @@ arg_enum! { #[allow(missing_docs)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum NodeKeyType { - Secp256k1, Ed25519 } } @@ -136,10 +163,6 @@ pub struct NodeKeyParams { /// The value is a string that is parsed according to the choice of /// `--node-key-type` as follows: /// - /// `secp256k1`: - /// The value is parsed as a hex-encoded Secp256k1 32 bytes secret key, - /// i.e. 64 hex characters. - /// /// `ed25519`: /// The value is parsed as a hex-encoded Ed25519 32 bytes secret key, /// i.e. 64 hex characters. @@ -170,18 +193,12 @@ pub struct NodeKeyParams { /// /// The node's secret key determines the corresponding public key and hence the /// node's peer ID in the context of libp2p. - /// - /// NOTE: The current default key type is `secp256k1` for a transition period only - /// but will eventually change to `ed25519` in a future release. To continue using - /// `secp256k1` keys, use `--node-key-type=secp256k1`. #[structopt( long = "node-key-type", value_name = "TYPE", - raw( - possible_values = "&NodeKeyType::variants()", - case_insensitive = "true", - default_value = r#""Ed25519""# - ) + possible_values = &NodeKeyType::variants(), + case_insensitive = true, + default_value = "Ed25519" )] pub node_key_type: NodeKeyType, @@ -190,9 +207,6 @@ pub struct NodeKeyParams { /// The contents of the file are parsed according to the choice of `--node-key-type` /// as follows: /// - /// `secp256k1`: - /// The file must contain an unencoded 32 bytes Secp256k1 secret key. - /// /// `ed25519`: /// The file must contain an unencoded 32 bytes Ed25519 secret key. /// @@ -209,7 +223,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, } @@ -220,11 +234,9 @@ pub struct ExecutionStrategies { #[structopt( long = "execution-syncing", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategy::variants()", - case_insensitive = "true", - default_value = r#""NativeElseWasm""# - ) + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + default_value = "NativeElseWasm" )] pub execution_syncing: ExecutionStrategy, @@ -232,11 +244,9 @@ pub struct ExecutionStrategies { #[structopt( long = "execution-import-block", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategy::variants()", - case_insensitive = "true", - default_value = r#""NativeElseWasm""# - ) + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + default_value = "NativeElseWasm" )] pub execution_import_block: ExecutionStrategy, @@ -244,11 +254,9 @@ pub struct ExecutionStrategies { #[structopt( long = "execution-block-construction", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategy::variants()", - case_insensitive = "true", - default_value = r#""Wasm""# - ) + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + default_value = "Wasm" )] pub execution_block_construction: ExecutionStrategy, @@ -256,11 +264,9 @@ pub struct ExecutionStrategies { #[structopt( long = "execution-offchain-worker", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategy::variants()", - case_insensitive = "true", - default_value = r#""Native""# - ) + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + default_value = "Native" )] pub execution_offchain_worker: ExecutionStrategy, @@ -268,11 +274,9 @@ pub struct ExecutionStrategies { #[structopt( long = "execution-other", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategy::variants()", - case_insensitive = "true", - default_value = r#""Native""# - ) + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + default_value = "Native" )] pub execution_other: ExecutionStrategy, @@ -280,17 +284,15 @@ pub struct ExecutionStrategies { #[structopt( long = "execution", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategy::variants()", - case_insensitive = "true", - conflicts_with_all = "&[ - \"execution_other\", - \"execution_offchain_worker\", - \"execution_block_construction\", - \"execution_import_block\", - \"execution_syncing\", - ]" - ) + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + conflicts_with_all = &[ + "execution-other", + "execution-offchain-worker", + "execution-block-construction", + "execution-import-block", + "execution-syncing", + ] )] pub execution: Option, } @@ -298,39 +300,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, @@ -339,44 +345,74 @@ 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. - #[structopt(long = "rpc-cors", value_name = "ORIGINS", parse(try_from_str = "parse_cors"))] + /// + /// 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 state pruning mode, a number of blocks to keep or 'archive'. + /// + /// Default is to keep all block states if the node is running as a + /// validator (i.e. 'archive'), otherwise state is only kept for the last + /// 256 blocks. #[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 + /// Force start with unsafe pruning settings. + /// + /// When running as a validator it is highly recommended to disable state + /// pruning (i.e. 'archive') which is the default. The node will refuse to + /// start as a validator if pruning is enabled unless this option is set. + #[structopt(long = "unsafe-pruning")] + pub unsafe_pruning: bool, + + /// 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. - #[structopt(long = "telemetry-url", value_name = "URL VERBOSITY", parse(try_from_str = "parse_telemetry_endpoints"))] + /// 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", - raw( - possible_values = "&OffchainWorkerEnabled::variants()", - case_insensitive = "true", - default_value = r#""WhenValidating""# - ) + possible_values = &OffchainWorkerEnabled::variants(), + case_insensitive = true, + default_value = "WhenValidating" )] pub offchain_worker: OffchainWorkerEnabled, + /// Method for executing Wasm runtime code. + #[structopt( + long = "wasm-execution", + value_name = "METHOD", + possible_values = &WasmExecutionMethod::variants(), + case_insensitive = true, + default_value = "Interpreted" + )] + pub wasm_method: WasmExecutionMethod, + #[allow(missing_docs)] #[structopt(flatten)] pub execution_strategies: ExecutionStrategies, @@ -408,14 +444,14 @@ pub struct RunCmd { /// Use interactive shell for entering the password used by the keystore. #[structopt( long = "password-interactive", - raw(conflicts_with_all = "&[ \"password\", \"password_filename\" ]") + conflicts_with_all = &[ "password", "password-filename" ] )] pub password_interactive: bool, /// Password used by the keystore. #[structopt( long = "password", - raw(conflicts_with_all = "&[ \"password_interactive\", \"password_filename\" ]") + conflicts_with_all = &[ "password-interactive", "password-filename" ] )] pub password: Option, @@ -424,7 +460,7 @@ pub struct RunCmd { long = "password-filename", value_name = "PATH", parse(from_os_str), - raw(conflicts_with_all = "&[ \"password_interactive\", \"password\" ]") + conflicts_with_all = &[ "password-interactive", "password" ] )] pub password_filename: Option } @@ -441,7 +477,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()) @@ -562,6 +602,13 @@ pub struct BuildSpecCmd { #[structopt(long = "raw")] pub raw: bool, + /// Disable adding the default bootnode to the specification. + /// + /// By default the `/ip4/127.0.0.1/tcp/30333/p2p/NODE_PEER_ID` bootnode is added to the + /// specification when no bootnode exists. + #[structopt(long = "disable-default-bootnode")] + pub disable_default_bootnode: bool, + #[allow(missing_docs)] #[structopt(flatten)] pub shared_params: SharedParams, @@ -580,11 +627,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, @@ -606,7 +657,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, @@ -614,15 +667,23 @@ pub struct ImportBlocksCmd { #[structopt(flatten)] pub shared_params: SharedParams, + /// Method for executing Wasm runtime code. + #[structopt( + long = "wasm-execution", + value_name = "METHOD", + possible_values = &WasmExecutionMethod::variants(), + case_insensitive = true, + default_value = "Interpreted" + )] + pub wasm_method: WasmExecutionMethod, + /// The means of execution used when calling into the runtime while importing blocks. #[structopt( long = "execution", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategy::variants()", - case_insensitive = "true", - default_value = r#""NativeElseWasm""# - ) + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + default_value = "NativeElseWasm" )] pub execution: ExecutionStrategy, } @@ -697,11 +758,13 @@ impl StructOpt for CoreParams where ) ).subcommand( BuildSpecCmd::augment_clap(SubCommand::with_name("build-spec")) - .about("Build a spec.json file, outputing to stdout.") + .about("Build a spec.json file, outputting to stdout.") ) .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 9edb9b1c85d356dfcdef34073544bd96f4b413ab..5a0afd2d6f72a8eebe47eecd30aaa9dfcce30f6f 100644 --- a/core/client/Cargo.toml +++ b/core/client/Cargo.toml @@ -5,12 +5,13 @@ 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 } @@ -26,12 +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" -tempfile = "3.1" +env_logger = "0.7.0" +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"] @@ -43,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 89a1dcc0cbc8ae43da1ef07654410c77676f7790..7d88c39d7fd7ed18635cd5c6253202c65ba127e9 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.2" } +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.7.0" [features] default = [] diff --git a/core/client/db/src/cache/list_cache.rs b/core/client/db/src/cache/list_cache.rs index 188012e78f0cffb288b384250a59ad99b91023a7..7a4fcc448e0e55970141b294e31fe387ef69c89b 100644 --- a/core/client/db/src/cache/list_cache.rs +++ b/core/client/db/src/cache/list_cache.rs @@ -39,7 +39,7 @@ //! Finalized entry E1 is pruned when block B is finalized so that: //! EntryAt(B.number - prune_depth).points_to(E1) -use std::collections::BTreeSet; +use std::collections::{BTreeSet, BTreeMap}; use log::warn; @@ -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). @@ -80,6 +89,9 @@ pub enum CommitOperation { /// - new entry is finalized AND/OR /// - some forks are destroyed BlockFinalized(ComplexBlockId, Option>, BTreeSet), + /// When best block is reverted - contains the forks that have to be updated + /// (they're either destroyed, or their best entry is updated to earlier block). + BlockReverted(BTreeMap>>), } /// Single fork of list-based cache. @@ -107,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| { @@ -117,7 +133,7 @@ impl> ListCache ListCache { storage, - prune_depth, + pruning_strategy, best_finalized_block, best_finalized_entry, unfinalized, @@ -320,6 +336,44 @@ impl> ListCache Ok(Some(operation)) } + /// When block is reverted. + pub fn on_block_revert>( + &self, + tx: &mut Tx, + reverted_block: &ComplexBlockId, + ) -> ClientResult> { + // can't revert finalized blocks + debug_assert!(self.best_finalized_block.number < reverted_block.number); + + // iterate all unfinalized forks and truncate/destroy if required + let mut updated = BTreeMap::new(); + for (index, fork) in self.unfinalized.iter().enumerate() { + // we only need to truncate fork if its head is ancestor of truncated block + if fork.head.valid_from.number < reverted_block.number { + continue; + } + + // we only need to truncate fork if its head is connected to truncated block + if !chain::is_connected_to_block(&self.storage, reverted_block, &fork.head.valid_from)? { + continue; + } + + let updated_fork = fork.truncate( + &self.storage, + tx, + reverted_block.number, + self.best_finalized_block.number, + )?; + updated.insert(index, updated_fork); + } + + // schedule commit operation and update meta + let operation = CommitOperation::BlockReverted(updated); + tx.update_meta(self.best_finalized_entry.as_ref(), &self.unfinalized, &operation); + + Ok(operation) + } + /// When transaction is committed. pub fn on_transaction_commit(&mut self, op: CommitOperation) { match op { @@ -353,6 +407,14 @@ impl> ListCache self.unfinalized.remove(*fork_index); } }, + CommitOperation::BlockReverted(forks) => { + for (fork_index, updated_fork) in forks.into_iter().rev() { + match updated_fork { + Some(updated_fork) => self.unfinalized[fork_index] = updated_fork, + None => { self.unfinalized.remove(fork_index); }, + } + } + }, } } @@ -362,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(()), @@ -515,6 +582,43 @@ impl Fork { best_finalized_block, ) } + + /// Truncate fork by deleting all entries that are descendants of given block. + pub fn truncate, Tx: StorageTransaction>( + &self, + storage: &S, + tx: &mut Tx, + reverting_block: NumberFor, + best_finalized_block: NumberFor, + ) -> ClientResult>> { + let mut current = self.head.valid_from.clone(); + loop { + // read pointer to previous entry + let entry = storage.require_entry(¤t)?; + + // truncation stops when we have reached the ancestor of truncated block + if current.number < reverting_block { + // if we have reached finalized block => destroy fork + if chain::is_finalized_block(storage, ¤t, best_finalized_block)? { + return Ok(None); + } + + // else fork needs to be updated + return Ok(Some(Fork { + best_block: None, + head: entry.into_entry(current), + })); + } + + tx.remove_storage_entry(¤t); + + // truncation also stops when there are no more entries in the list + current = match entry.prev_valid_from { + Some(prev_valid_from) => prev_valid_from, + None => return Ok(None), + }; + } + } } /// Destroy fork by deleting all unfinalized entries. @@ -669,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] @@ -679,7 +783,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(&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] @@ -689,7 +793,7 @@ 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) + 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 @@ -700,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 @@ -710,7 +814,7 @@ 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) + 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 @@ -726,7 +830,7 @@ pub mod tests { .with_header(test_header(3)) .with_header(test_header(4)) .with_header(fork_header(0, 2, 3)), - 1024, test_id(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 @@ -743,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 @@ -756,7 +860,7 @@ 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) + 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 @@ -771,7 +875,7 @@ pub mod tests { .with_header(test_header(3)) .with_header(test_header(4)) .with_header(fork_header(0, 2, 3)), - 1024, test_id(2) + PruningStrategy::ByDepth(1024), test_id(2) ).value_at_block(&fork_id(0, 2, 3)).unwrap(), Some((correct_id(2), None, 2))); } @@ -781,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), @@ -790,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), @@ -805,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(); @@ -830,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(), @@ -856,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(), @@ -871,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); @@ -884,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(), @@ -894,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(), @@ -912,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(), @@ -940,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(), @@ -955,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(), @@ -969,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!( @@ -989,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(), @@ -1004,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 @@ -1043,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 @@ -1060,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] @@ -1080,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()); } @@ -1341,32 +1445,98 @@ 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] + fn revert_block_works() { + // 1 -> (2) -> 3 -> 4 -> 5 + // \ + // -> 5'' + // \ + // -> (3') -> 4' -> 5' + let mut cache = ListCache::new( + DummyStorage::new() + .with_meta(Some(correct_id(1)), vec![correct_id(5), fork_id(1, 2, 5), fork_id(2, 4, 5)]) + .with_id(1, correct_id(1).hash) + .with_entry(correct_id(1), StorageEntry { prev_valid_from: None, value: 1 }) + .with_entry(correct_id(3), StorageEntry { prev_valid_from: Some(correct_id(1)), value: 3 }) + .with_entry(correct_id(4), StorageEntry { prev_valid_from: Some(correct_id(3)), value: 4 }) + .with_entry(correct_id(5), StorageEntry { prev_valid_from: Some(correct_id(4)), value: 5 }) + .with_entry(fork_id(1, 2, 4), StorageEntry { prev_valid_from: Some(correct_id(1)), value: 14 }) + .with_entry(fork_id(1, 2, 5), StorageEntry { prev_valid_from: Some(fork_id(1, 2, 4)), value: 15 }) + .with_entry(fork_id(2, 4, 5), StorageEntry { prev_valid_from: Some(correct_id(4)), value: 25 }) + .with_header(test_header(1)) + .with_header(test_header(2)) + .with_header(test_header(3)) + .with_header(test_header(4)) + .with_header(test_header(5)) + .with_header(fork_header(1, 2, 3)) + .with_header(fork_header(1, 2, 4)) + .with_header(fork_header(1, 2, 5)) + .with_header(fork_header(2, 4, 5)), + PruningStrategy::ByDepth(1024), correct_id(1) + ); + + // when 5 is reverted: entry 5 is truncated + let op = cache.on_block_revert(&mut DummyTransaction::new(), &correct_id(5)).unwrap(); + assert_eq!(op, CommitOperation::BlockReverted(vec![ + (0, Some(Fork { best_block: None, head: Entry { valid_from: correct_id(4), value: 4 } })), + ].into_iter().collect())); + cache.on_transaction_commit(op); + + // when 3 is reverted: entries 4+5' are truncated + let op = cache.on_block_revert(&mut DummyTransaction::new(), &correct_id(3)).unwrap(); + assert_eq!(op, CommitOperation::BlockReverted(vec![ + (0, None), + (2, None), + ].into_iter().collect())); + cache.on_transaction_commit(op); + + // when 2 is reverted: entries 4'+5' are truncated + let op = cache.on_block_revert(&mut DummyTransaction::new(), &correct_id(2)).unwrap(); + assert_eq!(op, CommitOperation::BlockReverted(vec![ + (0, None), + ].into_iter().collect())); + cache.on_transaction_commit(op); } } diff --git a/core/client/db/src/cache/list_storage.rs b/core/client/db/src/cache/list_storage.rs index a7bfc4dd5856f63934409f6b0abf631e582d8a62..4fd9ecaced25e7afc699fdf0f5c6f05aa4e199a6 100644 --- a/core/client/db/src/cache/list_storage.rs +++ b/core/client/db/src/cache/list_storage.rs @@ -227,6 +227,14 @@ mod meta { unfinalized.remove(*fork_index); } }, + CommitOperation::BlockReverted(ref forks) => { + for (fork_index, updated_fork) in forks.iter().rev() { + match updated_fork { + Some(updated_fork) => unfinalized[*fork_index] = &updated_fork.head().valid_from, + None => { unfinalized.remove(*fork_index); }, + } + } + }, } (finalized, unfinalized).encode() diff --git a/core/client/db/src/cache/mod.rs b/core/client/db/src/cache/mod.rs index 68245a54eeeacf3a2bc29a1c37aae2bb509cf3b5..9aaea57b0cdb240ed650221fb1554ad5412e63a3 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(), ) }) @@ -208,7 +207,7 @@ impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> { // prepare list of caches that are not update // (we might still need to do some cache maintenance in this case) let missed_caches = self.cache.cache_at.keys() - .filter(|cache| !data_at.contains_key(cache.clone())) + .filter(|cache| !data_at.contains_key(*cache)) .cloned() .collect::>(); @@ -269,6 +268,27 @@ impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> { Ok(self) } + + /// When block is reverted. + pub fn on_block_revert( + mut self, + reverted_block: &ComplexBlockId, + ) -> ClientResult { + for (name, cache) in self.cache.cache_at.iter() { + let op = cache.on_block_revert( + &mut self::list_storage::DbStorageTransaction::new( + cache.storage(), + &mut self.tx + ), + reverted_block, + )?; + + assert!(!self.cache_at_op.contains_key(name)); + self.cache_at_op.insert(name.to_owned(), op); + } + + Ok(self) + } } /// Synchronous implementation of database-backed blockchain data cache. @@ -299,8 +319,8 @@ impl BlockchainCache for DbCacheSync { key: &CacheKeyId, at: &BlockId, ) -> Option<((NumberFor, Block::Hash), Option<(NumberFor, Block::Hash)>, Vec)> { - let cache = self.0.read(); - let storage = cache.cache_at.get(key)?.storage(); + 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 { @@ -335,3 +355,17 @@ impl BlockchainCache for DbCacheSync { } } +/// 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 927359ecdf70e9648c44c96f5863d5561c7825df..0f765506a31ef583e6b2617a26a020c7161d1892 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,20 +208,31 @@ 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, - E: CodeExecutor + RuntimeInfo, + E: CodeExecutor + RuntimeInfo, S: BuildStorage, { 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)>, @@ -409,12 +456,11 @@ impl BlockImportOperation { } impl client::backend::BlockImportOperation -for BlockImportOperation -where Block: BlockT, + for BlockImportOperation 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 +470,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 +485,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 +494,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 +519,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 +539,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 +601,7 @@ pub struct DbChangesTrieStorage { db: Arc, meta: Arc, Block::Hash>>>, min_blocks_to_keep: Option, + cache: RwLock>>, _phantom: ::std::marker::PhantomData, } @@ -562,6 +613,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 +737,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 +774,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 +818,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 +833,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 +904,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 +927,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 +940,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 +994,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 +1012,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 +1040,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 +1068,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 +1114,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 +1156,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 +1212,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 +1263,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 +1316,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 +1328,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 +1340,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 +1349,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 +1381,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 +1421,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 +1466,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 +1502,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); @@ -1432,6 +1518,12 @@ impl client::backend::Backend for Backend whe impl client::backend::LocalBackend for Backend where Block: BlockT {} +/// TODO: remove me in #3201 +pub fn unused_sink(cache_tx: crate::cache::DbCacheTransaction) { + cache_tx.on_block_revert(&crate::cache::ComplexBlockId::new(Default::default(), 0.into())).unwrap(); + unimplemented!() +} + #[cfg(test)] mod tests { use hash_db::{HashDB, EMPTY_PREFIX}; @@ -1443,6 +1535,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>; @@ -1471,7 +1565,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![ @@ -1481,7 +1574,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, }; @@ -1495,7 +1588,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 @@ -2014,6 +2107,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. @@ -2026,11 +2120,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]); @@ -2038,11 +2128,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()); @@ -2050,11 +2136,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]); @@ -2062,11 +2144,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()); @@ -2077,16 +2155,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()); @@ -2094,6 +2169,98 @@ 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_tree_route_regression() { + // NOTE: this is a test for a regression introduced in #3665, the result + // of tree_route would be erroneously computed, since it was taking into + // account the `ancestor` in `CachedHeaderMetadata` for the comparison. + // in this test we simulate the same behavior with the side-effect + // triggering the issue being eviction of a previously fetched record + // from the cache, therefore this test is dependent on the LRU cache + // size for header metadata, which is currently set to 5000 elements. + let backend = Backend::::new_test(10000, 10000); + let blockchain = backend.blockchain(); + + let genesis = insert_header(&backend, 0, Default::default(), Vec::new(), Default::default()); + + let block100 = (1..=100).fold(genesis, |parent, n| { + insert_header(&backend, n, parent, Vec::new(), Default::default()) + }); + + let block7000 = (101..=7000).fold(block100, |parent, n| { + insert_header(&backend, n, parent, Vec::new(), Default::default()) + }); + + // This will cause the ancestor of `block100` to be set to `genesis` as a side-effect. + lowest_common_ancestor(blockchain, genesis, block100).unwrap(); + + // While traversing the tree we will have to do 6900 calls to + // `header_metadata`, which will make sure we will exhaust our cache + // which only takes 5000 elements. In particular, the `CachedHeaderMetadata` struct for + // block #100 will be evicted and will get a new value (with ancestor set to its parent). + let tree_route = tree_route(blockchain, block100, block7000).unwrap(); + + assert!(tree_route.retracted().is_empty()); + } + #[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 2ee2c2ec545316947bfe424c9ab2c935fed6c19e..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>; @@ -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(); @@ -1030,26 +1109,37 @@ 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) - let mut genesis_hash = None; - insert_block(&db, HashMap::new(), || { - let header = default_header(&Default::default(), 0); - genesis_hash = Some(header.hash()); - header - }); + // 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 + // 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..a8c3886020e271daac7fafb9a75cbe4cd4e2548b --- /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.hash != from.hash { + 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)] +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 f4a4f8a4aa9c653fb946de860bf2291ca4c7cac1..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. @@ -139,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..05a2a8eba1c3eacb06578fd7a59269d7cd2fa9fa 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::OffchainExt, H256, Blake2Hasher, NativeOrEncoded, NeverNativeValue, + traits::{CodeExecutor, KeystoreExt}, +}; use crate::runtime_api::{ProofRecorder, InitializeBlock}; use crate::backend; @@ -45,15 +47,13 @@ where /// Execute a call to a contract on top of state in a block of given hash. /// /// No changes are made. - fn call< - O: offchain::Externalities, - >( + fn call( &self, id: &BlockId, method: &str, call_data: &[u8], strategy: ExecutionStrategy, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, ) -> Result, error::Error>; /// Execute a contextual call on top of state in a block of a given hash. @@ -63,14 +63,13 @@ where /// of the execution context. fn contextual_call< 'a, - O: offchain::Externalities, IB: Fn() -> error::Result<()>, EM: Fn( Result, Self::Error>, 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, @@ -81,7 +80,7 @@ where initialize_block: InitializeBlock<'a, B>, execution_manager: ExecutionManager, native_call: Option, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, proof_recorder: &Option>>>, enable_keystore: bool, ) -> error::Result> where ExecutionManager: Clone; @@ -95,14 +94,13 @@ where /// /// No changes are made. fn call_at_state< - O: offchain::Externalities, S: state_machine::Backend, F: FnOnce( Result, Self::Error>, - Result, Self::Error> + 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, @@ -110,8 +108,15 @@ where call_data: &[u8], manager: ExecutionManager, native_call: Option, - side_effects_handler: Option<&mut O>, - ) -> Result<(NativeOrEncoded, (S::Transaction, H::Out), Option>), error::Error>; + side_effects_handler: Option, + ) -> Result< + ( + NativeOrEncoded, + (S::Transaction, H::Out), + Option>> + ), + error::Error, + >; /// Execute a call to a contract on top of given state, gathering execution proof. /// @@ -182,22 +187,22 @@ impl Clone for LocalCallExecutor where E: Clone { impl CallExecutor for LocalCallExecutor where B: backend::Backend, - E: CodeExecutor + RuntimeInfo, + E: CodeExecutor + RuntimeInfo, Block: BlockT, { type Error = E::Error; - fn call( + fn call( &self, id: &BlockId, method: &str, call_data: &[u8], strategy: ExecutionStrategy, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, ) -> 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, @@ -205,7 +210,7 @@ where &self.executor, method, call_data, - self.keystore.clone(), + self.keystore.clone().map(KeystoreExt), ).execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( strategy.get_manager(), false, @@ -218,14 +223,13 @@ where fn contextual_call< 'a, - O: offchain::Externalities, IB: Fn() -> error::Result<()>, EM: Fn( Result, Self::Error>, 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, @@ -236,7 +240,7 @@ where initialize_block: InitializeBlock<'a, Block>, execution_manager: ExecutionManager, native_call: Option, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, recorder: &Option>>>, enable_keystore: bool, ) -> Result, error::Error> where ExecutionManager: Clone { @@ -250,7 +254,7 @@ where } let keystore = if enable_keystore { - self.keystore.clone() + self.keystore.clone().map(KeystoreExt) } else { None }; @@ -270,7 +274,7 @@ where recorder.clone() ); - state_machine::new( + StateMachine::new( &backend, self.backend.changes_trie_storage(), side_effects_handler, @@ -288,7 +292,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, @@ -317,7 +321,6 @@ where &mut overlay, &state, self.backend.changes_trie_storage(), - NeverOffchainExt::new(), None, ); let version = self.executor.runtime_version(&mut ext); @@ -326,14 +329,13 @@ where } fn call_at_state< - O: offchain::Externalities, S: state_machine::Backend, F: FnOnce( Result, Self::Error>, - Result, Self::Error> + 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, @@ -341,13 +343,13 @@ where call_data: &[u8], manager: ExecutionManager, native_call: Option, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, ) -> error::Result<( NativeOrEncoded, (S::Transaction, ::Out), - Option>, + Option>>, )> { - state_machine::new( + StateMachine::new( state, self.backend.changes_trie_storage(), side_effects_handler, @@ -355,7 +357,7 @@ where &self.executor, method, call_data, - self.keystore.clone(), + self.keystore.clone().map(KeystoreExt), ).execute_using_consensus_failure_handler( manager, true, @@ -382,7 +384,7 @@ where &self.executor, method, call_data, - self.keystore.clone(), + self.keystore.clone().map(KeystoreExt), ) .map_err(Into::into) } 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 c6234dc8d1cca2cedc12d730a54e07901412af17..d853d851c546cdfa0329967c49b4e37db7ce3640 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::{OffchainExt, 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. @@ -267,7 +248,7 @@ pub fn new_in_mem( Block, RA >> where - E: CodeExecutor + RuntimeInfo, + E: CodeExecutor + RuntimeInfo, S: BuildStorage, Block: BlockT, { @@ -283,13 +264,13 @@ pub fn new_with_backend( keystore: Option, ) -> error::Result, Block, RA>> where - E: CodeExecutor + RuntimeInfo, + E: CodeExecutor + RuntimeInfo, S: BuildStorage, Block: BlockT, 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 } @@ -924,19 +928,6 @@ impl Client where return Err(error::Error::NotInFinalizedChain); } - // find tree route from last finalized to given block. - let route_from_finalized = crate::blockchain::tree_route( - self.backend.blockchain(), - BlockId::Hash(info.finalized_hash), - BlockId::Hash(parent_hash), - )?; - - // the block being imported retracts the last finalized block, refusing to - // import. - if !route_from_finalized.retracted().is_empty() { - 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 // and get a new chain head. @@ -975,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( @@ -1002,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( @@ -1017,7 +1026,7 @@ impl Client where body: Option>, ) -> error::Result<( Option>, - Option>, + Option>>, Option<( Vec<(Vec, Option>)>, Vec<(Vec, Vec<(Vec, Option>)>)> @@ -1032,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(); @@ -1049,18 +1058,27 @@ impl Client where }), } }; - let (_, storage_update, changes_update) = self.executor.call_at_state::<_, _, _, NeverNativeValue, fn() -> _>( - transaction_state, - &mut overlay, - "Core_execute_block", - &::new(import_headers.pre().clone(), body.unwrap_or_default()).encode(), - match origin { - BlockOrigin::NetworkInitialSync => get_execution_manager(self.execution_strategies().syncing), - _ => get_execution_manager(self.execution_strategies().importing), - }, - None, - NeverOffchainExt::new(), - )?; + + let encoded_block = ::encode_from( + import_headers.pre(), + &body.unwrap_or_default() + ); + + let (_, storage_update, changes_update) = self.executor + .call_at_state::<_, _, NeverNativeValue, fn() -> _>( + transaction_state, + &mut overlay, + "Core_execute_block", + &encoded_block, + match origin { + BlockOrigin::NetworkInitialSync => get_execution_manager( + self.execution_strategies().syncing, + ), + _ => get_execution_manager(self.execution_strategies().importing), + }, + None, + None, + )?; overlay.commit_prospective(); @@ -1092,11 +1110,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 \ @@ -1105,17 +1119,13 @@ 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. if route_from_best.common_block().hash != block { // NOTE: we're setting the finalized block as best block, this might - // be slightly innacurate since we might have a "better" block + // be slightly inaccurate since we might have a "better" block // further along this chain, but since best chain selection logic is // pluggable we cannot make a better choice here. usages that need // an accurate "best" block need to go through `SelectChain` @@ -1172,35 +1182,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() @@ -1209,68 +1207,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> { @@ -1282,6 +1218,7 @@ impl Client where let info = self.backend.blockchain().info(); ClientInfo { chain: info, + used_state_cache_size: self.backend.used_state_cache_size(), } } @@ -1340,7 +1277,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))), } }; @@ -1386,6 +1323,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, @@ -1427,6 +1384,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, @@ -1457,7 +1441,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, @@ -1471,8 +1455,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(), @@ -1480,18 +1462,20 @@ 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 mut offchain_extensions = match context { - ExecutionContext::OffchainWorker(ext) => Some(ext), - _ => None, + let capabilities = context.capabilities(); + let offchain_extensions = if let ExecutionContext::OffchainCall(Some(ext)) = context { + Some(OffchainExt::new(offchain::LimitedExternalities::new(capabilities, ext.0))) + } else { + None }; - self.executor.contextual_call::<_, _, fn(_,_) -> _,_,_>( + self.executor.contextual_call::<_, fn(_,_) -> _,_,_>( || core_api.initialize_block(at, &self.prepare_environment_block(at)?), at, function, @@ -1500,9 +1484,9 @@ impl CallRuntimeAt for Client where initialize_block, manager, native_call, - offchain_extensions.as_mut(), + offchain_extensions, recorder, - enable_keystore, + capabilities.has(offchain::Capability::Keystore), ) } @@ -1511,6 +1495,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, @@ -1520,6 +1507,13 @@ impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client, @@ -1536,9 +1530,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()))? { @@ -1555,7 +1562,8 @@ impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client return Ok(ImportResult::KnownBad), } - Ok(ImportResult::imported()) + + Ok(ImportResult::imported(false)) } } @@ -1576,10 +1584,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) } } @@ -1643,129 +1694,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() } @@ -1794,7 +1730,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()) } } @@ -1829,7 +1766,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. @@ -1838,11 +1775,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 @@ -1850,16 +1831,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); } @@ -1872,18 +1854,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; @@ -1893,7 +1880,6 @@ 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}, }; @@ -2543,7 +2529,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 = {:?}", @@ -2554,8 +2545,6 @@ pub(crate) mod tests { #[test] fn import_with_justification() { - use test_client::blockchain::Backend; - let client = test_client::new(); // G -> A1 @@ -2571,33 +2560,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(); @@ -2621,12 +2606,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(), ); @@ -2635,19 +2617,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(); @@ -2674,29 +2655,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(), ); @@ -2715,7 +2693,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(), ); } @@ -2777,44 +2755,6 @@ pub(crate) mod tests { assert_eq!(980, current_balance()); } - #[test] - fn state_reverted_on_set_head() { - let _ = env_logger::try_init(); - let client = test_client::new(); - - let current_balance = || - client.runtime_api().balance_of( - &BlockId::number(client.info().chain.best_number), AccountKeyring::Alice.into() - ).unwrap(); - - // G -> A1 - // \ - // -> 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(); - client.import(BlockOrigin::Own, a1.clone()).unwrap(); - - let mut b1 = client.new_block_at(&BlockId::Number(0), Default::default()).unwrap(); - b1.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), - amount: 50, - 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()); - } - #[test] fn doesnt_import_blocks_that_revert_finality() { let _ = env_logger::try_init(); @@ -2867,7 +2807,7 @@ pub(crate) mod tests { // 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, false).unwrap(); + client.finalize_block(BlockId::Hash(a2.hash()), None).unwrap(); let b3 = client.new_block_at(&BlockId::Hash(b2.hash()), Default::default()) .unwrap().bake().unwrap(); 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..031b2dc0ad7df2a58b51e03798c73f07f8134f1e 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,25 +44,26 @@ 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}; + 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 { - executor::NativeExecutor::new(None) + executor::NativeExecutor::new(executor::WasmExecutionMethod::Interpreted, None) } fn construct_block( @@ -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(), + None, &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(), + None, &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(), + None, &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(), + None, &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(), + None, &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(), + None, &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..5a2cb746f38642c746ff6541dc58c4e916a3f2c2 100644 --- a/core/client/src/lib.rs +++ b/core/client/src/lib.rs @@ -49,7 +49,7 @@ //! use substrate_client::{Client, in_mem::Backend, LocalCallExecutor}; //! use primitives::Blake2Hasher; //! use sr_primitives::{StorageOverlay, ChildrenStorageOverlay}; -//! use executor::NativeExecutor; +//! use executor::{NativeExecutor, WasmExecutionMethod}; //! //! // In this example, we're using the `Block` and `RuntimeApi` types from the //! // `substrate-test-runtime-client` crate. These types are automatically generated when @@ -62,12 +62,13 @@ //! backend.clone(), //! LocalCallExecutor::new( //! backend.clone(), -//! NativeExecutor::::new(None), +//! NativeExecutor::::new(WasmExecutionMethod::Interpreted, None), //! None, //! ), //! // 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..65776bcfe08f35e139c8f60582730c77507d81ec 100644 --- a/core/client/src/light/call_executor.rs +++ b/core/client/src/light/call_executor.rs @@ -14,263 +14,90 @@ // 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 sr_primitives::generic::BlockId; -use sr_primitives::traits::{One, Block as BlockT, Header as HeaderT}; +use primitives::{ + offchain::OffchainExt, H256, Blake2Hasher, convert_hash, NativeOrEncoded, + traits::CodeExecutor, +}; +use sr_primitives::{ + generic::BlockId, 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 GenesisCallExecutor { + /// Create new genesis call executor. + pub fn new(backend: Arc, local: L) -> Self { + Self { backend, local } } } -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 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 - 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 +impl CallExecutor for + GenesisCallExecutor where Block: BlockT, B: RemoteBackend, - Remote: CallExecutor, Local: CallExecutor, { type Error = ClientError; - fn call< - O: offchain::Externalities, - >( + fn call( &self, id: &BlockId, method: &str, call_data: &[u8], strategy: ExecutionStrategy, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, ) -> 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), } } 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, + NC: FnOnce() -> result::Result + UnwindSafe, >( &self, initialize_block_fn: IB, @@ -281,7 +108,7 @@ impl CallExecutor for initialize_block: InitializeBlock<'a, Block>, _manager: ExecutionManager, native_call: Option, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, recorder: &Option>>>, enable_keystore: bool, ) -> ClientResult> where ExecutionManager: Clone { @@ -290,7 +117,6 @@ impl CallExecutor for match self.backend.is_local_state_available(at) { true => CallExecutor::contextual_call::< - _, _, fn( Result, Local::Error>, @@ -312,93 +138,49 @@ 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), } } 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 + 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, ) -> 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,13 +234,37 @@ 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, +{ + 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, - E: CodeExecutor, - H: Hasher, - H::Out: Ord + 'static, + E: CodeExecutor, + H: Hasher, { let local_state_root = request.header.state_root(); let root: H::Out = convert_hash(&local_state_root); @@ -466,51 +272,134 @@ 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 super::*; use consensus::BlockOrigin; - use test_client::{self, runtime::Header, ClientExt, TestClient}; - use executor::NativeExecutor; + use test_client::{self, runtime::{Header, Digest, Block}, ClientExt, TestClient}; + use executor::{NativeExecutor, WasmExecutionMethod}; + use primitives::Blake2Hasher; 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, + ) -> Result, ClientError> { + Ok(vec![42]) + } + + fn contextual_call< + 'a, + 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, + _proof_recorder: &Option>>>, + _enable_keystore: bool, + ) -> ClientResult> where ExecutionManager: Clone { + unreachable!() + } + + fn runtime_version(&self, _id: &BlockId) -> Result { + unreachable!() + } + + fn call_at_state< + 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, + ) -> 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!() + } + } + + fn local_executor() -> NativeExecutor { + NativeExecutor::new(WasmExecutionMethod::Interpreted, None) + } #[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( @@ -520,30 +409,65 @@ mod tests { ).unwrap(); // check remote execution proof locally - 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(), + let local_result = check_execution_proof::<_, _, Blake2Hasher>( + &local_executor(), + &RemoteCallRequest { + block: test_client::runtime::Hash::default(), + header: remote_header, + method: method.into(), + call_data: vec![], + retry_count: None, }, - method: method.into(), - call_data: vec![], - retry_count: None, - }, remote_execution_proof).unwrap(); + remote_execution_proof, + ).unwrap(); (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 execution_result = check_execution_proof_with_make_header::<_, _, Blake2Hasher, _>( + &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 +476,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 +507,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(), + None, ).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, + None, ); + + 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..dbf6d41c38f16d7553b58e5935337c44363d5a70 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, H256}; 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, + E: CodeExecutor, + H: Hasher, S: BlockchainStorage, - F: Send + Sync, { fn check_header_proof( &self, @@ -384,23 +394,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 +438,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 +462,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,11 +498,11 @@ 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; - use executor::{self, NativeExecutor}; + use executor::{NativeExecutor, WasmExecutionMethod}; use crate::error::Error as ClientError; use test_client::{ self, ClientExt, blockchain::HeaderBackend, AccountKeyring, @@ -511,12 +526,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 +549,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 { @@ -547,26 +562,33 @@ pub mod tests { } type TestChecker = LightDataChecker< - executor::NativeExecutor, + NativeExecutor, Blake2Hasher, Block, DummyStorage, - OkCallFetcher, >; + fn local_executor() -> NativeExecutor { + NativeExecutor::new(WasmExecutionMethod::Interpreted, None) + } + fn prepare_for_read_proof_check() -> (TestChecker, Header, Vec>, u32) { // prepare remote client let remote_client = test_client::new(); 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(); @@ -577,11 +599,55 @@ pub mod tests { 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); + let local_checker = LightDataChecker::new( + Arc::new(DummyBlockchain::new(DummyStorage::new())), + local_executor() + ); (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_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(); @@ -603,8 +669,10 @@ pub mod tests { if insert_cht { local_storage.insert_cht_root(1, local_cht_root); } - let local_executor = NativeExecutor::::new(None); - let local_checker = LightDataChecker::new(Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor); + let local_checker = LightDataChecker::new( + Arc::new(DummyBlockchain::new(DummyStorage::new())), + local_executor(), + ); (local_checker, local_cht_root, remote_block_header, remote_header_proof) } @@ -623,9 +691,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] @@ -665,7 +753,7 @@ pub mod tests { let (remote_client, local_roots, test_cases) = prepare_client_with_key_changes(); let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), - NativeExecutor::::new(None) + local_executor(), ); let local_checker = &local_checker as &dyn FetchChecker; let max = remote_client.info().chain.best_number; @@ -678,7 +766,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 +778,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 +813,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 @@ -733,7 +822,7 @@ pub mod tests { local_storage.changes_tries_cht_roots.insert(0, local_cht_root); let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(local_storage)), - NativeExecutor::::new(None) + local_executor(), ); // check proof on local client @@ -743,6 +832,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, }; @@ -761,7 +851,7 @@ pub mod tests { let (remote_client, local_roots, test_cases) = prepare_client_with_key_changes(); let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), - NativeExecutor::::new(None) + local_executor(), ); let local_checker = &local_checker as &dyn FetchChecker; let max = remote_client.info().chain.best_number; @@ -774,7 +864,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 +873,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,13 +927,13 @@ 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 let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), - NativeExecutor::::new(None) + local_executor(), ); assert!(local_checker.check_changes_tries_proof(4, &remote_proof.roots, remote_proof.roots_proof.clone()).is_err()); @@ -852,7 +943,7 @@ pub mod tests { local_storage.changes_tries_cht_roots.insert(0, local_cht_root); let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(local_storage)), - NativeExecutor::::new(None) + local_executor(), ); assert!(local_checker.check_changes_tries_proof(4, &remote_proof.roots, vec![]).is_err()); } @@ -866,7 +957,7 @@ pub mod tests { let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), - NativeExecutor::::new(None) + local_executor(), ); let body_request = RemoteBodyRequest { @@ -889,7 +980,7 @@ pub mod tests { let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), - NativeExecutor::::new(None) + local_executor(), ); let body_request = RemoteBodyRequest { diff --git a/core/client/src/light/mod.rs b/core/client/src/light/mod.rs index 89d3c60ddc3727f7fb67ef8b1c332b92ed12d4b3..d06a9ae9dd93c09b4bb7e7322ea6d478ff916f53 100644 --- a/core/client/src/light/mod.rs +++ b/core/client/src/light/mod.rs @@ -24,67 +24,59 @@ 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, + 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, + E: CodeExecutor, { LightDataChecker::new(blockchain, executor) } 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..a09d51095018e57b5700c94a83baad1f6b5592ce 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.7.0" +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 84671e5ae6864072b41555bc1ca1005318aaa74e..e4620fcdbfdd44e6c3873db6eb80e318075fa051 100644 --- a/core/consensus/aura/primitives/src/lib.rs +++ b/core/consensus/aura/primitives/src/lib.rs @@ -23,38 +23,38 @@ 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. diff --git a/core/consensus/aura/src/lib.rs b/core/consensus/aura/src/lib.rs index 406874eafbcc415168e78c74029639fb23ad5e9b..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,13 +41,14 @@ 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::{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::*; use parking_lot::Mutex; @@ -217,8 +218,8 @@ impl slots::SimpleSlotWorker for AuraWorker Result { - authorities(self.client.as_ref(), &BlockId::Hash(*block)) + fn epoch_data(&self, header: &B::Header, _slot_number: u64) -> Result { + authorities(self.client.as_ref(), &BlockId::Hash(header.hash())) } fn authorities_len(&self, epoch_data: &Self::EpochData) -> usize { @@ -245,7 +246,7 @@ impl slots::SimpleSlotWorker for AuraWorker Box Box, @@ -307,16 +308,33 @@ impl SlotWorker for AuraWorker { - { - debug!(target: "aura", $( $i ),+); - format!($( $i ),+) - } - }; +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, @@ -325,12 +343,12 @@ 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. @@ -347,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, @@ -356,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)?; @@ -372,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, }; @@ -385,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, @@ -396,7 +414,7 @@ fn check_header( Ok(CheckedHeader::Checked(header, (slot_num, seal))) } else { - Err(format!("Bad signature on {:?}", hash)) + Err(Error::BadSignature(hash)) } } } @@ -418,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; @@ -427,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 @@ -437,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); @@ -452,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(()) @@ -496,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 @@ -517,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(); @@ -541,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], @@ -552,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); @@ -680,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; @@ -740,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(); @@ -761,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"), } } @@ -796,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."); @@ -803,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() diff --git a/core/consensus/babe/Cargo.toml b/core/consensus/babe/Cargo.toml index 9490887ba34bced36527613052f78164da18c1bb..30b7c1f8d6b1cec1d34a17cd48fb1550e52de676 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,22 @@ 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" +derive_more = "0.15.0" [dev-dependencies] keyring = { package = "substrate-keyring", path = "../../keyring" } @@ -41,9 +44,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.7.0" +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 427c4fec57e7df3ee1d435703e340e9bd2c3e315..95dd247810782396499596ffaa3a1d4d74c2ce65 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::{AuthorityIndex, BabeBlockWeight, SlotNumber}; +use super::{AuthorityId, AuthorityIndex, SlotNumber, BabeAuthorityWeight}; #[cfg(feature = "std")] use sr_primitives::{DigestItem, generic::OpaqueDigestItemId}; #[cfg(feature = "std")] @@ -35,6 +33,8 @@ use schnorrkel::{ SignatureError, errors::MultiSignatureStage, vrf::{VRFProof, VRFOutput, VRF_OUTPUT_LENGTH, VRF_PROOF_LENGTH} }; +use rstd::vec::Vec; + /// 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 @@ -52,8 +52,6 @@ pub enum BabePreDigest { authority_index: super::AuthorityIndex, /// Slot number slot_number: SlotNumber, - /// Chain weight (measured in number of Primary blocks) - weight: BabeBlockWeight, }, /// A secondary deterministic slot assignment. Secondary { @@ -61,8 +59,6 @@ pub enum BabePreDigest { authority_index: super::AuthorityIndex, /// Slot number slot_number: SlotNumber, - /// Chain weight (measured in number of Primary blocks) - weight: BabeBlockWeight, }, } @@ -84,42 +80,46 @@ impl BabePreDigest { } } - /// Returns the weight of the pre digest. - pub fn weight(&self) -> BabeBlockWeight { + /// 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 { weight, .. } => *weight, - BabePreDigest::Secondary { weight, .. } => *weight, + BabePreDigest::Primary { .. } => 1, + BabePreDigest::Secondary { .. } => 0, } } } /// The prefix used by BABE for its VRF keys. -pub const BABE_VRF_PREFIX: &'static [u8] = b"substrate-babe-vrf"; +pub const BABE_VRF_PREFIX: &[u8] = b"substrate-babe-vrf"; /// A raw version of `BabePreDigest`, usable on `no_std`. #[derive(Copy, Clone, Encode, Decode)] pub enum RawBabePreDigest { /// A primary VRF-based slot assignment. + #[codec(index = "1")] Primary { /// Authority index authority_index: AuthorityIndex, /// Slot number slot_number: SlotNumber, - /// Chain weight (measured in number of Primary blocks) - weight: BabeBlockWeight, /// 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, - /// Chain weight (measured in number of Primary blocks) - weight: BabeBlockWeight, }, } @@ -142,25 +142,21 @@ impl Encode for BabePreDigest { vrf_proof, authority_index, slot_number, - weight, } => { RawBabePreDigest::Primary { vrf_output: *vrf_output.as_bytes(), vrf_proof: vrf_proof.to_bytes(), authority_index: *authority_index, slot_number: *slot_number, - weight: *weight, } }, BabePreDigest::Secondary { authority_index, slot_number, - weight, } => { RawBabePreDigest::Secondary { authority_index: *authority_index, slot_number: *slot_number, - weight: *weight, } }, }; @@ -176,7 +172,7 @@ impl codec::EncodeLike for BabePreDigest {} impl Decode for BabePreDigest { fn decode(i: &mut R) -> Result { let pre_digest = match Decode::decode(i)? { - RawBabePreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number, weight } => { + 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; @@ -186,11 +182,10 @@ impl Decode for BabePreDigest { vrf_output: VRFOutput::from_bytes(&vrf_output).map_err(convert_error)?, authority_index, slot_number, - weight, } }, - RawBabePreDigest::Secondary { authority_index, slot_number, weight } => { - BabePreDigest::Secondary { authority_index, slot_number, weight } + RawBabePreDigest::Secondary { authority_index, slot_number } => { + BabePreDigest::Secondary { authority_index, slot_number } }, }; @@ -198,6 +193,17 @@ impl Decode for BabePreDigest { } } +/// Information about the next epoch. This is broadcast in the first block +/// of the epoch. +#[derive(Decode, Encode, Default, PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] +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 { @@ -214,7 +220,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")] @@ -237,8 +243,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 09ac2f20123ac5b9ba407ae57a451291992b0864..c464e797d8d5868439504e725aac90b379433e69 100644 --- a/core/consensus/babe/primitives/src/lib.rs +++ b/core/consensus/babe/primitives/src/lib.rs @@ -23,12 +23,12 @@ mod digest; use codec::{Encode, Decode}; use rstd::vec::Vec; -use sr_primitives::ConsensusEngineId; +use sr_primitives::{ConsensusEngineId, RuntimeDebug}; 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; @@ -74,39 +79,54 @@ pub type BabeAuthorityWeight = u64; pub type BabeBlockWeight = u32; /// BABE epoch information -#[derive(Decode, Encode, Default, PartialEq, Eq, Clone)] -#[cfg_attr(any(feature = "std", test), derive(Debug))] +#[derive(Decode, Encode, Default, PartialEq, Eq, Clone, RuntimeDebug)] 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, BabeAuthorityWeight)>, /// Randomness for this epoch pub randomness: [u8; VRF_OUTPUT_LENGTH], - /// Whether secondary slot assignments should be used during the epoch. - pub secondary_slots: bool, +} + +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, RuntimeDebug)] pub struct BabeConfiguration { /// The slot duration in milliseconds for BABE. Currently, only /// the value provided by this type at genesis will be used. @@ -114,35 +134,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! { @@ -152,9 +172,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..6290d5cf316434bede137c5badfb0d9822ea1e0b 100644 --- a/core/consensus/babe/src/aux_schema.rs +++ b/core/consensus/babe/src/aux_schema.rs @@ -22,18 +22,23 @@ 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, T: Decode, { let corrupt = |e: codec::Error| { - ClientError::Backend(format!("BABE DB is corrupted. Decode error: {}", e.what())).into() + ClientError::Backend(format!("BABE DB is corrupted. Decode error: {}", e.what())) }; match backend.get_aux(key)? { None => Ok(None), @@ -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 6d049dd6be16a3755f58e8d78e832f94afc8abbf..287b26a300f43382e720f89cf77a0be70cbde63a 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -56,7 +56,8 @@ //! 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, pin::Pin, time::{Instant, Duration}}; @@ -65,74 +66,146 @@ 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::{BlockId, OpaqueDigestItemId}, Justification}; +use sr_primitives::{generic::{BlockId, OpaqueDigestItemId}, Justification, RuntimeString}; use sr_primitives::traits::{ - Block as BlockT, Header, DigestItemFor, NumberFor, ProvideRuntimeApi, + Block as BlockT, Header, DigestItemFor, ProvideRuntimeApi, Zero, }; use keystore::KeyStorePtr; -use codec::{Decode, Encode}; -use parking_lot::{Mutex, MutexGuard}; -use primitives::{blake2_256, Blake2Hasher, H256, Pair, Public, U256}; -use merlin::Transcript; +use parking_lot::Mutex; +use primitives::{Blake2Hasher, H256, Pair}; use inherents::{InherentDataProviders, InherentData}; use substrate_telemetry::{ telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG, }; -use schnorrkel::{ - keys::Keypair, - vrf::{ - VRFProof, VRFInOut, VRFOutput, - }, -}; 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::*; -use futures01::Stream as _; -use log::{error, warn, debug, info, trace}; - +use log::{warn, debug, info, trace}; use slots::{SlotWorker, SlotData, SlotInfo, SlotCompatible}; +use epoch_changes::descendent_query; +use header_metadata::HeaderMetadata; +use schnorrkel::SignatureError; 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}; + + +#[derive(derive_more::Display, Debug)] +enum Error { + #[display(fmt = "Multiple BABE pre-runtime digests, rejecting!")] + MultiplePreRuntimeDigests, + #[display(fmt = "No BABE pre-runtime digest found")] + NoPreRuntimeDigest, + #[display(fmt = "Multiple BABE epoch change digests, rejecting!")] + MultipleEpochChangeDigests, + #[display(fmt = "Could not extract timestamp and slot: {:?}", _0)] + Extraction(consensus_common::Error), + #[display(fmt = "Could not fetch epoch at {:?}", _0)] + FetchEpoch(B::Hash), + #[display(fmt = "Header {:?} rejected: too far in the future", _0)] + TooFarInFuture(B::Hash), + #[display(fmt = "Parent ({}) of {} unavailable. Cannot import", _0, _1)] + ParentUnavailable(B::Hash, B::Hash), + #[display(fmt = "Slot number must increase: parent slot: {}, this slot: {}", _0, _1)] + SlotNumberMustIncrease(u64, u64), + #[display(fmt = "Header {:?} has a bad seal", _0)] + HeaderBadSeal(B::Hash), + #[display(fmt = "Header {:?} is unsealed", _0)] + HeaderUnsealed(B::Hash), + #[display(fmt = "Slot author not found")] + SlotAuthorNotFound, + #[display(fmt = "Secondary slot assignments are disabled for the current epoch.")] + SecondarySlotAssignmentsDisabled, + #[display(fmt = "Bad signature on {:?}", _0)] + BadSignature(B::Hash), + #[display(fmt = "Invalid author: Expected secondary author: {:?}, got: {:?}.", _0, _1)] + InvalidAuthor(AuthorityId, AuthorityId), + #[display(fmt = "No secondary author expected.")] + NoSecondaryAuthorExpected, + #[display(fmt = "VRF verification of block by author {:?} failed: threshold {} exceeded", _0, _1)] + VRFVerificationOfBlockFailed(AuthorityId, u128), + #[display(fmt = "VRF verification failed: {:?}", _0)] + VRFVerificationFailed(SignatureError), + #[display(fmt = "Could not fetch parent header: {:?}", _0)] + FetchParentHeader(client::error::Error), + #[display(fmt = "Expected epoch change to happen at {:?}, s{}", _0, _1)] + ExpectedEpochChange(B::Hash, u64), + #[display(fmt = "Could not look up epoch: {:?}", _0)] + CouldNotLookUpEpoch(Box>), + #[display(fmt = "Block {} is not valid under any epoch.", _0)] + BlockNotValid(B::Hash), + #[display(fmt = "Unexpected epoch change")] + UnexpectedEpochChange, + #[display(fmt = "Parent block of {} has no associated weight", _0)] + ParentBlockNoAssociatedWeight(B::Hash), + #[display(fmt = "Checking inherents failed: {}", _0)] + CheckInherents(String), + Client(client::error::Error), + Runtime(RuntimeString), + ForkTree(Box>), +} + +impl std::convert::From> for String { + fn from(error: Error) -> String { + error.to_string() + } +} + +fn babe_err(error: Error) -> Error { + debug!(target: "babe", "{}", error); + error +} + +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"); @@ -141,37 +214,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, @@ -181,12 +246,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, @@ -197,80 +264,86 @@ 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, - 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 slots::SimpleSlotWorker 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, - H: Header, I: BlockImport + Send + Sync + 'static, SO: SyncOracle + Send + Clone, Error: std::error::Error + Send + From<::consensus_common::Error> + From + 'static, @@ -289,8 +362,16 @@ impl slots::SimpleSlotWorker for BabeWorker Result { - epoch_from_runtime(self.client.as_ref(), &BlockId::Hash(*block)) + 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) } @@ -300,22 +381,23 @@ impl slots::SimpleSlotWorker for BabeWorker Option { - let parent_weight = { - let pre_digest = find_pre_digest::(&header).ok()?; - pre_digest.weight() - }; - - claim_slot( + debug!(target: "babe", "Attempting to claim slot {}", slot_number); + let s = authorship::claim_slot( slot_number, - parent_weight, epoch_data, - self.c, + &*self.config, &self.keystore, - ) + ); + + if let Some(_) = s { + debug!(target: "babe", "Claimed slot {}", slot_number); + } + + s } fn pre_digest_data(&self, _slot_number: u64, claim: &Self::Claim) -> Vec> { @@ -324,7 +406,7 @@ impl slots::SimpleSlotWorker for BabeWorker Box Box, @@ -336,9 +418,6 @@ impl slots::SimpleSlotWorker for BabeWorker as CompatibleDigestItem>::babe_seal(signature); - // When we building our own blocks we always author on top of the - // current best according to `SelectChain`, therefore our own block - // proposal should always become the new best. BlockImportParams { origin: BlockOrigin::Own, header, @@ -346,8 +425,11 @@ impl slots::SimpleSlotWorker for BabeWorker slots::SimpleSlotWorker for BabeWorker Result { self.env.init(block).map_err(|e| { - consensus_common::Error::ClientImport(format!("{:?}", e)).into() + consensus_common::Error::ClientImport(format!("{:?}", e)) }) } } -impl SlotWorker for BabeWorker where - B: BlockT, - C: ProvideRuntimeApi + ProvideCache + Send + Sync, +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, - H: Header, I: BlockImport + Send + Sync + 'static, SO: SyncOracle + Send + Sync + Clone, Error: std::error::Error + Send + From<::consensus_common::Error> + From + 'static, @@ -386,18 +467,9 @@ impl SlotWorker for BabeWorker where } } -macro_rules! babe_err { - ($($i: expr),+) => { - { debug!(target: "babe", $($i),+) - ; format!($($i),+) - } - }; -} - /// 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: &B::Header) -> 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 @@ -405,7 +477,6 @@ fn find_pre_digest(header: &B::Header) -> Result(header: &B::Header) -> Result Err(babe_err!("Multiple BABE pre-runtime digests, rejecting!"))?, + (Some(_), true) => return Err(babe_err(Error::MultiplePreRuntimeDigests)), (None, _) => trace!(target: "babe", "Ignoring digest not meant for us"), (s, false) => pre_digest = s, } } - pre_digest.ok_or_else(|| babe_err!("No BABE pre-runtime digest found")) + pre_digest.ok_or_else(|| babe_err(Error::NoPreRuntimeDigest)) } /// Extract the BABE epoch change digest from the given header, if it exists. -fn find_next_epoch_digest(header: &B::Header) -> Result, String> +fn find_next_epoch_digest(header: &B::Header) + -> Result, Error> where DigestItemFor: CompatibleDigestItem, { let mut epoch_digest: Option<_> = None; @@ -430,7 +502,7 @@ fn find_next_epoch_digest(header: &B::Header) -> Result trace!(target: "babe", "Checking log {:?}, looking for epoch change digest.", log); let log = log.try_to::(OpaqueDigestItemId::Consensus(&BABE_ENGINE_ID)); match (log, epoch_digest.is_some()) { - (Some(ConsensusLog::NextEpochData(_)), true) => Err(babe_err!("Multiple BABE epoch change digests, rejecting!"))?, + (Some(ConsensusLog::NextEpochData(_)), true) => return Err(babe_err(Error::MultipleEpochChangeDigests)), (Some(ConsensusLog::NextEpochData(epoch)), false) => epoch_digest = Some(epoch), _ => trace!(target: "babe", "Ignoring digest not meant for us"), } @@ -439,252 +511,61 @@ 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`. -/// -/// The given header can either be from a primary or secondary slot assignment, -/// with each having different validation logic. -// FIXME #1018 needs misbehavior types. The `transaction_pool` parameter will be -// used to submit such misbehavior reports. -fn check_header( - mut header: B::Header, - parent_header: B::Header, - slot_now: u64, - authorities: &[(AuthorityId, BabeAuthorityWeight)], - client: &C, - randomness: [u8; 32], - epoch_index: u64, - secondary_slots: bool, - 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", 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(); - - let pre_digest = find_pre_digest::(&header)?; - - if pre_digest.slot_number() > slot_now { - header.digest_mut().push(seal); - return Ok(CheckedHeader::Deferred(header, pre_digest.slot_number())); - } - - if pre_digest.authority_index() > authorities.len() as u32 { - return Err(babe_err!("Slot author not found")); - } - - let parent_weight = { - let parent_pre_digest = find_pre_digest::(&parent_header)?; - parent_pre_digest.weight() - }; - - match &pre_digest { - BabePreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number, weight } => { - debug!(target: "babe", "Verifying Primary block"); - - let digest = (vrf_output, vrf_proof, *authority_index, *slot_number, *weight); - - check_primary_header::( - pre_hash, - digest, - sig, - parent_weight, - authorities, - randomness, - epoch_index, - c, - )?; - }, - BabePreDigest::Secondary { authority_index, slot_number, weight } if secondary_slots => { - debug!(target: "babe", "Verifying Secondary block"); - - let digest = (*authority_index, *slot_number, *weight); - - check_secondary_header::( - pre_hash, - digest, - sig, - parent_weight, - &authorities, - randomness, - )?; - }, - _ => { - return Err(babe_err!("Secondary slot assignments are disabled for the current epoch.")); - } - } - - let author = &authorities[pre_digest.authority_index() as usize].0; - - // 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( - client, - slot_now, - pre_digest.slot_number(), - &header, - author, - ).map_err(|e| e.to_string())? { - info!( - "Slot author {:?} is equivocating at slot {} with headers {:?} and {:?}", - author, - pre_digest.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))) -} - -/// 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, BabeBlockWeight), - signature: AuthoritySignature, - parent_weight: BabeBlockWeight, - authorities: &[(AuthorityId, BabeAuthorityWeight)], - randomness: [u8; 32], - epoch_index: u64, - c: (u64, u64), -) -> Result<(), String> - where DigestItemFor: CompatibleDigestItem, -{ - let (vrf_output, vrf_proof, authority_index, slot_number, weight) = pre_digest; - if weight != parent_weight + 1 { - return Err("Invalid weight: should increase with Primary block.".into()); - } - - let author = &authorities[authority_index as usize].0; - - if AuthorityPair::verify(&signature, pre_hash, &author) { - let (inout, _) = { - 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_primary_threshold(c, 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, BabeBlockWeight), - signature: AuthoritySignature, - parent_weight: BabeBlockWeight, - authorities: &[(AuthorityId, BabeAuthorityWeight)], - randomness: [u8; 32], -) -> Result<(), String> { - let (authority_index, slot_number, weight) = pre_digest; - - if weight != parent_weight { - return Err("Invalid weight: Should stay the same with secondary block.".into()); - } - - // check the signature is valid under the expected authority and - // chain state. - let expected_author = secondary_slot_author( - slot_number, - authorities, - randomness, - ).ok_or_else(|| "No secondary author expected.".to_string())?; - let author = &authorities[authority_index as usize].0; +#[derive(Default, Clone)] +struct TimeSource(Arc, Vec<(Instant, u64)>)>>); - 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)) +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 { +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 { +impl BabeVerifier { fn check_inherents( &self, block: Block, block_id: BlockId, inherent_data: InherentData, - ) -> Result<(), String> + ) -> Result<(), Error> where PRA: ProvideRuntimeApi, PRA::Api: BlockBuilderApi { let inherent_res = self.api.runtime_api().check_inherents( &block_id, block, inherent_data, - ).map_err(|e| format!("{:?}", e))?; + ).map_err(Error::Client)?; if !inherent_res.ok() { inherent_res .into_errors() .try_for_each(|(i, e)| { - Err(self.inherent_data_providers.error_to_string(&i, &e)) + Err(Error::CheckInherents(self.inherent_data_providers.error_to_string(&i, &e))) }) } else { Ok(()) @@ -704,7 +585,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))) }) @@ -717,8 +598,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) @@ -735,14 +616,13 @@ fn median_algorithm( } } -impl Verifier for BabeVerifier where +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, - T: Send + Sync + 'static, { fn verify( &mut self, @@ -764,71 +644,68 @@ impl Verifier for BabeVerifier::Runtime)?; let (_, slot_now, _) = self.time_source.extract_timestamp_and_slot(&inherent_data) - .map_err(|e| format!("Could not extract timestamp and slot: {:?}", e))?; + .map_err(Error::::Extraction)?; let hash = header.hash(); let parent_hash = *header.parent_hash(); - let epoch = epoch(self.api.as_ref(), &BlockId::Hash(parent_hash)) - .map_err(|e| format!("Could not fetch epoch at {:?}: {:?}", parent_hash, e))?; - let (epoch, maybe_next_epoch) = epoch.deconstruct(); - let Epoch { authorities, randomness, epoch_index, secondary_slots, .. } = epoch; - - let parent_header = self.client.header(&BlockId::Hash(parent_hash)) - .map_err(|e| format!("Could not fetch parent header {:?}: {:?}", parent_hash, e))? - .ok_or_else(|| format!("Parent header {:?} not found.", parent_hash))?; + let parent_header_metadata = self.client.header_metadata(parent_hash) + .map_err(Error::::FetchParentHeader)?; + + 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| Error::::ForkTree(Box::new(e)))? + .ok_or_else(|| Error::::FetchEpoch(parent_hash))? + }; - // We add one to allow for some small drift. + // 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 mut checked_header = check_header::( - header.clone(), - parent_header.clone(), - slot_now + 1, - &authorities, - &self.api, - randomness, - epoch_index, - secondary_slots, - self.config.c(), - self.transaction_pool.as_ref().map(|x| &**x), - ); - - // if we have failed to check header using (presumably) current epoch AND we're probably in the next epoch - // => check using next epoch - // (this is only possible on the light client at epoch#0) - if epoch_index == 0 && checked_header.is_err() { - if let Some(Epoch { authorities, randomness, epoch_index, .. }) = maybe_next_epoch { - let checked_header_next = check_header::( - header, - parent_header, - slot_now + 1, - &authorities, - &self.api, - randomness, - epoch_index, - secondary_slots, - self.config.c(), - self.transaction_pool.as_ref().map(|x| &**x), - ); - - match checked_header_next { - Ok(checked_header_next) => checked_header = Ok(checked_header_next), - Err(_) => (), - } - } - } + 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, + }; - let checked_header = checked_header?; - match checked_header { - CheckedHeader::Checked(pre_header, (pre_digest, seal)) => { - let babe_pre_digest = pre_digest.as_babe_pre_digest() + 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. @@ -852,129 +729,33 @@ impl Verifier for BabeVerifier ?pre_header); - // The fork choice rule is that we pick the heaviest chain (i.e. - // more primary blocks), if there's a tie we go with the longest - // chain. - let new_best = { - let (last_best, last_best_number) = { - #[allow(deprecated)] - let info = self.client.backend().blockchain().info(); - (info.best_hash, info.best_number) - }; - - let best_header = self.client.header(&BlockId::Hash(last_best)) - .map_err(|_| "Failed fetching best header")? - .expect("parent_header must be imported; qed"); - - let best_weight = find_pre_digest::(&best_header) - .map(|babe_pre_digest| babe_pre_digest.weight())?; - - let new_weight = babe_pre_digest.weight(); - - if new_weight > best_weight { - true - } else if new_weight == best_weight { - *pre_header.number() > last_best_number - } else { - false - } - }; - - 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(), - fork_choice: ForkChoiceStrategy::Custom(new_best), + // 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); telemetry!(CONSENSUS_DEBUG; "babe.header_too_far_in_future"; "hash" => ?hash, "a" => ?a, "b" => ?b ); - Err(format!("Header {:?} rejected: too far in the future", hash)) + Err(Error::::TooFarInFuture(hash).into()) } } } } -/// Regular BABE epoch or spanned genesis epoch. -#[derive(Debug, Decode, Encode)] -enum MaybeSpanEpoch { - /// Genesis entry. Has the data for epoch#0 and epoch#1. - Genesis(Epoch, Epoch), - /// Regular entry. Has the data for the epoch after next (i.e. current epoch + 2). - Regular(Epoch), -} - -impl MaybeSpanEpoch { - pub fn deconstruct(self) -> (Epoch, Option) { - match self { - MaybeSpanEpoch::Genesis(epoch0, epoch1) => (epoch0, Some(epoch1)), - MaybeSpanEpoch::Regular(epoch) => (epoch, None), - } - } - - #[cfg(test)] - pub fn into_regular(self) -> Option { - match self { - MaybeSpanEpoch::Regular(epoch) => Some(epoch), - _ => None, - } - } -} - -/// 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, -{ - epoch_from_cache(client, at) - .or_else(|| epoch_from_runtime(client, at).map(MaybeSpanEpoch::Regular)) - .ok_or(consensus_common::Error::InvalidAuthoritiesSet) -} - -/// Extract current epoch data from cache. -fn epoch_from_cache(client: &C, at: &BlockId) -> Option where - B: BlockT, - C: ProvideCache, -{ - // the epoch that is BABE-valid at the block is not the epoch that is cache-valid at the block - // we need to go back for maximum two steps - client.cache() - .and_then(|cache| cache - .get_at(&well_known_cache_keys::EPOCH, at) - .and_then(|(_, _, v)| Decode::decode(&mut &v[..]).ok())) -} - -/// Extract current epoch from runtime. -fn epoch_from_runtime(client: &C, at: &BlockId) -> Option where - B: BlockT, - C: ProvideRuntimeApi, - C::Api: BabeApi, -{ - 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 - } -} - /// The BABE import queue type. pub type BabeImportQueue = BasicQueue; @@ -994,269 +775,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 -} - -/// Returns true if the given VRF output is lower than the given threshold, -/// false otherwise. -fn check_primary_threshold(inout: &VRFInOut, threshold: u128) -> bool { - u128::from_le_bytes(inout.make_bytes::<[u8; 16]>(BABE_VRF_PREFIX)) < threshold -} - -/// Calculates the primary selection threshold for a given authority, taking -/// into account `c` (`1 - c` represents the probability of a slot being empty). -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()) -} - -/// 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. -fn claim_slot( - slot_number: SlotNumber, - parent_weight: BabeBlockWeight, - epoch: &Epoch, - c: (u64, u64), - keystore: &KeyStorePtr, -) -> Option<(BabePreDigest, AuthorityPair)> { - claim_primary_slot(slot_number, parent_weight, epoch, c, keystore) - .or_else(|| { - if epoch.secondary_slots { - claim_secondary_slot( - slot_number, - parent_weight, - &epoch.authorities, - keystore, - epoch.randomness, - ) - } else { - None - } - }) -} - -/// 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, - parent_weight: BabeBlockWeight, - 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 = 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_primary_threshold(c, authorities, authority_index); - - let pre_digest = get_keypair(&pair) - .vrf_sign_after_check(transcript, |inout| 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, - weight: parent_weight + 1, - } - }); - - // early exit on first successful claim - if let Some(pre_digest) = pre_digest { - return Some((pre_digest, pair)); - } - } - - None -} - -/// 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. -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) -} - -/// 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, - parent_weight: BabeBlockWeight, - authorities: &[(AuthorityId, BabeAuthorityWeight)], - keystore: &KeyStorePtr, - randomness: [u8; 32], -) -> Option<(BabePreDigest, AuthorityPair)> { - if authorities.is_empty() { - return None; - } - - let expected_author = 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, - weight: parent_weight, - }; - - return Some((pre_digest, pair)); - } - } - - None -} - -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 epoch0 = epoch_from_runtime(client, &genesis_id).ok_or(consensus_common::Error::InvalidAuthoritiesSet)?; - let mut epoch1 = epoch0.clone(); - epoch1.epoch_index = 1; - - let genesis_epoch = MaybeSpanEpoch::Genesis(epoch0, epoch1); - 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 @@ -1270,6 +788,7 @@ pub struct BabeBlockImport { client: Arc>, api: Arc, epoch_changes: SharedEpochChanges, + config: Config, } impl Clone for BabeBlockImport { @@ -1279,6 +798,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, } } } @@ -1314,77 +836,99 @@ 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()), + Err(e) => return Err(ConsensusError::ClientImport(e.to_string())), } - 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"); - pre_digest.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 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 parent_header = self.client.header(&BlockId::Hash(parent_hash)) + .map_err(|e| ConsensusError::ChainLookup(e.to_string()))? + .ok_or_else(|| ConsensusError::ChainLookup(babe_err( + Error::::ParentUnavailable(parent_hash, hash) + ).into()))?; + + 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"); + + // make sure that slot number is strictly increasing + if slot_number <= parent_slot { + return Err( + ConsensusError::ClientImport(babe_err( + Error::::SlotNumberMustIncrease(parent_slot, slot_number) + ).into()) + ); + } - // 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_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(Error::::ParentBlockNoAssociatedWeight(hash)).into() + ))? + }; + + 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(Error::::CouldNotLookUpEpoch(Box::new(e))).into() + ))? + .ok_or_else(|| ConsensusError::ClientImport( + babe_err(Error::::BlockNotValid(hash)).into() + ))?; + + 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())))?; + .map_err(|e| 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(Error::::ExpectedEpochChange(hash, slot_number)).into(), ) ); }, (false, true) => { - if !check_roots()? { - return Err(ConsensusError::ClientImport("Unexpected epoch change".into())); - } + return Err(ConsensusError::ClientImport(Error::::UnexpectedEpochChange.into())); }, } @@ -1392,37 +936,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() { + debug!(target: "babe", "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, @@ -1432,6 +985,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 @@ -1447,89 +1035,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 { client: client.clone(), - api: api.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. @@ -1543,26 +1171,25 @@ pub mod test_helpers { slot_number: u64, parent: &B::Header, client: &C, - c: (u64, u64), keystore: &KeyStorePtr, + link: &BabeLink, ) -> Option where - B: BlockT, - C: ProvideRuntimeApi + ProvideCache, + B: BlockT, + C: ProvideRuntimeApi + ProvideCache + HeaderBackend + HeaderMetadata, C::Api: BabeApi, { - let epoch = match epoch(client, &BlockId::Hash(parent.hash())).unwrap() { - MaybeSpanEpoch::Regular(epoch) => epoch, - _ => unreachable!("it is always Regular epoch on full nodes"), - }; - - let weight = find_pre_digest::(parent).ok() - .map(|d| d.weight())?; + 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, - weight, - &epoch, - c, + epoch.as_ref(), + &link.config, keystore, ).map(|(digest, _)| digest) } diff --git a/core/consensus/babe/src/tests.rs b/core/consensus/babe/src/tests.rs index 8635473a593f9c3e5d4fc89ca0bef5d980665a06..2e236f190b66a11d4d4961c5f149b9b65edfc581 100644 --- a/core/consensus/babe/src/tests.rs +++ b/core/consensus/babe/src/tests.rs @@ -20,20 +20,24 @@ // https://github.com/paritytech/substrate/issues/2532 #![allow(deprecated)] use super::*; +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 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}; +use std::{time::Duration, cell::RefCell}; type Item = DigestItem; @@ -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,21 +155,41 @@ 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; @@ -94,7 +202,6 @@ pub struct TestVerifier { TestBlock, test_client::runtime::RuntimeApi, PeersFullClient, - (), >, mutator: Mutator, } @@ -110,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 { @@ -129,31 +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 client = client.as_full().expect("only full clients are used in test"); trace!(target: "babe", "Creating a verifier"); - 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"); - 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 { client: client.clone(), api: client, - inherent_data_providers, - config, - time_source: Default::default(), - transaction_pool : Default::default(), + 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()), } } @@ -188,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 = &[ @@ -202,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")); } @@ -250,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] @@ -325,28 +488,34 @@ fn can_author_block() { .expect("Generates authority pair"); let mut i = 0; - let mut epoch = Epoch { + let epoch = Epoch { start_slot: 0, authorities: vec![(pair.public(), 1)], randomness: [0; 32], epoch_index: 1, duration: 100, - secondary_slots: true, }; - let parent_weight = 0; + 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, parent_weight, &epoch, (3, 10), &keystore) { + 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. - epoch.secondary_slots = false; + config.secondary_slots = false; loop { - match claim_slot(i, parent_weight, &epoch, (3, 10), &keystore) { + match claim_slot(i, &epoch, &config, &keystore) { None => i += 1, Some(s) => { debug!(target: "babe", "Authored block {:?}", s.0); @@ -356,15 +525,254 @@ fn can_author_block() { } } +// Propose and import a new BABE block on top of the given parent. +fn propose_and_import_block( + parent: &TestHeader, + slot_number: Option, + proposer_factory: &mut DummyFactory, + block_import: &mut BoxBlockImport, +) -> H256 { + let mut proposer = proposer_factory.init(parent).unwrap(); + + let slot_number = slot_number.unwrap_or_else(|| { + let parent_pre_digest = find_pre_digest::(parent).unwrap(); + parent_pre_digest.slot_number() + 1 + }); + + let pre_digest = sr_primitives::generic::Digest { + logs: vec![ + Item::babe_pre_digest( + BabePreDigest::Secondary { + authority_index: 0, + slot_number, + }, + ), + ], + }; + + 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 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 +} + #[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().into_regular().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 proposer_factory = DummyFactory { + client: client.clone(), + config: data.link.config.clone(), + epoch_changes: data.link.epoch_changes.clone(), + mutator: Arc::new(|_, _| ()), + }; + + let mut block_import = data.block_import.lock().take().expect("import set up during init"); + + let genesis_header = client.header(&BlockId::Number(0)).unwrap().unwrap(); + + let block_hash = propose_and_import_block( + &genesis_header, + Some(999), + &mut proposer_factory, + &mut block_import, + ); + + let genesis_epoch = data.link.config.genesis_epoch(999); + + let epoch_changes = data.link.epoch_changes.lock(); + let epoch_for_second_block = epoch_changes.epoch_for_child_of( + descendent_query(&*client), + &block_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(); + + let mut proposer_factory = DummyFactory { + client: client.clone(), + config: data.link.config.clone(), + epoch_changes: data.link.epoch_changes.clone(), + mutator: Arc::new(|_, _| ()), + }; + + // This is just boilerplate code for proposing and importing n valid BABE + // blocks that are 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_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, + None, + &mut proposer_factory, + &mut block_import, + ); + 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)), + ); +} + +#[test] +#[should_panic] +fn verify_slots_are_strictly_increasing() { + 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 mut proposer_factory = 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(); + + // we should have no issue importing this block + let b1 = propose_and_import_block( + &genesis_header, + Some(999), + &mut proposer_factory, + &mut block_import, + ); + + let b1 = client.header(&BlockId::Hash(b1)).unwrap().unwrap(); + + // we should fail to import this block since the slot number didn't increase. + // we will panic due to the `PanickingBlockImport` defined above. + propose_and_import_block( + &b1, + Some(999), + &mut proposer_factory, + &mut block_import, + ); } diff --git a/core/consensus/babe/src/verification.rs b/core/consensus/babe/src/verification.rs new file mode 100644 index 0000000000000000000000000000000000000000..36e34dfb9578b8ace59b25ee0eff192b284a4a1e --- /dev/null +++ b/core/consensus/babe/src/verification.rs @@ -0,0 +1,217 @@ +// 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, babe_err, BlockT, Error}; +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, +} + +/// 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>, Error> 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(Error::HeaderUnsealed(header.hash()))), + }; + + let sig = seal.as_babe_seal().ok_or_else(|| { + babe_err(Error::HeaderBadSeal(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(Error::SlotAuthorNotFound)), + }; + + 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(Error::SecondarySlotAssignmentsDisabled)); + } + } + + 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<(), Error> { + 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(Error::VRFVerificationFailed(s)) + })? + }; + + let threshold = calculate_primary_threshold( + c, + &epoch.authorities, + authority_index as usize, + ); + + if !check_primary_threshold(&inout, threshold) { + return Err(babe_err(Error::VRFVerificationOfBlockFailed(author.clone(), threshold))); + } + + Ok(()) + } else { + Err(babe_err(Error::BadSignature(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<(), Error> { + 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(|| Error::NoSecondaryAuthorExpected)?; + + let author = &epoch.authorities[authority_index as usize].0; + + if expected_author != author { + return Err(Error::InvalidAuthor(expected_author.clone(), author.clone())); + } + + if AuthorityPair::verify(&signature, pre_hash.as_ref(), author) { + Ok(()) + } else { + Err(Error::BadSignature(pre_hash)) + } +} diff --git a/core/consensus/common/Cargo.toml b/core/consensus/common/Cargo.toml index 32930d5d7b90e385adcc13199642ca6e1ea9f060..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" +derive_more = "0.15.0" libp2p = { version = "0.12.0", default-features = false } -log = "0.4" +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/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/common/src/select_chain.rs b/core/consensus/common/src/select_chain.rs index cae28656a13b90cc50319d3f4fb6449ebdf59de3..e696db6b877b47d1290637a00e76f7dc6cbf9ee5 100644 --- a/core/consensus/common/src/select_chain.rs +++ b/core/consensus/common/src/select_chain.rs @@ -42,8 +42,9 @@ pub trait SelectChain: Sync + Send + Clone { /// best chain to author new blocks upon and probably finalize. fn best_chain(&self) -> Result<::Header, Error>; - /// Get the best ancestor of `target_hash` that we should attempt - /// to finalize next. + /// Get the best descendent of `target_hash` that we should attempt to + /// finalize next, if any. It is valid to return the given `target_hash` + /// itself if no better descendent exists. fn finality_target( &self, target_hash: ::Hash, diff --git a/core/consensus/pow/Cargo.toml b/core/consensus/pow/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..86efcbb95da2bcdd7e89a42ee17ffa0d174f8ef7 --- /dev/null +++ b/core/consensus/pow/Cargo.toml @@ -0,0 +1,19 @@ +[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"] } +derive_more = "0.15.0" 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..040eb01d9c5f01188ed80a2fd4ec386d1802ff3b --- /dev/null +++ b/core/consensus/pow/src/lib.rs @@ -0,0 +1,539 @@ +// 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, RuntimeString}; +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, Error as ConsensusError +}; +use consensus_common::import_queue::{BoxBlockImport, BasicQueue, Verifier}; +use codec::{Encode, Decode}; +use log::*; + +#[derive(derive_more::Display, Debug)] +pub enum Error { + #[display(fmt = "Header uses the wrong engine {:?}", _0)] + WrongEngine([u8; 4]), + #[display(fmt = "Header {:?} is unsealed", _0)] + HeaderUnsealed(B::Hash), + #[display(fmt = "PoW validation error: invalid seal")] + InvalidSeal, + #[display(fmt = "Rejecting block too far in future")] + TooFarInFuture, + #[display(fmt = "Fetching best header failed using select chain: {:?}", _0)] + BestHeaderSelectChain(ConsensusError), + #[display(fmt = "Fetching best header failed: {:?}", _0)] + BestHeader(client::error::Error), + #[display(fmt = "Best header does not exist")] + NoBestHeader, + #[display(fmt = "Block proposing error: {:?}", _0)] + BlockProposingError(String), + #[display(fmt = "Fetch best hash failed via select chain: {:?}", _0)] + BestHashSelectChain(ConsensusError), + #[display(fmt = "Error with block built on {:?}: {:?}", _0, _1)] + BlockBuiltError(B::Hash, ConsensusError), + #[display(fmt = "Creating inherents failed: {}", _0)] + CreateInherents(RuntimeString), + #[display(fmt = "Checking inherents failed: {}", _0)] + CheckInherents(String), + Client(client::error::Error), + Codec(codec::Error), + Environment(String), + Runtime(RuntimeString) +} + +impl std::convert::From> for String { + fn from(error: Error) -> String { + error.to_string() + } +} + +/// 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(Error::Client)? { + Some(bytes) => Self::decode(&mut &bytes[..]) + .map_err(Error::Codec), + 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, Error>; +} + +/// 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), Error> 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(Error::WrongEngine(id)) + } + }, + _ => return Err(Error::HeaderUnsealed(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(Error::InvalidSeal); + } + + Ok((header, difficulty, seal)) + } + + fn check_inherents( + &self, + block: B, + block_id: BlockId, + inherent_data: InherentData, + timestamp_now: u64, + ) -> Result<(), Error> 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(Error::Client)?; + + 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(Error::TooFarInFuture); + } + + Ok(()) + }, + Some(TIError::Other(e)) => Err(Error::Runtime(e)), + None => Err(Error::CheckInherents( + 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::<_, B>(self.client.as_ref(), &best_hash)?; + let mut aux = PowAux::read::<_, B>(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<(), Error> 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(Error::BestHeaderSelectChain)?; + let hash = header.hash(); + (hash, header) + }, + None => { + let hash = client.info().best_hash; + let header = client.header(BlockId::Hash(hash)) + .map_err(Error::BestHeader)? + .ok_or(Error::NoBestHeader)?; + (hash, header) + }, + }; + let mut aux = PowAux::read(client, &best_hash)?; + let mut proposer = env.init(&best_header) + .map_err(|e| Error::Environment(format!("{:?}", e)))?; + + let inherent_data = inherent_data_providers + .create_inherent_data().map_err(Error::CreateInherents)?; + 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| Error::BlockProposingError(format!("{:?}", 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(Error::BestHashSelectChain)? + .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| Error::BlockBuiltError(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 4203da9d7d7f38f3d51c1791ee031293b2f7077c..4074242502b7192e26c13372eb77411d0bd32ff0 100644 --- a/core/consensus/slots/Cargo.toml +++ b/core/consensus/slots/Cargo.toml @@ -4,6 +4,7 @@ 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" } @@ -13,10 +14,10 @@ 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/slots/build.rs b/core/consensus/slots/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..36730271c715eaa1daf6e957e4b1e01443a2bc7a --- /dev/null +++ b/core/consensus/slots/build.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. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use std::env; + +fn main() { + if let Ok(profile) = env::var("PROFILE") { + println!("cargo:rustc-cfg=build_type=\"{}\"", profile); + } +} diff --git a/core/consensus/slots/src/aux_schema.rs b/core/consensus/slots/src/aux_schema.rs index 1d54cb5c2ee6cf05e52edb70c6f6fea5621bb180..186288c17443227ec7b1661f758e73565a119a3b 100644 --- a/core/consensus/slots/src/aux_schema.rs +++ b/core/consensus/slots/src/aux_schema.rs @@ -38,7 +38,7 @@ fn load_decode(backend: &C, key: &[u8]) -> ClientResult> None => Ok(None), Some(t) => T::decode(&mut &t[..]) .map_err( - |e| ClientError::Backend(format!("Slots DB is corrupted. Decode error: {}", e.what())).into(), + |e| ClientError::Backend(format!("Slots DB is corrupted. Decode error: {}", e.what())), ) .map(Some) } diff --git a/core/consensus/slots/src/lib.rs b/core/consensus/slots/src/lib.rs index 2513071a9fe40afb929093429c8cd3ff008ea5f1..e33d00d25531f7c9d30e9b9ef59e6f37f8a8c906 100644 --- a/core/consensus/slots/src/lib.rs +++ b/core/consensus/slots/src/lib.rs @@ -52,7 +52,7 @@ 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 at +/// 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 { @@ -77,8 +77,9 @@ pub trait SimpleSlotWorker { /// A handle to a `BlockImport`. fn block_import(&self) -> Arc>; - /// Returns the epoch data necessary for authoring. - fn epoch_data(&self, block: &B::Hash) -> Result; + /// 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; @@ -95,7 +96,7 @@ pub trait SimpleSlotWorker { fn pre_digest_data(&self, slot_number: u64, claim: &Self::Claim) -> Vec>; /// Returns a function which produces a `BlockImportParams`. - fn import_block(&self) -> Box Box, @@ -120,7 +121,7 @@ pub trait SimpleSlotWorker { let (timestamp, slot_number, slot_duration) = (slot_info.timestamp, slot_info.number, slot_info.duration); - let epoch_data = match self.epoch_data(&chain_head.hash()) { + 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); @@ -188,9 +189,9 @@ pub trait SimpleSlotWorker { logs, }, remaining_duration, - ).map_err(|e| consensus_common::Error::ClientImport(format!("{:?}", e)).into()), + ).map_err(|e| consensus_common::Error::ClientImport(format!("{:?}", e))), Delay::new(remaining_duration) - .map_err(|err| consensus_common::Error::FaultyTimer(err).into()) + .map_err(consensus_common::Error::FaultyTimer) ).map(|v| match v { futures::future::Either::Left((b, _)) => b.map(|b| (b, claim)), futures::future::Either::Right((Ok(_), _)) => @@ -198,7 +199,7 @@ pub trait SimpleSlotWorker { futures::future::Either::Right((Err(err), _)) => Err(err), }); - let import_block = self.import_block(); + let block_import_params_maker = self.block_import_params(); let block_import = self.block_import(); let logging_target = self.logging_target(); @@ -208,6 +209,9 @@ pub trait SimpleSlotWorker { 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, ); @@ -216,11 +220,11 @@ pub trait SimpleSlotWorker { } let (header, body) = block.deconstruct(); - let header_num = header.number().clone(); + let header_num = *header.number(); let header_hash = header.hash(); - let parent_hash = header.parent_hash().clone(); + let parent_hash = *header.parent_hash(); - let import_block = import_block( + let block_import_params = block_import_params_maker( header, &header_hash, body, @@ -229,17 +233,17 @@ pub trait SimpleSlotWorker { info!("Pre-sealed block for proposal at {}. Hash now {:?}, previously {:?}.", header_num, - import_block.post_header().hash(), + block_import_params.post_header().hash(), header_hash, ); telemetry!(CONSENSUS_INFO; "slots.pre_sealed_block"; "header_num" => ?header_num, - "hash_now" => ?import_block.post_header().hash(), + "hash_now" => ?block_import_params.post_header().hash(), "hash_previously" => ?header_hash, ); - if let Err(err) = block_import.lock().import_block(import_block, Default::default()) { + 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, @@ -356,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); @@ -394,11 +399,10 @@ 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") + "slot duration kept in invalid format".to_string() }) - .into() }), None => { use sr_primitives::traits::Zero; 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..cf3ea4ff7a6e706c9e94868205316ff59a12fbfe 100644 --- a/core/executor/Cargo.toml +++ b/core/executor/Cargo.toml @@ -5,31 +5,32 @@ 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" } +externalities = { package = "substrate-externalities", path = "../externalities" } 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..72041218bf9f2ac9959e85d0e63d34ff8e94788f 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" } +wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.4", 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..68e5205f0c7a867bda0b7bad5efd2252a9fd33f9 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.8", }, // 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..61eca8dd4e23ffa37a1081b9aad9c14f5388b151 100644 --- a/core/executor/runtime-test/src/lib.rs +++ b/core/executor/runtime-test/src/lib.rs @@ -5,47 +5,23 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -use rstd::{vec::Vec, slice, vec}; +#[cfg(not(feature = "std"))] +use rstd::{vec::Vec, vec}; +#[cfg(not(feature = "std"))] 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, }; +#[cfg(not(feature = "std"))] +use sr_primitives::{print, traits::{BlakeTwo256, Hash}}; +#[cfg(not(feature = "std"))] use primitives::{ed25519, sr25519}; -macro_rules! impl_stubs { - ( $( $new_name:ident => $invoke:expr, )* ) => { - $( - impl_stubs!(@METHOD $new_name => $invoke); - )* - }; - ( @METHOD $new_name:ident => $invoke:expr ) => { - #[no_mangle] - pub fn $new_name(input_data: *mut u8, input_len: usize) -> u64 { - let input: &[u8] = if input_len == 0 { - &[0u8; 0] - } else { - unsafe { - slice::from_raw_parts(input_data, input_len) - } - }; - - let output: Vec = $invoke(input); - let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); - - // Leak the output vector to avoid it being freed. - // This is fine in a WASM context since the heap - // will be discarded after the call. - rstd::mem::forget(output); - res - } - }; -} - -impl_stubs!( - test_data_in => |input| { +primitives::wasm_export_functions! { + fn test_data_in(input: Vec) -> Vec { print("set_storage"); - set_storage(b"input", input); + set_storage(b"input", &input); print("storage"); let foo = storage(b"foo").unwrap(); @@ -55,25 +31,44 @@ impl_stubs!( print("finished!"); b"all ok!".to_vec() - }, - test_clear_prefix => |input| { - clear_prefix(input); + } + + fn test_clear_prefix(input: Vec) -> Vec { + clear_prefix(&input); b"all ok!".to_vec() - }, - test_empty_return => |_| Vec::new(), - test_exhaust_heap => |_| Vec::with_capacity(16777216), - test_panic => |_| panic!("test panic"), - test_conditional_panic => |input: &[u8]| { + } + + fn test_empty_return() {} + + fn test_exhaust_heap() -> Vec { Vec::with_capacity(16777216) } + + fn test_panic() { panic!("test panic") } + + fn test_conditional_panic(input: Vec) -> Vec { if input.len() > 0 { panic!("test panic") } - input.to_vec() - }, - test_blake2_256 => |input| blake2_256(input).to_vec(), - test_blake2_128 => |input| blake2_128(input).to_vec(), - test_twox_256 => |input| twox_256(input).to_vec(), - test_twox_128 => |input| twox_128(input).to_vec(), - test_ed25519_verify => |input: &[u8]| { + + input + } + + fn test_blake2_256(input: Vec) -> Vec { + blake2_256(&input).to_vec() + } + + fn test_blake2_128(input: Vec) -> Vec { + blake2_128(&input).to_vec() + } + + fn test_twox_256(input: Vec) -> Vec { + twox_256(&input).to_vec() + } + + fn test_twox_128(input: Vec) -> Vec { + twox_128(&input).to_vec() + } + + fn test_ed25519_verify(input: Vec) -> bool { let mut pubkey = [0; 32]; let mut sig = [0; 64]; @@ -81,9 +76,10 @@ impl_stubs!( sig.copy_from_slice(&input[32..96]); let msg = b"all ok!"; - [ed25519_verify(&ed25519::Signature(sig), &msg[..], &ed25519::Public(pubkey)) as u8].to_vec() - }, - test_sr25519_verify => |input: &[u8]| { + ed25519_verify(&ed25519::Signature(sig), &msg[..], &ed25519::Public(pubkey)) + } + + fn test_sr25519_verify(input: Vec) -> bool { let mut pubkey = [0; 32]; let mut sig = [0; 64]; @@ -91,34 +87,36 @@ impl_stubs!( sig.copy_from_slice(&input[32..96]); let msg = b"all ok!"; - [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"[..], - ] + sr25519_verify(&sr25519::Signature(sig), &msg[..], &sr25519::Public(pubkey)) + } + + fn test_ordered_trie_root() -> Vec { + BlakeTwo256::ordered_trie_root( + vec![ + b"zero"[..].into(), + b"one"[..].into(), + b"two"[..].into(), + ], ).as_ref().to_vec() - }, - test_sandbox => |code: &[u8]| { - let ok = execute_sandboxed(code, &[]).is_ok(); - [ok as u8].to_vec() - }, - test_sandbox_args => |code: &[u8]| { - let ok = execute_sandboxed( - code, + } + + fn test_sandbox(code: Vec) -> bool { + execute_sandboxed(&code, &[]).is_ok() + } + + fn test_sandbox_args(code: Vec) -> bool { + execute_sandboxed( + &code, &[ sandbox::TypedValue::I32(0x12345678), sandbox::TypedValue::I64(0x1234567887654321), - ] - ).is_ok(); - [ok as u8].to_vec() - }, - test_sandbox_return_val => |code: &[u8]| { + ], + ).is_ok() + } + + fn test_sandbox_return_val(code: Vec) -> bool { let ok = match execute_sandboxed( - code, + &code, &[ sandbox::TypedValue::I32(0x1336), ] @@ -126,41 +124,43 @@ impl_stubs!( Ok(sandbox::ReturnValue::Value(sandbox::TypedValue::I32(0x1337))) => true, _ => false, }; - [ok as u8].to_vec() - }, - test_sandbox_instantiate => |code: &[u8]| { + + ok + } + + fn test_sandbox_instantiate(code: Vec) -> u8 { let env_builder = sandbox::EnvironmentDefinitionBuilder::new(); - let code = match sandbox::Instance::new(code, &env_builder, &mut ()) { + let code = match sandbox::Instance::new(&code, &env_builder, &mut ()) { Ok(_) => 0, Err(sandbox::Error::Module) => 1, Err(sandbox::Error::Execution) => 2, Err(sandbox::Error::OutOfBounds) => 3, }; - [code].to_vec() - }, - test_offchain_local_storage => |_| { + + code + } + + fn test_offchain_local_storage() -> bool { let kind = primitives::offchain::StorageKind::PERSISTENT; assert_eq!(runtime_io::local_storage_get(kind, b"test"), None); runtime_io::local_storage_set(kind, b"test", b"asd"); assert_eq!(runtime_io::local_storage_get(kind, b"test"), Some(b"asd".to_vec())); let res = runtime_io::local_storage_compare_and_set(kind, b"test", Some(b"asd"), b""); - assert_eq!(res, true); assert_eq!(runtime_io::local_storage_get(kind, b"test"), Some(b"".to_vec())); + res + } - [0].to_vec() - }, - test_offchain_local_storage_with_none => |_| { + fn test_offchain_local_storage_with_none() { let kind = primitives::offchain::StorageKind::PERSISTENT; assert_eq!(runtime_io::local_storage_get(kind, b"test"), None); let res = runtime_io::local_storage_compare_and_set(kind, b"test", None, b"value"); assert_eq!(res, true); assert_eq!(runtime_io::local_storage_get(kind, b"test"), Some(b"value".to_vec())); + } - [0].to_vec() - }, - test_offchain_http => |_| { + fn test_offchain_http() -> bool { use primitives::offchain::HttpRequestStatus; let run = || -> Option<()> { let id = runtime_io::http_request_start("POST", "http://localhost:12345", &[]).ok()?; @@ -181,16 +181,23 @@ impl_stubs!( Some(()) }; - [if run().is_some() { 0 } else { 1 }].to_vec() - }, -); + run().is_some() + } + } -fn execute_sandboxed(code: &[u8], args: &[sandbox::TypedValue]) -> Result { +#[cfg(not(feature = "std"))] +fn execute_sandboxed( + code: &[u8], + args: &[sandbox::TypedValue], +) -> Result { struct State { counter: u32, } - fn env_assert(_e: &mut State, args: &[sandbox::TypedValue]) -> Result { + fn env_assert( + _e: &mut State, + args: &[sandbox::TypedValue], + ) -> Result { if args.len() != 1 { return Err(sandbox::HostError); } @@ -201,7 +208,10 @@ fn execute_sandboxed(code: &[u8], args: &[sandbox::TypedValue]) -> Result Result { + fn env_inc_counter( + e: &mut State, + args: &[sandbox::TypedValue], + ) -> Result { if args.len() != 1 { return Err(sandbox::HostError); } 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..e1221bea54aefd7b1bc4a896f082bd170b2fdc44 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,31 @@ 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) } } + +impl From for Error { + fn from(err: WasmError) -> Error { + Error::Other(err.to_string()) + } +} + +/// Type for errors occurring during Wasm runtime construction. +#[derive(Debug, derive_more::Display)] +pub enum WasmError { + /// Code could not be read from the state. + CodeNotFound, + /// Failure to reinitialize runtime instance from snapshot. + ApplySnapshotFailed, + /// Wasm code failed validation. + InvalidModule, + /// Wasm code could not be deserialized. + CantDeserializeWasm, + /// Instantiation error. + Instantiation(Error), +} diff --git a/core/executor/src/host_interface.rs b/core/executor/src/host_interface.rs new file mode 100644 index 0000000000000000000000000000000000000000..7d87d93333fd25c734ec0861112670c10dd27ebe --- /dev/null +++ b/core/executor/src/host_interface.rs @@ -0,0 +1,1175 @@ +// 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 . + +//! Definition and implementation of the Substrate Wasm host interface. +//! +//! These are the host functions callable from within the Substrate runtime. + +use crate::error::{Error, Result}; + +use codec::Encode; +use std::{convert::TryFrom, str, panic}; +use primitives::{ + blake2_128, blake2_256, twox_64, twox_128, twox_256, ed25519, sr25519, Blake2Hasher, Pair, + crypto::KeyTypeId, offchain, +}; +use trie::{TrieConfiguration, trie_types::Layout}; +use wasm_interface::{FunctionContext, Pointer, PointerType, Result as WResult, WordSize}; + +#[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 )* ) => () +} + +pub struct SubstrateExternals; + +enum RecoverResult { + Invalid(u32), + Valid(secp256k1::PublicKey), +} + +fn secp256k1_recover( + context: &mut dyn FunctionContext, + msg_data: Pointer, + sig_data: Pointer, +) -> WResult { + 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(RecoverResult::Invalid(1)), + }; + + 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(RecoverResult::Invalid(2)), + }; + + 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")?; + + Ok(match secp256k1::recover(&secp256k1::Message::parse(&msg), &rs, &v) { + Ok(pubkey) => RecoverResult::Valid(pubkey), + Err(_) => RecoverResult::Invalid(3), + }) +} + +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) + } + + 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_log( + level: u32, + target_data: Pointer, + target_len: WordSize, + message_data: Pointer, + message_len: WordSize, + ) { + let target = context.read_memory(target_data, target_len) + .map_err(|_| "Invalid attempt to determine target in ext_log")?; + let message = context.read_memory(message_data, message_len) + .map_err(|_| "Invalid attempt to determine message in ext_log")?; + + runtime_io::log(level.into(), &target, &message); + 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(()) + } + + 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 { + 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 { + 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 { + 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 { + 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)) + )?; + + 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) + } + + 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 { + 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 { + 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 + }; + + context.write_memory(out, &result) + .map_err(|_| "Invalid attempt to set result in ext_twox_64")?; + Ok(()) + } + + ext_twox_128(data: Pointer, len: WordSize, out: Pointer) { + let result: [u8; 16] = if len == 0 { + let hashed = twox_128(&[0u8; 0]); + hashed + } else { + 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 { + 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(()) + } + + ext_blake2_128(data: Pointer, len: WordSize, out: Pointer) { + let result: [u8; 16] = if len == 0 { + let hashed = blake2_128(&[0u8; 0]); + hashed + } else { + 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 { + 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(()) + } + + 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_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) + }, + None => Ok(1), + } + } + + 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); + + 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) + }, + None => Ok(1), + } + } + + ext_secp256k1_ecdsa_recover( + msg_data: Pointer, + sig_data: Pointer, + pubkey_data: Pointer, + ) -> u32 { + match secp256k1_recover(context, msg_data, sig_data)? { + RecoverResult::Invalid(c) => Ok(c), + RecoverResult::Valid(pubkey) => { + context.write_memory(pubkey_data, &pubkey.serialize()[1..65]) + .map_err(|_| "Invalid attempt to set pubkey in ext_secp256k1_ecdsa_recover")?; + Ok(0) + } + } + } + + ext_secp256k1_ecdsa_recover_compressed( + msg_data: Pointer, + sig_data: Pointer, + pubkey_data: Pointer, + ) -> u32 { + match secp256k1_recover(context, msg_data, sig_data)? { + RecoverResult::Invalid(c) => Ok(c), + RecoverResult::Valid(pubkey) => { + context.write_memory(pubkey_data, &pubkey.serialize_compressed()[..]) + .map_err(|_| "Invalid attempt to set pubkey in ext_secp256k1_ecdsa_recover")?; + Ok(0) + } + } + } + + ext_is_validator() -> u32 { + if runtime_io::is_validator() { Ok(1) } else { Ok(0) } + } + + 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")?; + + 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(()) + } + + 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 { + 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()) + } + } + + 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), + name_str, + value_str, + ); + + Ok(if res.is_ok() { 0 } else { 1 }) + } + + 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), + &chunk, + deadline_to_timestamp(deadline), + ); + + Ok(match res { + Ok(()) => 0, + Err(e) => e.into(), + }) + } + + 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")?; + } + + Ok(()) + } + + ext_http_response_headers( + request_id: u32, + written_out: Pointer, + ) -> Pointer { + use codec::Encode; + + let headers = runtime_io::http_response_headers(offchain::HttpRequestId(request_id as u16)); + + let encoded = headers.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_http_response_headers")?; + context.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: 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); + + 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 + } + }) + } + } +} + +trait WritePrimitive { + fn write_primitive(&mut self, ptr: Pointer, t: T) -> WResult<()>; +} + +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)) + } +} + +/// 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)) +} + +fn deadline_to_timestamp(deadline: u64) -> Option { + if deadline == 0 { + None + } else { + Some(offchain::Timestamp::from_unix_millis(deadline)) + } +} + diff --git a/core/executor/src/lib.rs b/core/executor/src/lib.rs index 065de451c19dc65c241ee6cd90bd1b45af38886f..ac98388cd7bbebf79fbfe78d2da7c0584ec53836 100644 --- a/core/executor/src/lib.rs +++ b/core/executor/src/lib.rs @@ -14,39 +14,68 @@ // 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"] #[macro_use] mod wasm_utils; -mod wasm_executor; +mod wasmi_execution; #[macro_use] mod native_executor; mod sandbox; mod allocator; -mod wasm_runtimes_cache; +mod host_interface; +mod wasm_runtime; pub mod error; 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::traits::Externalities; +#[doc(hidden)] +pub use wasm_interface; +pub use wasm_runtime::WasmExecutionMethod; + +/// Call the given `function` in the given wasm `code`. +/// +/// The signature of `function` needs to follow the default Substrate function signature. +/// +/// - `call_data`: Will be given as input parameters to `function` +/// - `execution_method`: The execution method to use. +/// - `ext`: The externalities that should be set while executing the wasm function. +/// - `heap_pages`: The number of heap pages to allocate. +/// +/// Returns the `Vec` that contains the return value of the function. +pub fn call_in_wasm( + function: &str, + call_data: &[u8], + execution_method: WasmExecutionMethod, + ext: &mut E, + code: &[u8], + heap_pages: u64, +) -> error::Result> { + let mut instance = wasm_runtime::create_wasm_runtime_with_code( + ext, + execution_method, + heap_pages, + code, + )?; + instance.call(ext, function, call_data) +} /// Provides runtime information. pub trait RuntimeInfo { @@ -54,8 +83,30 @@ pub trait RuntimeInfo { fn native_version(&self) -> &NativeVersion; /// Extract RuntimeVersion of given :code block - fn runtime_version> ( + fn runtime_version ( &self, ext: &mut E, ) -> Option; } + +#[cfg(test)] +mod tests { + use super::*; + use runtime_test::WASM_BINARY; + use runtime_io::TestExternalities; + + #[test] + fn call_in_interpreted_wasm_works() { + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + let res = call_in_wasm( + "test_empty_return", + &[], + WasmExecutionMethod::Interpreted, + &mut ext, + &WASM_BINARY, + 8, + ).unwrap(); + assert_eq!(res, vec![0u8; 0]); + } +} diff --git a/core/executor/src/native_executor.rs b/core/executor/src/native_executor.rs index 937e0033539f0ea3dbd8abf0638be2f507cf443e..7323703ed96568af9a8e79f8aadd55a9338b794a 100644 --- a/core/executor/src/native_executor.rs +++ b/core/executor/src/native_executor.rs @@ -16,44 +16,45 @@ use std::{result, cell::RefCell, panic::UnwindSafe}; use crate::error::{Error, Result}; -use state_machine::{CodeExecutor, Externalities}; -use crate::wasm_executor::WasmExecutor; +use crate::wasm_runtime::{RuntimesCache, WasmExecutionMethod, WasmRuntime}; +use crate::RuntimeInfo; use runtime_version::{NativeVersion, RuntimeVersion}; use codec::{Decode, Encode}; -use crate::RuntimeInfo; -use primitives::{Blake2Hasher, NativeOrEncoded}; +use primitives::{NativeOrEncoded, traits::{CodeExecutor, Externalities}}; use log::{trace, warn}; -use crate::RuntimesCache; - thread_local! { static RUNTIMES_CACHE: RefCell = RefCell::new(RuntimesCache::new()); } +/// Default num of pages for the heap +const DEFAULT_HEAP_PAGES: u64 = 1024; + fn safe_call(f: F) -> Result where F: UnwindSafe + FnOnce() -> U { // 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. /// /// If the inner closure panics, it will be caught and return an error. -pub fn with_native_environment(ext: &mut dyn Externalities, 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)) + externalities::set_and_run_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. - fn dispatch(ext: &mut dyn Externalities, method: &str, data: &[u8]) -> Result>; + /// 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. fn native_version() -> NativeVersion; @@ -65,31 +66,50 @@ pub trait NativeExecutionDispatch: Send + Sync { pub struct NativeExecutor { /// Dummy field to avoid the compiler complaining about us not using `D`. _dummy: ::std::marker::PhantomData, - /// The fallback executor in case native isn't available. - fallback: WasmExecutor, + /// Method used to execute fallback Wasm code. + fallback_method: WasmExecutionMethod, /// Native runtime version info. native_version: NativeVersion, /// The number of 64KB pages to allocate for Wasm execution. - default_heap_pages: Option, + default_heap_pages: u64, } impl NativeExecutor { /// Create new instance. - pub fn new(default_heap_pages: Option) -> Self { + /// + /// # Parameters + /// + /// `fallback_method` - Method used to execute fallback Wasm code. + /// + /// `default_heap_pages` - Number of 64KB pages to allocate for Wasm execution. + /// Defaults to `DEFAULT_HEAP_PAGES` if `None` is provided. + pub fn new(fallback_method: WasmExecutionMethod, default_heap_pages: Option) -> Self { NativeExecutor { _dummy: Default::default(), - fallback: WasmExecutor::new(), + fallback_method, native_version: D::native_version(), - default_heap_pages: default_heap_pages, + default_heap_pages: default_heap_pages.unwrap_or(DEFAULT_HEAP_PAGES), } } + + fn with_runtime( + &self, + ext: &mut E, + f: impl for <'a> FnOnce(&'a mut dyn WasmRuntime, &'a mut E) -> Result, + ) -> Result where E: Externalities { + RUNTIMES_CACHE.with(|cache| { + let mut cache = cache.borrow_mut(); + let runtime = cache.fetch_runtime(ext, self.fallback_method, self.default_heap_pages)?; + f(runtime, ext) + }) + } } impl Clone for NativeExecutor { fn clone(&self) -> Self { NativeExecutor { _dummy: Default::default(), - fallback: self.fallback.clone(), + fallback_method: self.fallback_method, native_version: D::native_version(), default_heap_pages: self.default_heap_pages, } @@ -101,32 +121,28 @@ impl RuntimeInfo for NativeExecutor { &self.native_version } - fn runtime_version>( + fn runtime_version( &self, ext: &mut E, ) -> Option { - RUNTIMES_CACHE.with(|cache| { - let cache = &mut cache.borrow_mut(); - - match cache.fetch_runtime(&self.fallback, ext, self.default_heap_pages) { - Ok(runtime) => runtime.version(), - Err(e) => { - warn!(target: "executor", "Failed to fetch runtime: {:?}", e); - None - } + match self.with_runtime(ext, |runtime, _ext| Ok(runtime.version())) { + Ok(version) => version, + Err(e) => { + warn!(target: "executor", "Failed to fetch runtime: {:?}", e); + None } - }) + } } } -impl CodeExecutor for NativeExecutor { +impl CodeExecutor for NativeExecutor { type Error = Error; fn call < - E: Externalities, + E: Externalities, R:Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe + NC: FnOnce() -> result::Result + UnwindSafe >( &self, ext: &mut E, @@ -135,15 +151,9 @@ impl CodeExecutor for NativeExecutor, ) -> (Result>, bool){ - RUNTIMES_CACHE.with(|cache| { - let cache = &mut cache.borrow_mut(); - let cached_runtime = match cache.fetch_runtime( - &self.fallback, ext, self.default_heap_pages, - ) { - Ok(cached_runtime) => cached_runtime, - Err(e) => return (Err(e), false), - }; - let onchain_version = cached_runtime.version(); + let mut used_native = false; + let result = self.with_runtime(ext, |runtime, ext| { + let onchain_version = runtime.version(); match ( use_native, onchain_version @@ -160,25 +170,9 @@ impl CodeExecutor for NativeExecutor".into(), |v| format!("{}", v)) ); - ( - cached_runtime.with(|module| - self.fallback - .call_in_wasm_module(ext, module, method, data) - .map(NativeOrEncoded::Encoded) - ), - false - ) - } - (false, _, _) => { - ( - cached_runtime.with(|module| - self.fallback - .call_in_wasm_module(ext, module, method, data) - .map(NativeOrEncoded::Encoded) - ), - false - ) + runtime.call(ext, method, data).map(NativeOrEncoded::Encoded) } + (false, _, _) => runtime.call(ext, method, data).map(NativeOrEncoded::Encoded), (true, true, Some(call)) => { trace!( target: "executor", @@ -188,11 +182,13 @@ impl CodeExecutor for NativeExecutor".into(), |v| format!("{}", v)) ); - ( - with_native_environment(ext, move || (call)()) - .and_then(|r| r.map(NativeOrEncoded::Native).map_err(|s| Error::ApiError(s.to_string()))), - true - ) + + used_native = true; + with_native_environment(ext, move || (call)()) + .and_then(|r| r + .map(NativeOrEncoded::Native) + .map_err(|s| Error::ApiError(s.to_string())) + ) } _ => { trace!( @@ -201,31 +197,28 @@ impl CodeExecutor for NativeExecutor".into(), |v| format!("{}", v)) ); - (D::dispatch(ext, method, data).map(NativeOrEncoded::Encoded), true) + + used_native = true; + D::dispatch(ext, method, data).map(NativeOrEncoded::Encoded) } } - }) + }); + (result, used_native) } } /// Implements a `NativeExecutionDispatch` for provided parameters. #[macro_export] macro_rules! native_executor_instance { - ( $pub:vis $name:ident, $dispatcher:path, $version:path, $code:expr) => { + ( $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>, + ext: &mut $crate::Externalities, method: &str, data: &[u8] ) -> $crate::error::Result> { diff --git a/core/executor/src/sandbox.rs b/core/executor/src/sandbox.rs index 6687738abc89750acefae9b9dbdc39bba5a27ec1..e1e9e0db95263ab946cf2a8e0279020a8bbc7426 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 @@ -562,17 +586,31 @@ impl Store { #[cfg(test)] mod tests { use super::*; - use primitives::{Blake2Hasher}; - use crate::wasm_executor::WasmExecutor; + use primitives::{Blake2Hasher, traits::Externalities}; + use crate::wasm_runtime::WasmRuntime; + use crate::wasmi_execution; use state_machine::TestExternalities as CoreTestExternalities; use wabt; use runtime_test::WASM_BINARY; - type TestExternalities = CoreTestExternalities; + type TestExternalities = CoreTestExternalities; + + fn call_wasm( + ext: &mut E, + heap_pages: u64, + code: &[u8], + method: &str, + data: &[u8], + ) -> Result> { + let mut instance = wasmi_execution::create_instance(ext, code, heap_pages) + .map_err(|err| err.to_string())?; + instance.call(ext, method, data) + } #[test] fn sandbox_should_work() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -594,17 +632,18 @@ mod tests { call $assert ) ) - "#).unwrap(); + "#).unwrap().encode(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(), - vec![1], + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(), + true.encode(), ); } #[test] fn sandbox_trap() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -618,14 +657,15 @@ mod tests { "#).unwrap(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(), + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(), vec![0], ); } #[test] fn sandbox_should_trap_when_heap_exhausted() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -636,21 +676,25 @@ mod tests { call $assert ) ) - "#).unwrap(); + "#).unwrap().encode(); - let res = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_exhaust_heap", &code); + let res = call_wasm(&mut ext, 8, &test_code[..], "test_exhaust_heap", &code); assert_eq!(res.is_err(), true); 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()), + ), ); } } #[test] fn start_called() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -678,17 +722,18 @@ mod tests { call $assert ) ) - "#).unwrap(); + "#).unwrap().encode(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(), - vec![1], + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(), + true.encode(), ); } #[test] fn invoke_args() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -712,17 +757,18 @@ mod tests { ) ) ) - "#).unwrap(); + "#).unwrap().encode(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_args", &code).unwrap(), - vec![1], + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_args", &code).unwrap(), + true.encode(), ); } #[test] fn return_val() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -734,17 +780,18 @@ mod tests { ) ) ) - "#).unwrap(); + "#).unwrap().encode(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_return_val", &code).unwrap(), - vec![1], + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_return_val", &code).unwrap(), + true.encode(), ); } #[test] fn unlinkable_module() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -754,31 +801,33 @@ mod tests { (func (export "call") ) ) - "#).unwrap(); + "#).unwrap().encode(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), - vec![1], + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), + 1u8.encode(), ); } #[test] fn corrupted_module() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; // Corrupted wasm file - let code = &[0, 0, 0, 0, 1, 0, 0, 0]; + let code = vec![0u8, 0, 0, 0, 1, 0, 0, 0].encode(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", code).unwrap(), - vec![1], + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), + 1u8.encode(), ); } #[test] fn start_fn_ok() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -791,17 +840,18 @@ mod tests { (start $start) ) - "#).unwrap(); + "#).unwrap().encode(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), - vec![0], + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), + 0u8.encode(), ); } #[test] fn start_fn_traps() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -815,11 +865,11 @@ mod tests { (start $start) ) - "#).unwrap(); + "#).unwrap().encode(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), - vec![2], + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), + 2u8.encode(), ); } } diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs deleted file mode 100644 index b22fe3d363af37986f271778a9597fa15bd749b6..0000000000000000000000000000000000000000 --- a/core/executor/src/wasm_executor.rs +++ /dev/null @@ -1,1747 +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 . - -//! Rust implementation of Substrate contracts. - -use std::{collections::HashMap, convert::TryFrom, str}; -use tiny_keccak; -use secp256k1; - -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 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, -}; -use trie::{TrieConfiguration, trie_types::Layout}; -use crate::sandbox; -use crate::allocator; -use log::trace; - -#[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, - 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 { - Ok(FunctionExecutor { - sandbox_store: sandbox::Store::new(), - heap: allocator::FreeingBumpHeapAllocator::new(m.clone(), 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 { - &self.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 deallocate(&mut self, ptr: u32) -> Result<()> { - self.heap.deallocate(ptr) - } - fn write_memory(&mut self, ptr: u32, data: &[u8]) -> Result<()> { - self.memory.set(ptr, 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) - } -} - -trait WritePrimitive { - fn write_primitive(&self, offset: u32, t: T) -> Result<()>; -} - -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) - } -} - -trait ReadPrimitive { - fn read_primitive(&self, offset: u32) -> Result; -} - -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)) - } -} - -fn deadline_to_timestamp(deadline: u64) -> Option { - if deadline == 0 { - None - } else { - Some(offchain::Timestamp::from_unix_millis(deadline)) - } -} - -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); - } - } - 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), - ); - } - 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) - ); - } - 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)) - } 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)) - } 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)) - } else { - format!(" {}", ::primitives::hexdisplay::ascii_format(&key)) - }, - if let Some(ref b) = maybe_value { - &format!("{}", HexDisplay::from(b)) - } else { - "" - }, - HexDisplay::from(&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")?; - 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)) - } else { - format!(" {}", ::primitives::hexdisplay::ascii_format(&key)) - }, - if let Some(ref b) = maybe_value { - &format!("{}", HexDisplay::from(b)) - } else { - "" - }, - HexDisplay::from(&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) - } - }, - // 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)) - } else { - format!(" {}", primitives::hexdisplay::ascii_format(&key)) - }, - if let Some(ref b) = maybe_value { - &format!("{}", HexDisplay::from(b)) - } else { - "" - }, - HexDisplay::from(&key), - ); - - 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)) - } else { - format!(" {}", ::primitives::hexdisplay::ascii_format(&key)) - }, - if let Some(ref b) = maybe_value { - &format!("{}", HexDisplay::from(b)) - } else { - "" - }, - HexDisplay::from(&key), - ); - - 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_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)) - }, - HexDisplay::from(&hashed_key), - ); - - this.hash_lookup.insert(hashed_key.to_vec(), key); - hashed_key - }; - - 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)) - }, - HexDisplay::from(&hashed_key), - ); - this.hash_lookup.insert(hashed_key.to_vec(), key); - hashed_key - }; - - 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 - }; - - 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 = this.ext - .keystore() - .ok_or("No `keystore` associated for the current context!")? - .read() - .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 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 = this.ext - .keystore() - .ok_or("No `keystore` associated for the current context!")? - .write() - .ed25519_generate_new(key_type, seed) - .map_err(|_| "`ed25519` key generation failed")?; - - 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 pub_key = ed25519::Public::try_from(pubkey.as_ref()) - .map_err(|_| "Invalid `ed25519` public key")?; - - let signature = this.ext - .keystore() - .ok_or("No `keystore` associated for the current context!")? - .read() - .ed25519_key_pair(key_type, &pub_key) - .map(|k| k.sign(msg.as_ref())); - - 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 = this.ext - .keystore() - .ok_or("No `keystore` associated for the current context!")? - .read() - .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 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 = this.ext - .keystore() - .ok_or("No `keystore` associated for the current context!")? - .write() - .sr25519_generate_new(key_type, seed) - .map_err(|_| "`sr25519` key generation failed")?; - - 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 pub_key = sr25519::Public::try_from(pubkey.as_ref()) - .map_err(|_| "Invalid `sr25519` public key")?; - - let signature = this.ext - .keystore() - .ok_or("No `keystore` associated for the current context!")? - .read() - .sr25519_key_pair(key_type, &pub_key) - .map(|k| k.sign(msg.as_ref())); - - 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 mut msg = [0u8; 32]; - this.memory.get_into(msg_data, &mut msg[..]) - .map_err(|_| "Invalid attempt to get message in ext_secp256k1_ecdsa_recover")?; - - let pubkey = match secp256k1::recover(&secp256k1::Message::parse(&msg), &rs, &v) { - Ok(pk) => pk, - _ => return Ok(3), - }; - - this.memory.set(pubkey_data, &pubkey.serialize()[1..65]) - .map_err(|_| "Invalid attempt to set pubkey in ext_secp256k1_ecdsa_recover")?; - - Ok(0) - }, - ext_is_validator() -> u32 => { - this.ext.offchain() - .map(|o| if o.is_validator() { 1 } else { 0 }) - .ok_or("Calling unavailable API ext_is_validator: wasm".into()) - }, - 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()) - }; - - 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_len == 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")? - } 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")? - } - }; - - 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( - offchain::HttpRequestId(request_id as u16), - &chunk, - deadline_to_timestamp(deadline) - )) - .ok_or_else(|| "Calling unavailable API ext_http_request_write_body: wasm")?; - - 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, _>>()?; - - 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( - offchain::HttpRequestId(request_id as u16), - &mut internal_buffer, - 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")?; - - read as u32 - }, - Err(err) => { - u32::max_value() - u32::from(err) + 1 - } - }) - }, - 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() - }; - - 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, - }; - - 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") - )?; - - // 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 instance = this.sandbox_store.instance(instance_idx)?; - let result = instance.invoke(&export, &args, this, 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")?; - } - 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), - } - }, - 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)?; - - 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), - } - }, - ext_sandbox_memory_teardown(memory_idx: u32) => { - this.sandbox_store.memory_teardown(memory_idx)?; - Ok(()) - }, - => <'e, E: Externalities + 'e> -); - -/// Wasm rust executor for contracts. -/// -/// Executes the provided code in a sandboxed wasm runtime. -#[derive(Debug, Clone)] -pub struct WasmExecutor; - -impl WasmExecutor { - - /// Create a new instance. - pub fn new() -> Self { - WasmExecutor - } - - /// Call a given method in the given code. - /// - /// Signature of this method needs to be `(I32, I32) -> I64`. - /// - /// This should be used for tests only. - pub fn call>( - &self, - ext: &mut E, - heap_pages: usize, - code: &[u8], - method: &str, - data: &[u8], - ) -> Result> { - let module = ::wasmi::Module::from_buffer(code)?; - let module = Self::instantiate_module::(heap_pages, &module)?; - self.call_in_wasm_module(ext, &module, method, data) - } - - /// Call a given method with a custom signature in the given code. - /// - /// This should be used for tests only. - pub fn call_with_custom_signature< - E: Externalities, - F: FnOnce(&mut dyn FnMut(&[u8]) -> Result) -> Result>, - FR: FnOnce(Option, &MemoryRef) -> Result>, - R, - >( - &self, - ext: &mut E, - heap_pages: usize, - code: &[u8], - method: &str, - create_parameters: F, - filter_result: FR, - ) -> Result { - let module = wasmi::Module::from_buffer(code)?; - let module = Self::instantiate_module::(heap_pages, &module)?; - self.call_in_wasm_module_with_custom_signature( - ext, - &module, - method, - create_parameters, - filter_result, - ) - } - - fn get_mem_instance(module: &ModuleRef) -> Result { - Ok(module - .export_by_name("memory") - .ok_or_else(|| Error::InvalidMemoryReference)? - .as_memory() - .ok_or_else(|| Error::InvalidMemoryReference)? - .clone()) - } - - /// Find the global named `__heap_base` in the given wasm module instance and - /// tries to get its value. - fn get_heap_base(module: &ModuleRef) -> Result { - let heap_base_val = module - .export_by_name("__heap_base") - .ok_or_else(|| Error::HeapBaseNotFoundOrInvalid)? - .as_global() - .ok_or_else(|| Error::HeapBaseNotFoundOrInvalid)? - .get(); - - Ok(match heap_base_val { - wasmi::RuntimeValue::I32(v) => v as u32, - _ => return Err(Error::HeapBaseNotFoundOrInvalid), - }) - } - - /// Call a given method in the given wasm-module runtime. - pub fn call_in_wasm_module>( - &self, - ext: &mut E, - module_instance: &ModuleRef, - method: &str, - data: &[u8], - ) -> Result> { - self.call_in_wasm_module_with_custom_signature( - ext, - module_instance, - method, - |alloc| { - let offset = alloc(data)?; - Ok(vec![I32(offset as i32), I32(data.len() as i32)]) - }, - |res, memory| { - if let Some(I64(r)) = res { - let offset = r as u32; - let length = (r as u64 >> 32) as usize; - memory.get(offset, length).map_err(|_| Error::Runtime).map(Some) - } else { - Ok(None) - } - } - ) - } - - /// Call a given method in the given wasm-module runtime. - fn call_in_wasm_module_with_custom_signature< - E: Externalities, - F: FnOnce(&mut dyn FnMut(&[u8]) -> Result) -> Result>, - FR: FnOnce(Option, &MemoryRef) -> Result>, - R, - >( - &self, - ext: &mut E, - module_instance: &ModuleRef, - method: &str, - create_parameters: F, - filter_result: FR, - ) -> Result { - // extract a reference to a linear memory, optional reference to a table - // and then initialize FunctionExecutor. - let memory = Self::get_mem_instance(module_instance)?; - let table: Option = module_instance - .export_by_name("__indirect_function_table") - .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 parameters = create_parameters(&mut |data: &[u8]| { - let offset = fec.heap.allocate(data.len() as u32)?; - memory.set(offset, &data)?; - Ok(offset) - })?; - - let result = module_instance.invoke_export( - method, - ¶meters, - &mut fec - ); - let 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); - Err(e.into()) - }, - }; - - result - } - - /// Prepare module instance - pub fn instantiate_module>( - heap_pages: usize, - module: &Module, - ) -> Result { - // start module instantiation. Don't run 'start' function yet. - let intermediate_instance = ModuleInstance::new( - module, - &ImportsBuilder::new() - .with_resolver("env", FunctionExecutor::::resolver()) - )?; - - // Verify that the module has the heap base global variable. - let _ = Self::get_heap_base(intermediate_instance.not_started_instance())?; - - // Extract a reference to a linear memory. - let memory = Self::get_mem_instance(intermediate_instance.not_started_instance())?; - memory.grow(Pages(heap_pages)).map_err(|_| Error::Runtime)?; - - if intermediate_instance.has_start() { - // Runtime is not allowed to have the `start` function. - Err(Error::RuntimeHasStartFn) - } else { - Ok(intermediate_instance.assert_no_start()) - } - } -} - - -#[cfg(test)] -mod tests { - use super::*; - - use codec::Encode; - - use state_machine::TestExternalities as CoreTestExternalities; - use hex_literal::hex; - use primitives::map; - use runtime_test::WASM_BINARY; - use substrate_offchain::testing; - - type TestExternalities = CoreTestExternalities; - - #[test] - fn returning_should_work() { - let mut ext = TestExternalities::default(); - let test_code = WASM_BINARY; - - let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_empty_return", &[]).unwrap(); - assert_eq!(output, vec![0u8; 0]); - } - - #[test] - fn panicking_should_work() { - let mut ext = TestExternalities::default(); - let test_code = WASM_BINARY; - - let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_panic", &[]); - assert!(output.is_err()); - - let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_conditional_panic", &[]); - assert_eq!(output.unwrap(), vec![0u8; 0]); - - let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_conditional_panic", &[2]); - assert!(output.is_err()); - } - - #[test] - fn storage_should_work() { - let mut ext = TestExternalities::default(); - ext.set_storage(b"foo".to_vec(), b"bar".to_vec()); - let test_code = WASM_BINARY; - - let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_data_in", b"Hello world").unwrap(); - - assert_eq!(output, b"all ok!".to_vec()); - - let expected = TestExternalities::new((map![ - b"input".to_vec() => b"Hello world".to_vec(), - b"foo".to_vec() => b"bar".to_vec(), - b"baz".to_vec() => b"bar".to_vec() - ], map![])); - assert_eq!(ext, expected); - } - - #[test] - fn clear_prefix_should_work() { - let mut ext = TestExternalities::default(); - ext.set_storage(b"aaa".to_vec(), b"1".to_vec()); - ext.set_storage(b"aab".to_vec(), b"2".to_vec()); - ext.set_storage(b"aba".to_vec(), b"3".to_vec()); - ext.set_storage(b"abb".to_vec(), b"4".to_vec()); - ext.set_storage(b"bbb".to_vec(), b"5".to_vec()); - let test_code = WASM_BINARY; - - // This will clear all entries which prefix is "ab". - let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_clear_prefix", b"ab").unwrap(); - - assert_eq!(output, b"all ok!".to_vec()); - - let expected = TestExternalities::new((map![ - b"aaa".to_vec() => b"1".to_vec(), - b"aab".to_vec() => b"2".to_vec(), - b"bbb".to_vec() => b"5".to_vec() - ], map![])); - assert_eq!(expected, ext); - } - - #[test] - fn blake2_256_should_work() { - let mut ext = TestExternalities::default(); - let test_code = WASM_BINARY; - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_blake2_256", &[]).unwrap(), - blake2_256(&b""[..]).encode() - ); - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_blake2_256", b"Hello world!").unwrap(), - blake2_256(&b"Hello world!"[..]).encode() - ); - } - - #[test] - fn blake2_128_should_work() { - let mut ext = TestExternalities::default(); - let test_code = WASM_BINARY; - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_blake2_128", &[]).unwrap(), - blake2_128(&b""[..]).encode() - ); - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_blake2_128", b"Hello world!").unwrap(), - blake2_128(&b"Hello world!"[..]).encode() - ); - } - - #[test] - fn twox_256_should_work() { - let mut ext = TestExternalities::default(); - let test_code = WASM_BINARY; - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_256", &[]).unwrap(), - hex!("99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a") - ); - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_256", b"Hello world!").unwrap(), - hex!("b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74") - ); - } - - #[test] - fn twox_128_should_work() { - let mut ext = TestExternalities::default(); - let test_code = WASM_BINARY; - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_128", &[]).unwrap(), - hex!("99e9d85137db46ef4bbea33613baafd5") - ); - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_128", b"Hello world!").unwrap(), - hex!("b27dfd7f223f177f2a13647b533599af") - ); - } - - #[test] - fn ed25519_verify_should_work() { - let mut ext = TestExternalities::::default(); - let test_code = WASM_BINARY; - let key = ed25519::Pair::from_seed(&blake2_256(b"test")); - let sig = key.sign(b"all ok!"); - let mut calldata = vec![]; - calldata.extend_from_slice(key.public().as_ref()); - calldata.extend_from_slice(sig.as_ref()); - - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata).unwrap(), - vec![1] - ); - - let other_sig = key.sign(b"all is not ok!"); - let mut calldata = vec![]; - calldata.extend_from_slice(key.public().as_ref()); - calldata.extend_from_slice(other_sig.as_ref()); - - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata).unwrap(), - vec![0] - ); - } - - #[test] - fn sr25519_verify_should_work() { - let mut ext = TestExternalities::::default(); - let test_code = WASM_BINARY; - let key = sr25519::Pair::from_seed(&blake2_256(b"test")); - let sig = key.sign(b"all ok!"); - let mut calldata = vec![]; - calldata.extend_from_slice(key.public().as_ref()); - calldata.extend_from_slice(sig.as_ref()); - - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sr25519_verify", &calldata).unwrap(), - vec![1] - ); - - let other_sig = key.sign(b"all is not ok!"); - let mut calldata = vec![]; - calldata.extend_from_slice(key.public().as_ref()); - calldata.extend_from_slice(other_sig.as_ref()); - - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sr25519_verify", &calldata).unwrap(), - vec![0] - ); - } - - #[test] - fn ordered_trie_root_should_work() { - let mut ext = TestExternalities::::default(); - let trie_input = vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]; - let test_code = WASM_BINARY; - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_ordered_trie_root", &[]).unwrap(), - Layout::::ordered_trie_root(trie_input.iter()).as_fixed_bytes().encode() - ); - } - - #[test] - fn offchain_local_storage_should_work() { - use substrate_client::backend::OffchainStorage; - - let mut ext = TestExternalities::::default(); - let (offchain, state) = testing::TestOffchainExt::new(); - ext.set_offchain_externalities(offchain); - let test_code = WASM_BINARY; - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_offchain_local_storage", &[]).unwrap(), - vec![0] - ); - assert_eq!(state.read().persistent_storage.get(b"", b"test"), Some(vec![])); - } - - #[test] - fn offchain_http_should_work() { - let mut ext = TestExternalities::::default(); - let (offchain, state) = testing::TestOffchainExt::new(); - ext.set_offchain_externalities(offchain); - state.write().expect_request( - 0, - testing::PendingRequest { - method: "POST".into(), - uri: "http://localhost:12345".into(), - body: vec![1, 2, 3, 4], - headers: vec![("X-Auth".to_owned(), "test".to_owned())], - sent: true, - response: vec![1, 2, 3], - response_headers: vec![("X-Auth".to_owned(), "hello".to_owned())], - ..Default::default() - }, - ); - - let test_code = WASM_BINARY; - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_offchain_http", &[]).unwrap(), - vec![0] - ); - } -} diff --git a/core/executor/src/wasm_runtime.rs b/core/executor/src/wasm_runtime.rs new file mode 100644 index 0000000000000000000000000000000000000000..8d2291fe048932cedf247cf5c05c02a5f8d5a8fd --- /dev/null +++ b/core/executor/src/wasm_runtime.rs @@ -0,0 +1,183 @@ +// 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 . + +//! Traits and accessor functions for calling into the Substrate Wasm runtime. +//! +//! The primary means of accessing the runtimes is through a cache which saves the reusable +//! components of the runtime that are expensive to initialize. + +use crate::error::{Error, WasmError}; +use crate::wasmi_execution; +use log::{trace, warn}; +use codec::Decode; +use primitives::{storage::well_known_keys, traits::Externalities}; +use runtime_version::RuntimeVersion; +use std::{collections::hash_map::{Entry, HashMap}}; + +/// The Substrate Wasm runtime. +pub trait WasmRuntime { + /// Attempt to update the number of heap pages available during execution. + /// + /// Returns false if the update cannot be applied. The function is guaranteed to return true if + /// the heap pages would not change from its current value. + fn update_heap_pages(&mut self, heap_pages: u64) -> bool; + + /// Call a method in the Substrate runtime by name. Returns the encoded result on success. + fn call(&mut self, ext: &mut dyn Externalities, method: &str, data: &[u8]) + -> Result, Error>; + + /// Returns the version of this runtime. + /// + /// Returns `None` if the runtime doesn't provide the information or there was an error + /// while fetching it. + fn version(&self) -> Option; +} + +/// Specification of different methods of executing the runtime Wasm code. +#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] +pub enum WasmExecutionMethod { + /// Uses the Wasmi interpreter. + Interpreted, +} + +/// Cache for the runtimes. +/// +/// When an instance is requested for the first time it is added to this cache. Metadata is kept +/// with the instance so that it can be efficiently reinitialized. +/// +/// When using the Wasmi interpreter execution method, the metadata includes the initial memory and +/// values of mutable globals. Follow-up requests to fetch a runtime return this one instance with +/// the memory reset to the initial memory. So, one runtime instance is reused for every fetch +/// request. +/// +/// For now the cache grows indefinitely, but that should be fine for now since runtimes can only be +/// upgraded rarely and there are no other ways to make the node to execute some other runtime. +pub struct RuntimesCache { + /// A cache of runtime instances along with metadata, ready to be reused. + /// + /// Instances are keyed by the Wasm execution method and the hash of their code. + instances: HashMap<(WasmExecutionMethod, [u8; 32]), Result, WasmError>>, +} + +impl RuntimesCache { + /// Creates a new instance of a runtimes cache. + pub fn new() -> RuntimesCache { + RuntimesCache { + instances: HashMap::new(), + } + } + + /// Fetches an instance of the runtime. + /// + /// On first use we create a new runtime instance, save it to the cache + /// and persist its initial memory. + /// + /// Each subsequent request will return this instance, with its memory restored + /// to the persisted initial memory. Thus, we reuse one single runtime instance + /// for every `fetch_runtime` invocation. + /// + /// # Parameters + /// + /// `ext` - Externalities to use for the runtime. This is used for setting + /// up an initial runtime instance. The parameter is only needed for calling + /// into the Wasm module to find out the `Core_version`. + /// + /// `default_heap_pages` - Number of 64KB pages to allocate for Wasm execution. + /// + /// # Return value + /// + /// If no error occurred a tuple `(wasmi::ModuleRef, Option)` is + /// returned. `RuntimeVersion` is contained if the call to `Core_version` returned + /// a version. + /// + /// In case of failure one of two errors can be returned: + /// + /// `Err::InvalidCode` is returned for runtime code issues. + /// + /// `Error::InvalidMemoryReference` is returned if no memory export with the + /// identifier `memory` can be found in the runtime. + pub fn fetch_runtime( + &mut self, + ext: &mut E, + wasm_method: WasmExecutionMethod, + default_heap_pages: u64, + ) -> Result<&mut (dyn WasmRuntime + 'static), Error> { + let code_hash = ext + .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()) + .unwrap_or(default_heap_pages); + + let result = match self.instances.entry((wasm_method, code_hash.into())) { + Entry::Occupied(o) => { + let result = o.into_mut(); + if let Ok(ref mut cached_runtime) = result { + if !cached_runtime.update_heap_pages(heap_pages) { + trace!( + target: "runtimes_cache", + "heap_pages were changed. Reinstantiating the instance" + ); + *result = create_wasm_runtime(ext, wasm_method, heap_pages); + if let Err(ref err) = result { + warn!(target: "runtimes_cache", "cannot create a runtime: {:?}", err); + } + } + } + result + }, + Entry::Vacant(v) => { + trace!(target: "runtimes_cache", "no instance found in cache, creating now."); + let result = create_wasm_runtime(ext, wasm_method, heap_pages); + if let Err(ref err) = result { + warn!(target: "runtimes_cache", "cannot create a runtime: {:?}", err); + } + v.insert(result) + } + }; + + result.as_mut() + .map(|runtime| runtime.as_mut()) + .map_err(|ref e| Error::InvalidCode(format!("{:?}", e))) + } +} + +/// Create a wasm runtime with the given `code`. +pub fn create_wasm_runtime_with_code( + ext: &mut E, + wasm_method: WasmExecutionMethod, + heap_pages: u64, + code: &[u8], +) -> Result, WasmError> { + match wasm_method { + WasmExecutionMethod::Interpreted => + wasmi_execution::create_instance(ext, code, heap_pages) + .map(|runtime| -> Box { Box::new(runtime) }), + } +} + +fn create_wasm_runtime( + ext: &mut E, + wasm_method: WasmExecutionMethod, + heap_pages: u64, +) -> Result, WasmError> { + let code = ext + .original_storage(well_known_keys::CODE) + .ok_or(WasmError::CodeNotFound)?; + create_wasm_runtime_with_code(ext, wasm_method, heap_pages, &code) +} diff --git a/core/executor/src/wasm_runtimes_cache.rs b/core/executor/src/wasm_runtimes_cache.rs deleted file mode 100644 index 57845f81268499fa646e1adf3c5a11299f12c28e..0000000000000000000000000000000000000000 --- a/core/executor/src/wasm_runtimes_cache.rs +++ /dev/null @@ -1,346 +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 . - -//! Implements a cache for pre-created Wasm runtime module instances. - -use crate::error::Error; -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 runtime_version::RuntimeVersion; -use state_machine::Externalities; -use std::collections::hash_map::{Entry, HashMap}; -use std::mem; -use std::rc::Rc; -use wasmi::{Module as WasmModule, ModuleRef as WasmModuleInstanceRef, RuntimeValue}; - -#[derive(Debug)] -enum CacheError { - CodeNotFound, - ApplySnapshotFailed, - InvalidModule, - CantDeserializeWasm, - Instantiation(Error), -} - -/// A runtime along with its version and initial state snapshot. -#[derive(Clone)] -pub struct CachedRuntime { - /// A wasm module instance. - instance: WasmModuleInstanceRef, - /// Runtime version according to `Core_version`. - /// - /// Can be `None` if the runtime doesn't expose this function. - version: Option, - /// The snapshot of the instance's state taken just after the instantiation. - state_snapshot: StateSnapshot, -} - -impl CachedRuntime { - /// Perform an operation with the clean version of the runtime wasm instance. - pub fn with(&self, f: F) -> R - where - F: FnOnce(&WasmModuleInstanceRef) -> R, - { - self.state_snapshot.apply(&self.instance).expect( - "applying the snapshot can only fail if the passed instance is different - from the one that was used for creation of the snapshot; - we use the snapshot that is directly associated with the instance; - thus the snapshot was created using the instance; - qed", - ); - f(&self.instance) - } - - /// Returns the version of this cached runtime. - /// - /// Returns `None` if the runtime doesn't provide the information or there was an error - /// while fetching it. - pub fn version(&self) -> Option { - self.version.clone() - } -} - -/// A state snapshot of an instance taken just after instantiation. -/// -/// It is used for restoring the state of the module after execution. -#[derive(Clone)] -struct StateSnapshot { - /// The offset and the content of the memory segments that should be used to restore the snapshot - 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: u64, -} - -impl StateSnapshot { - // Returns `None` if instance is not valid. - fn take( - module_instance: &WasmModuleInstanceRef, - data_segments: Vec, - heap_pages: u64, - ) -> Option { - let prepared_segments = data_segments - .into_iter() - .map(|mut segment| { - // Just replace contents of the segment since the segments will be discarded later - // anyway. - let contents = mem::replace(segment.value_mut(), vec![]); - - let init_expr = segment.offset().code(); - // [op, End] - if init_expr.len() != 2 { - return None; - } - let offset = match init_expr[0] { - Instruction::I32Const(v) => v as u32, - Instruction::GetGlobal(idx) => { - let global_val = module_instance.globals().get(idx as usize)?.get(); - match global_val { - RuntimeValue::I32(v) => v as u32, - _ => return None, - } - } - _ => return None, - }; - - Some((offset, contents)) - }) - .collect::>>()?; - - // Collect all values of mutable globals. - let global_mut_values = module_instance - .globals() - .iter() - .filter(|g| g.is_mutable()) - .map(|g| g.get()) - .collect(); - - Some(Self { - data_segments: prepared_segments, - global_mut_values, - heap_pages, - }) - } - - /// Reset the runtime instance to the initial version by restoring - /// the preserved memory and globals. - /// - /// Returns `Err` if applying the snapshot is failed. - fn apply(&self, instance: &WasmModuleInstanceRef) -> Result<(), CacheError> { - let memory = instance - .export_by_name("memory") - .ok_or(CacheError::ApplySnapshotFailed)? - .as_memory() - .cloned() - .ok_or(CacheError::ApplySnapshotFailed)?; - - // First, erase the memory and copy the data segments into it. - memory - .erase() - .map_err(|_| CacheError::ApplySnapshotFailed)?; - for (offset, contents) in &self.data_segments { - memory - .set(*offset, contents) - .map_err(|_| CacheError::ApplySnapshotFailed)?; - } - - // Second, restore the values of mutable globals. - for (global_ref, global_val) in instance - .globals() - .iter() - .filter(|g| g.is_mutable()) - .zip(self.global_mut_values.iter()) - { - // the instance should be the same as used for preserving and - // we iterate the same way it as we do it for preserving values that means that the - // types should be the same and all the values are mutable. So no error is expected/ - global_ref - .set(*global_val) - .map_err(|_| CacheError::ApplySnapshotFailed)?; - } - Ok(()) - } -} - -/// Default num of pages for the heap -const DEFAULT_HEAP_PAGES: u64 = 1024; - -/// Cache for the runtimes. -/// -/// When an instance is requested for the first time it is added to this -/// cache. Furthermore its initial memory and values of mutable globals are preserved here. Follow-up -/// requests to fetch a runtime return this one instance with the memory -/// reset to the initial memory. So, one runtime instance is reused for -/// every fetch request. -/// -/// For now the cache grows indefinitely, but that should be fine for now since runtimes can only be -/// upgraded rarely and there are no other ways to make the node to execute some other runtime. -pub struct RuntimesCache { - /// A cache of runtime instances along with metadata, ready to be reused. - /// - /// Instances are keyed by the hash of their code. - instances: HashMap<[u8; 32], Result, CacheError>>, -} - -impl RuntimesCache { - /// Creates a new instance of a runtimes cache. - pub fn new() -> RuntimesCache { - RuntimesCache { - instances: HashMap::new(), - } - } - - /// Fetches an instance of the runtime. - /// - /// On first use we create a new runtime instance, save it to the cache - /// and persist its initial memory. - /// - /// Each subsequent request will return this instance, with its memory restored - /// to the persisted initial memory. Thus, we reuse one single runtime instance - /// for every `fetch_runtime` invocation. - /// - /// # Parameters - /// - /// `wasm_executor`- Rust wasm executor. Executes the provided code in a - /// sandboxed Wasm runtime. - /// - /// `ext` - Externalities to use for the runtime. This is used for setting - /// up an initial runtime instance. The parameter is only needed for calling - /// into the Wasm module to find out the `Core_version`. - /// - /// `default_heap_pages` - Number of 64KB pages to allocate for Wasm execution. - /// Defaults to `DEFAULT_HEAP_PAGES` if `None` is provided. - /// - /// # Return value - /// - /// If no error occurred a tuple `(wasmi::ModuleRef, Option)` is - /// returned. `RuntimeVersion` is contained if the call to `Core_version` returned - /// a version. - /// - /// In case of failure one of two errors can be returned: - /// - /// `Err::InvalidCode` is returned for runtime code issues. - /// - /// `Error::InvalidMemoryReference` is returned if no memory export with the - /// identifier `memory` can be found in the runtime. - pub fn fetch_runtime>( - &mut self, - wasm_executor: &WasmExecutor, - ext: &mut E, - default_heap_pages: Option, - ) -> Result, Error> { - let code_hash = ext - .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 { - Err(ref e) => Err(Error::InvalidCode(format!("{:?}", e))), - Ok(ref cached_runtime) => Ok(Rc::clone(cached_runtime)), - }; - - match self.instances.entry(code_hash.into()) { - 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, heap_pages); - if let Err(ref err) = result { - warn!(target: "runtimes_cache", "cannot create a runtime: {:?}", err); - } - handle_result(v.insert(result)) - } - } - } - - fn create_wasm_instance>( - wasm_executor: &WasmExecutor, - ext: &mut E, - heap_pages: u64, - ) -> Result, CacheError> { - let code = ext - .original_storage(well_known_keys::CODE) - .ok_or(CacheError::CodeNotFound)?; - let module = WasmModule::from_buffer(&code).map_err(|_| CacheError::InvalidModule)?; - - // Extract the data segments from the wasm code. - // - // 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)?; - - // Instantiate this 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) - .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; - qed - ", - ); - - let version = wasm_executor - .call_in_wasm_module(ext, &instance, "Core_version", &[]) - .ok() - .and_then(|v| RuntimeVersion::decode(&mut v.as_slice()).ok()); - Ok(Rc::new(CachedRuntime { - instance, - version, - state_snapshot, - })) - } -} - -/// 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()?; - let segments = raw_module - .data_section() - .map(|ds| ds.entries()) - .unwrap_or(&[]) - .to_vec(); - Some(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/executor/src/wasmi_execution.rs b/core/executor/src/wasmi_execution.rs new file mode 100644 index 0000000000000000000000000000000000000000..2b832b490641de116ce03dc1adec41025f1d9c60 --- /dev/null +++ b/core/executor/src/wasmi_execution.rs @@ -0,0 +1,963 @@ +// 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 . + +//! Implementation of a Wasm runtime using the Wasmi interpreter. + +use std::{str, mem}; +use wasmi::{ + Module, ModuleInstance, MemoryInstance, MemoryRef, TableRef, ImportsBuilder, ModuleRef, + memory_units::Pages, RuntimeValue::{I32, I64, self}, +}; +use crate::error::{Error, WasmError}; +use codec::{Encode, Decode}; +use primitives::{sandbox as sandbox_primitives, traits::Externalities}; +use crate::host_interface::SubstrateExternals; +use crate::sandbox; +use crate::allocator; +use crate::wasm_runtime::WasmRuntime; +use log::trace; +use parity_wasm::elements::{deserialize_buffer, DataSegment, Instruction, Module as RawModule}; +use runtime_version::RuntimeVersion; +use wasm_interface::{ + FunctionContext, HostFunctions, Pointer, WordSize, Sandbox, MemoryId, Result as WResult, +}; + +struct FunctionExecutor { + sandbox_store: sandbox::Store, + heap: allocator::FreeingBumpHeapAllocator, + memory: MemoryRef, + table: Option, +} + +impl FunctionExecutor { + fn new(m: MemoryRef, heap_base: u32, t: Option) -> Result { + Ok(FunctionExecutor { + sandbox_store: sandbox::Store::new(), + heap: allocator::FreeingBumpHeapAllocator::new(heap_base), + memory: m, + table: t, + }) + } +} + +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 { + &mut self.sandbox_store + } + fn allocate(&mut self, len: WordSize) -> Result, Error> { + let heap = &mut self.heap; + self.memory.with_direct_access_mut(|mem| { + heap.allocate(mem, len) + }) + } + fn deallocate(&mut self, ptr: Pointer) -> Result<(), Error> { + let heap = &mut self.heap; + self.memory.with_direct_access_mut(|mem| { + heap.deallocate(mem, ptr) + }) + } + fn write_memory(&mut self, ptr: Pointer, data: &[u8]) -> Result<(), Error> { + self.memory.set(ptr.into(), data).map_err(Into::into) + } + fn read_memory(&self, ptr: Pointer, len: WordSize) -> Result, Error> { + 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)), + } + } +} + +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 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) + } +} + +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), + )) + } + } + } + &Resolver + } +} + +impl wasmi::Externals for FunctionExecutor { + fn invoke_index(&mut self, index: usize, args: wasmi::RuntimeArgs) + -> 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)) + } +} + +fn get_mem_instance(module: &ModuleRef) -> Result { + Ok(module + .export_by_name("memory") + .ok_or_else(|| Error::InvalidMemoryReference)? + .as_memory() + .ok_or_else(|| Error::InvalidMemoryReference)? + .clone()) +} + +/// Find the global named `__heap_base` in the given wasm module instance and +/// tries to get its value. +fn get_heap_base(module: &ModuleRef) -> Result { + let heap_base_val = module + .export_by_name("__heap_base") + .ok_or_else(|| Error::HeapBaseNotFoundOrInvalid)? + .as_global() + .ok_or_else(|| Error::HeapBaseNotFoundOrInvalid)? + .get(); + + 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. +fn call_in_wasm_module( + ext: &mut dyn Externalities, + module_instance: &ModuleRef, + method: &str, + data: &[u8], +) -> Result, Error> { + call_in_wasm_module_with_custom_signature( + ext, + module_instance, + method, + |alloc| { + let offset = alloc(data)?; + Ok(vec![I32(offset as i32), I32(data.len() as i32)]) + }, + |res, memory| { + if let Some(I64(r)) = res { + let offset = r as u32; + let length = (r as u64 >> 32) as usize; + memory.get(offset, length).map_err(|_| Error::Runtime).map(Some) + } else { + Ok(None) + } + } + ) +} + +/// Call a given method in the given wasm-module runtime. +fn call_in_wasm_module_with_custom_signature< + F: FnOnce(&mut dyn FnMut(&[u8]) -> Result) -> Result, Error>, + FR: FnOnce(Option, &MemoryRef) -> Result, Error>, + R, +>( + ext: &mut dyn Externalities, + module_instance: &ModuleRef, + method: &str, + create_parameters: F, + filter_result: FR, +) -> Result { + // extract a reference to a linear memory, optional reference to a table + // and then initialize FunctionExecutor. + let memory = get_mem_instance(module_instance)?; + let table: Option = module_instance + .export_by_name("__indirect_function_table") + .and_then(|e| e.as_table().cloned()); + let heap_base = get_heap_base(module_instance)?; + + let mut fec = FunctionExecutor::new( + memory.clone(), + heap_base, + table, + )?; + + let parameters = create_parameters(&mut |data: &[u8]| { + let offset = fec.allocate_memory(data.len() as u32)?; + fec.write_memory(offset, data).map(|_| offset.into()).map_err(Into::into) + })?; + + let result = externalities::set_and_run_with_externalities( + ext, + || module_instance.invoke_export(method, ¶meters, &mut fec), + ); + + 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 + ); + Err(e.into()) + }, + } +} + +/// Prepare module instance +fn instantiate_module( + heap_pages: usize, + module: &Module, +) -> Result { + // start module instantiation. Don't run 'start' function yet. + let intermediate_instance = ModuleInstance::new( + module, + &ImportsBuilder::new() + .with_resolver("env", FunctionExecutor::resolver()) + )?; + + // Verify that the module has the heap base global variable. + let _ = get_heap_base(intermediate_instance.not_started_instance())?; + + // Extract a reference to a linear memory. + let memory = get_mem_instance(intermediate_instance.not_started_instance())?; + memory.grow(Pages(heap_pages)).map_err(|_| Error::Runtime)?; + + if intermediate_instance.has_start() { + // Runtime is not allowed to have the `start` function. + Err(Error::RuntimeHasStartFn) + } else { + Ok(intermediate_instance.assert_no_start()) + } +} + +/// A state snapshot of an instance taken just after instantiation. +/// +/// It is used for restoring the state of the module after execution. +#[derive(Clone)] +struct StateSnapshot { + /// The offset and the content of the memory segments that should be used to restore the snapshot + 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: u64, +} + +impl StateSnapshot { + // Returns `None` if instance is not valid. + fn take( + module_instance: &ModuleRef, + data_segments: Vec, + heap_pages: u64, + ) -> Option { + let prepared_segments = data_segments + .into_iter() + .map(|mut segment| { + // Just replace contents of the segment since the segments will be discarded later + // anyway. + let contents = mem::replace(segment.value_mut(), vec![]); + + 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; + } + let offset = match init_expr[0] { + Instruction::I32Const(v) => v as u32, + Instruction::GetGlobal(idx) => { + let global_val = module_instance.globals().get(idx as usize)?.get(); + match global_val { + RuntimeValue::I32(v) => v as u32, + _ => return None, + } + } + _ => return None, + }; + + Some((offset, contents)) + }) + .collect::>>()?; + + // Collect all values of mutable globals. + let global_mut_values = module_instance + .globals() + .iter() + .filter(|g| g.is_mutable()) + .map(|g| g.get()) + .collect(); + + Some(Self { + data_segments: prepared_segments, + global_mut_values, + heap_pages, + }) + } + + /// Reset the runtime instance to the initial version by restoring + /// the preserved memory and globals. + /// + /// Returns `Err` if applying the snapshot is failed. + fn apply(&self, instance: &ModuleRef) -> Result<(), WasmError> { + let memory = instance + .export_by_name("memory") + .ok_or(WasmError::ApplySnapshotFailed)? + .as_memory() + .cloned() + .ok_or(WasmError::ApplySnapshotFailed)?; + + // First, erase the memory and copy the data segments into it. + memory + .erase() + .map_err(|_| WasmError::ApplySnapshotFailed)?; + for (offset, contents) in &self.data_segments { + memory + .set(*offset, contents) + .map_err(|_| WasmError::ApplySnapshotFailed)?; + } + + // Second, restore the values of mutable globals. + for (global_ref, global_val) in instance + .globals() + .iter() + .filter(|g| g.is_mutable()) + .zip(self.global_mut_values.iter()) + { + // the instance should be the same as used for preserving and + // we iterate the same way it as we do it for preserving values that means that the + // types should be the same and all the values are mutable. So no error is expected/ + global_ref + .set(*global_val) + .map_err(|_| WasmError::ApplySnapshotFailed)?; + } + Ok(()) + } +} + +/// A runtime along with its version and initial state snapshot. +#[derive(Clone)] +pub struct WasmiRuntime { + /// A wasm module instance. + instance: ModuleRef, + /// Runtime version according to `Core_version`. + /// + /// Can be `None` if the runtime doesn't expose this function. + version: Option, + /// The snapshot of the instance's state taken just after the instantiation. + state_snapshot: StateSnapshot, +} + +impl WasmiRuntime { + /// Perform an operation with the clean version of the runtime wasm instance. + fn with(&self, f: F) -> R + where + F: FnOnce(&ModuleRef) -> R, + { + self.state_snapshot.apply(&self.instance).expect( + "applying the snapshot can only fail if the passed instance is different + from the one that was used for creation of the snapshot; + we use the snapshot that is directly associated with the instance; + thus the snapshot was created using the instance; + qed", + ); + f(&self.instance) + } +} + +impl WasmRuntime for WasmiRuntime { + fn update_heap_pages(&mut self, heap_pages: u64) -> bool { + self.state_snapshot.heap_pages == heap_pages + } + + fn call(&mut self, ext: &mut dyn Externalities, method: &str, data: &[u8]) + -> Result, Error> + { + self.with(|module| { + call_in_wasm_module(ext, module, method, data) + }) + } + + fn version(&self) -> Option { + self.version.clone() + } +} + +pub fn create_instance(ext: &mut E, code: &[u8], heap_pages: u64) + -> Result +{ + let module = Module::from_buffer(&code).map_err(|_| WasmError::InvalidModule)?; + + // Extract the data segments from the wasm code. + // + // 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)?; + + // Instantiate this module. + let instance = instantiate_module(heap_pages as usize, &module) + .map_err(WasmError::Instantiation)?; + + // Take state snapshot before executing anything. + 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; + qed + ", + ); + + let version = call_in_wasm_module(ext, &instance, "Core_version", &[]) + .ok() + .and_then(|v| RuntimeVersion::decode(&mut v.as_slice()).ok()); + Ok(WasmiRuntime { + instance, + version, + state_snapshot, + }) +} + +/// 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]) -> Result, WasmError> { + let raw_module: RawModule = deserialize_buffer(wasm_code) + .map_err(|_| WasmError::CantDeserializeWasm)?; + + let segments = raw_module + .data_section() + .map(|ds| ds.entries()) + .unwrap_or(&[]) + .to_vec(); + Ok(segments) +} + +#[cfg(test)] +mod tests { + use super::*; + + use state_machine::TestExternalities as CoreTestExternalities; + use hex_literal::hex; + use primitives::{ + Blake2Hasher, blake2_128, blake2_256, ed25519, sr25519, map, Pair, offchain::OffchainExt, + }; + use runtime_test::WASM_BINARY; + use substrate_offchain::testing; + use trie::{TrieConfiguration, trie_types::Layout}; + use codec::{Encode, Decode}; + + type TestExternalities = CoreTestExternalities; + + fn call( + ext: &mut E, + heap_pages: u64, + code: &[u8], + method: &str, + data: &[u8], + ) -> Result, Error> { + let mut instance = create_instance(ext, code, heap_pages) + .map_err(|err| err.to_string())?; + instance.call(ext, method, data) + } + + #[test] + fn returning_should_work() { + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + let test_code = WASM_BINARY; + + let output = call(&mut ext, 8, &test_code[..], "test_empty_return", &[]).unwrap(); + assert_eq!(output, vec![0u8; 0]); + } + + #[test] + fn panicking_should_work() { + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + let test_code = WASM_BINARY; + + let output = call(&mut ext, 8, &test_code[..], "test_panic", &[]); + assert!(output.is_err()); + + let output = call(&mut ext, 8, &test_code[..], "test_conditional_panic", &[0]); + assert_eq!(Decode::decode(&mut &output.unwrap()[..]), Ok(Vec::::new())); + + let output = call(&mut ext, 8, &test_code[..], "test_conditional_panic", &vec![2].encode()); + assert!(output.is_err()); + } + + #[test] + fn storage_should_work() { + let mut ext = TestExternalities::default(); + + { + let mut ext = ext.ext(); + ext.set_storage(b"foo".to_vec(), b"bar".to_vec()); + let test_code = WASM_BINARY; + + let output = call( + &mut ext, + 8, + &test_code[..], + "test_data_in", + &b"Hello world".to_vec().encode(), + ).unwrap(); + + assert_eq!(output, b"all ok!".to_vec().encode()); + } + + let expected = TestExternalities::new((map![ + b"input".to_vec() => b"Hello world".to_vec(), + b"foo".to_vec() => b"bar".to_vec(), + b"baz".to_vec() => b"bar".to_vec() + ], map![])); + assert_eq!(ext, expected); + } + + #[test] + fn clear_prefix_should_work() { + let mut ext = TestExternalities::default(); + { + let mut ext = ext.ext(); + ext.set_storage(b"aaa".to_vec(), b"1".to_vec()); + ext.set_storage(b"aab".to_vec(), b"2".to_vec()); + ext.set_storage(b"aba".to_vec(), b"3".to_vec()); + ext.set_storage(b"abb".to_vec(), b"4".to_vec()); + ext.set_storage(b"bbb".to_vec(), b"5".to_vec()); + let test_code = WASM_BINARY; + + // This will clear all entries which prefix is "ab". + let output = call( + &mut ext, + 8, + &test_code[..], + "test_clear_prefix", + &b"ab".to_vec().encode(), + ).unwrap(); + + assert_eq!(output, b"all ok!".to_vec().encode()); + } + + let expected = TestExternalities::new((map![ + b"aaa".to_vec() => b"1".to_vec(), + b"aab".to_vec() => b"2".to_vec(), + b"bbb".to_vec() => b"5".to_vec() + ], map![])); + assert_eq!(expected, ext); + } + + #[test] + fn blake2_256_should_work() { + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + let test_code = WASM_BINARY; + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_blake2_256", &[0]).unwrap(), + blake2_256(&b""[..]).to_vec().encode(), + ); + assert_eq!( + call( + &mut ext, + 8, + &test_code[..], + "test_blake2_256", + &b"Hello world!".to_vec().encode(), + ).unwrap(), + blake2_256(&b"Hello world!"[..]).to_vec().encode(), + ); + } + + #[test] + fn blake2_128_should_work() { + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + let test_code = WASM_BINARY; + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_blake2_128", &[0]).unwrap(), + blake2_128(&b""[..]).to_vec().encode(), + ); + assert_eq!( + call( + &mut ext, + 8, + &test_code[..], + "test_blake2_128", + &b"Hello world!".to_vec().encode(), + ).unwrap(), + blake2_128(&b"Hello world!"[..]).to_vec().encode(), + ); + } + + #[test] + fn twox_256_should_work() { + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + let test_code = WASM_BINARY; + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_twox_256", &[0]).unwrap(), + hex!( + "99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a" + ).to_vec().encode(), + ); + assert_eq!( + call( + &mut ext, + 8, + &test_code[..], + "test_twox_256", + &b"Hello world!".to_vec().encode(), + ).unwrap(), + hex!( + "b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74" + ).to_vec().encode(), + ); + } + + #[test] + fn twox_128_should_work() { + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + let test_code = WASM_BINARY; + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_twox_128", &[0]).unwrap(), + hex!("99e9d85137db46ef4bbea33613baafd5").to_vec().encode(), + ); + assert_eq!( + call( + &mut ext, + 8, + &test_code[..], + "test_twox_128", + &b"Hello world!".to_vec().encode(), + ).unwrap(), + hex!("b27dfd7f223f177f2a13647b533599af").to_vec().encode(), + ); + } + + #[test] + fn ed25519_verify_should_work() { + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + let test_code = WASM_BINARY; + let key = ed25519::Pair::from_seed(&blake2_256(b"test")); + let sig = key.sign(b"all ok!"); + let mut calldata = vec![]; + calldata.extend_from_slice(key.public().as_ref()); + calldata.extend_from_slice(sig.as_ref()); + + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata.encode()).unwrap(), + true.encode(), + ); + + let other_sig = key.sign(b"all is not ok!"); + let mut calldata = vec![]; + calldata.extend_from_slice(key.public().as_ref()); + calldata.extend_from_slice(other_sig.as_ref()); + + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata.encode()).unwrap(), + false.encode(), + ); + } + + #[test] + fn sr25519_verify_should_work() { + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + let test_code = WASM_BINARY; + let key = sr25519::Pair::from_seed(&blake2_256(b"test")); + let sig = key.sign(b"all ok!"); + let mut calldata = vec![]; + calldata.extend_from_slice(key.public().as_ref()); + calldata.extend_from_slice(sig.as_ref()); + + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_sr25519_verify", &calldata.encode()).unwrap(), + true.encode(), + ); + + let other_sig = key.sign(b"all is not ok!"); + let mut calldata = vec![]; + calldata.extend_from_slice(key.public().as_ref()); + calldata.extend_from_slice(other_sig.as_ref()); + + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_sr25519_verify", &calldata.encode()).unwrap(), + false.encode(), + ); + } + + #[test] + fn ordered_trie_root_should_work() { + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + let trie_input = vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]; + let test_code = WASM_BINARY; + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_ordered_trie_root", &[0]).unwrap(), + Layout::::ordered_trie_root(trie_input.iter()).as_bytes().encode(), + ); + } + + #[test] + fn offchain_local_storage_should_work() { + use substrate_client::backend::OffchainStorage; + + let mut ext = TestExternalities::default(); + let (offchain, state) = testing::TestOffchainExt::new(); + ext.register_extension(OffchainExt::new(offchain)); + let test_code = WASM_BINARY; + let mut ext = ext.ext(); + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_offchain_local_storage", &[0]).unwrap(), + true.encode(), + ); + assert_eq!(state.read().persistent_storage.get(b"", b"test"), Some(vec![])); + } + + #[test] + fn offchain_http_should_work() { + let mut ext = TestExternalities::default(); + let (offchain, state) = testing::TestOffchainExt::new(); + ext.register_extension(OffchainExt::new(offchain)); + state.write().expect_request( + 0, + testing::PendingRequest { + method: "POST".into(), + uri: "http://localhost:12345".into(), + body: vec![1, 2, 3, 4], + headers: vec![("X-Auth".to_owned(), "test".to_owned())], + sent: true, + response: Some(vec![1, 2, 3]), + response_headers: vec![("X-Auth".to_owned(), "hello".to_owned())], + ..Default::default() + }, + ); + + let test_code = WASM_BINARY; + let mut ext = ext.ext(); + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_offchain_http", &[0]).unwrap(), + true.encode(), + ); + } +} diff --git a/core/externalities/Cargo.toml b/core/externalities/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..97ece5439ac998301755e17ec322092f0037782b --- /dev/null +++ b/core/externalities/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "substrate-externalities" +version = "2.0.0" +license = "GPL-3.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +primitive-types = { version = "0.5.1", features = ["codec"] } +primitives-storage = { package = "substrate-primitives-storage", path = "../primitives/storage" } +rstd = { package = "sr-std", path = "../sr-std" } +environmental = { version = "1.0.2" } diff --git a/core/externalities/src/extensions.rs b/core/externalities/src/extensions.rs new file mode 100644 index 0000000000000000000000000000000000000000..c7d7bc48538ac645b9b6cf26858355906124f29f --- /dev/null +++ b/core/externalities/src/extensions.rs @@ -0,0 +1,127 @@ +// 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 . + +//! Externalities extensions storage. +//! +//! Externalities support to register a wide variety custom extensions. The [`Extensions`] provides +//! some convenience functionality to store and retrieve these extensions. +//! +//! It is required that each extension implements the [`Extension`] trait. + +use std::{collections::HashMap, any::{Any, TypeId}, ops::DerefMut}; + +/// Marker trait for types that should be registered as [`Externalities`](crate::Externalities) extension. +/// +/// As extensions are stored as `Box`, this trait should give more confidence that the correct +/// type is registered and requested. +pub trait Extension: Sized {} + +/// Macro for declaring an extension that usable with [`Extensions`]. +/// +/// The extension will be an unit wrapper struct that implements [`Extension`], `Deref` and +/// `DerefMut`. The wrapped type is given by the user. +/// +/// # Example +/// ``` +/// # use substrate_externalities::decl_extension; +/// decl_extension! { +/// /// Some test extension +/// struct TestExt(String); +/// } +/// ``` +#[macro_export] +macro_rules! decl_extension { + ( + $( #[ $attr:meta ] )* + $vis:vis struct $ext_name:ident ($inner:ty); + ) => { + $( #[ $attr ] )* + $vis struct $ext_name (pub $inner); + + impl $crate::Extension for $ext_name {} + + impl std::ops::Deref for $ext_name { + type Target = $inner; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl std::ops::DerefMut for $ext_name { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + } +} + +/// Something that provides access to the [`Extensions`] store. +/// +/// This is a super trait of the [`Externalities`](crate::Externalities). +pub trait ExtensionStore { + /// Tries to find a registered extension by the given `type_id` and returns it as a `&mut dyn Any`. + /// + /// It is advised to use [`ExternalitiesExt::extension`](crate::ExternalitiesExt::extension) + /// instead of this function to get type system support and automatic type downcasting. + fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any>; +} + +/// Stores extensions that should be made available through the externalities. +#[derive(Default)] +pub struct Extensions { + extensions: HashMap>, +} + +impl Extensions { + /// Create new instance of `Self`. + pub fn new() -> Self { + Self::default() + } + + /// Register the given extension. + pub fn register(&mut self, ext: E) { + self.extensions.insert(ext.type_id(), Box::new(ext)); + } + + /// Return a mutable reference to the requested extension. + pub fn get_mut(&mut self, ext_type_id: TypeId) -> Option<&mut dyn Any> { + self.extensions.get_mut(&ext_type_id).map(DerefMut::deref_mut) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + struct DummyExt(u32); + impl Extension for DummyExt {} + + struct DummyExt2(u32); + impl Extension for DummyExt2 {} + + #[test] + fn register_and_retrieve_extension() { + let mut exts = Extensions::new(); + exts.register(DummyExt(1)); + exts.register(DummyExt2(2)); + + let ext = exts.get_mut(TypeId::of::()).expect("Extension is registered"); + let ext_ty = ext.downcast_mut::().expect("Downcasting works"); + + assert_eq!(ext_ty.0, 1); + } +} diff --git a/core/externalities/src/lib.rs b/core/externalities/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..ecd5f7a7a751da68d9b069ab749c2c96edec7ae0 --- /dev/null +++ b/core/externalities/src/lib.rs @@ -0,0 +1,139 @@ +// 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 externalities abstraction +//! +//! The externalities mainly provide access to storage and to registered extensions. Extensions +//! are for example the keystore or the offchain externalities. These externalities are used to +//! access the node from the runtime via the runtime interfaces. +//! +//! This crate exposes the main [`Externalities`] trait. + +use primitive_types::H256; + +use std::any::{Any, TypeId}; + +use primitives_storage::ChildStorageKey; + +pub use scope_limited::{set_and_run_with_externalities, with_externalities}; +pub use extensions::{Extension, Extensions, ExtensionStore}; + +mod extensions; +mod scope_limited; + +/// The Substrate externalities. +/// +/// Provides access to the storage and to other registered extensions. +pub trait Externalities: ExtensionStore { + /// 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; + + /// Get child storage value hash. This may be optimized for large values. + fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option; + + /// 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; + + /// 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; + + /// 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) -> H256; + + /// 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: H256) -> Result, ()>; +} + +/// Extension for the [`Externalities`] trait. +pub trait ExternalitiesExt { + /// Tries to find a registered extension and returns a mutable reference. + fn extension(&mut self) -> Option<&mut T>; +} + +impl ExternalitiesExt for T { + fn extension(&mut self) -> Option<&mut A> { + self.extension_by_type_id(TypeId::of::()).and_then(Any::downcast_mut) + } +} diff --git a/core/externalities/src/scope_limited.rs b/core/externalities/src/scope_limited.rs new file mode 100644 index 0000000000000000000000000000000000000000..ae185449be2b0cf2573872787ba4ce3f916fa28b --- /dev/null +++ b/core/externalities/src/scope_limited.rs @@ -0,0 +1,37 @@ +// 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 . + +//! Stores the externalities in an `environmental` value to make it scope limited available. + +use crate::Externalities; + +environmental::environmental!(ext: trait Externalities); + +/// Set the given externalities while executing the given closure. To get access to the externalities +/// while executing the given closure [`with_externalities`] grants access to them. The externalities +/// are only set for the same thread this function was called from. +pub fn set_and_run_with_externalities(ext: &mut dyn Externalities, f: F) -> R + where F: FnOnce() -> R +{ + ext::using(ext, f) +} + +/// Execute the given closure with the currently set externalities. +/// +/// Returns `None` if no externalities are set or `Some(_)` with the result of the closure. +pub fn with_externalities R, R>(f: F) -> Option { + ext::with(f) +} diff --git a/core/finality-grandpa/Cargo.toml b/core/finality-grandpa/Cargo.toml index 22237c5a0b5a0f886fe2853604270627b272cf79..84178c8a78fd55499a4866b68c1e4613b225b130 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.41" 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.7.0" +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..27139bbeeffa8366e1313f1b40ff8e0cfaafae7d 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, RuntimeDebug}; use client::decl_runtime_apis; use rstd::vec::Vec; @@ -52,9 +52,15 @@ pub type AuthorityWeight = u64; /// The index of an authority. pub type AuthorityIndex = u64; +/// The monotonic identifier of a GRANDPA set of authorities. +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)] +#[cfg_attr(feature = "std", derive(Serialize))] +#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] pub struct ScheduledChange { /// The new authorities after the change, along with their respective weights. pub next_authorities: Vec<(AuthorityId, AuthorityWeight)>, @@ -63,13 +69,14 @@ pub struct ScheduledChange { } /// An consensus log item for GRANDPA. -#[cfg_attr(feature = "std", derive(Serialize, Debug))] -#[derive(Decode, Encode, PartialEq, Eq, Clone)] +#[cfg_attr(feature = "std", derive(Serialize))] +#[derive(Decode, Encode, PartialEq, Eq, Clone, RuntimeDebug)] 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 5fd09620e925b87070b74560bdbecac7fb9970c2..24402c8a02d3e6ae989ff31af882a425c9458023 100644 --- a/core/finality-grandpa/src/communication/gossip.rs +++ b/core/finality-grandpa/src/communication/gossip.rs @@ -132,7 +132,7 @@ struct View { impl Default for View { fn default() -> Self { View { - round: Round(0), + round: Round(1), set_id: SetId(0), last_commit: None, } @@ -144,7 +144,7 @@ impl View { fn update_set(&mut self, set_id: SetId) { if set_id != self.set_id { self.set_id = set_id; - self.round = Round(0); + self.round = Round(1); } } @@ -183,7 +183,13 @@ impl View { const KEEP_RECENT_ROUNDS: usize = 3; -/// Tracks topics we keep messages for. +/// Tracks gossip topics that we are keeping messages for. We keep topics of: +/// +/// - the last `KEEP_RECENT_ROUNDS` complete GRANDPA rounds, +/// +/// - the topic for the current and next round, +/// +/// - and a global topic for commit and catch-up messages. struct KeepTopics { current_set: SetId, rounds: VecDeque<(Round, SetId)>, @@ -194,21 +200,30 @@ impl KeepTopics { fn new() -> Self { KeepTopics { current_set: SetId(0), - rounds: VecDeque::with_capacity(KEEP_RECENT_ROUNDS + 1), + rounds: VecDeque::with_capacity(KEEP_RECENT_ROUNDS + 2), reverse_map: HashMap::new(), } } fn push(&mut self, round: Round, set_id: SetId) { self.current_set = std::cmp::max(self.current_set, set_id); - self.rounds.push_back((round, set_id)); - // the 1 is for the current round. - while self.rounds.len() > KEEP_RECENT_ROUNDS + 1 { + // under normal operation the given round is already tracked (since we + // track one round ahead). if we skip rounds (with a catch up) the given + // round topic might not be tracked yet. + if !self.rounds.contains(&(round, set_id)) { + self.rounds.push_back((round, set_id)); + } + + // we also accept messages for the next round + self.rounds.push_back((Round(round.0.saturating_add(1)), set_id)); + + // the 2 is for the current and next round. + while self.rounds.len() > KEEP_RECENT_ROUNDS + 2 { let _ = self.rounds.pop_front(); } - let mut map = HashMap::with_capacity(KEEP_RECENT_ROUNDS + 2); + let mut map = HashMap::with_capacity(KEEP_RECENT_ROUNDS + 3); map.insert(super::global_topic::(self.current_set.0), (None, self.current_set)); for &(round, set) in &self.rounds { @@ -247,7 +262,7 @@ fn neighbor_topics(view: &View>) -> Vec { #[derive(Debug, Encode, Decode)] pub(super) enum GossipMessage { /// Grandpa message with round and set info. - VoteOrPrecommit(VoteOrPrecommitMessage), + Vote(VoteMessage), /// Grandpa commit message with round and set info. Commit(FullCommitMessage), /// A neighbor packet. Not repropagated. @@ -264,9 +279,9 @@ impl From>> for GossipMessage { +pub(super) struct VoteMessage { /// The round this message is from. pub(super) round: Round, /// The voter set ID this message is from. @@ -386,12 +401,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 +425,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 +520,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 +534,7 @@ impl Inner { next_rebroadcast: Instant::now() + REBROADCAST_AFTER, authorities: Vec::new(), pending_catch_up: PendingCatchUp::None, + catch_up_enabled, config, } } @@ -550,7 +569,7 @@ impl Inner { { let local_view = match self.local_view { ref mut x @ None => x.get_or_insert(View { - round: Round(0), + round: Round(1), set_id, last_commit: None, }), @@ -562,7 +581,7 @@ impl Inner { }; local_view.update_set(set_id); - self.live_topics.push(Round(0), set_id); + self.live_topics.push(Round(1), set_id); self.authorities = authorities; } self.multicast_neighbor_packet() @@ -599,7 +618,7 @@ impl Inner { cost::PAST_REJECTION } - fn validate_round_message(&self, who: &PeerId, full: &VoteOrPrecommitMessage) + fn validate_round_message(&self, who: &PeerId, full: &VoteMessage) -> Action { match self.consider_vote(full.round, full.set_id) { @@ -804,14 +823,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 @@ -917,13 +943,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, }; @@ -979,7 +1009,7 @@ impl GossipValidator { let action = { match GossipMessage::::decode(&mut data) { - Ok(GossipMessage::VoteOrPrecommit(ref message)) + Ok(GossipMessage::Vote(ref message)) => self.inner.write().validate_round_message(who, message), Ok(GossipMessage::Commit(ref message)) => self.inner.write().validate_commit_message(who, message), Ok(GossipMessage::Neighbor(update)) => { @@ -1023,10 +1053,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 { @@ -1139,7 +1169,7 @@ impl network_gossip::Validator for GossipValidator Ok(GossipMessage::Neighbor(_)) => false, Ok(GossipMessage::CatchUpRequest(_)) => false, Ok(GossipMessage::CatchUp(_)) => false, - Ok(GossipMessage::VoteOrPrecommit(_)) => false, // should not be the case. + Ok(GossipMessage::Vote(_)) => false, // should not be the case. } }) } @@ -1314,7 +1344,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()); @@ -1350,7 +1380,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(); @@ -1370,7 +1400,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), @@ -1408,6 +1438,7 @@ mod tests { let (val, _) = GossipValidator::::new( config(), voter_set_state(), + true, ); let set_id = 1; @@ -1443,17 +1474,18 @@ mod tests { let (val, _) = GossipValidator::::new( config(), voter_set_state(), + true, ); let set_id = 1; let auth = AuthorityId::from_slice(&[1u8; 32]); let peer = PeerId::random(); val.note_set(SetId(set_id), vec![auth.clone()], |_, _| {}); - val.note_round(Round(0), |_, _| {}); + val.note_round(Round(1), |_, _| {}); let inner = val.inner.read(); - let unknown_voter = inner.validate_round_message(&peer, &VoteOrPrecommitMessage { - round: Round(0), + let unknown_voter = inner.validate_round_message(&peer, &VoteMessage { + round: Round(1), set_id: SetId(set_id), message: SignedMessage:: { message: grandpa::Message::Prevote(grandpa::Prevote { @@ -1465,8 +1497,8 @@ mod tests { } }); - let bad_sig = inner.validate_round_message(&peer, &VoteOrPrecommitMessage { - round: Round(0), + let bad_sig = inner.validate_round_message(&peer, &VoteMessage { + round: Round(1), set_id: SetId(set_id), message: SignedMessage:: { message: grandpa::Message::Prevote(grandpa::Prevote { @@ -1487,6 +1519,7 @@ mod tests { let (val, _) = GossipValidator::::new( config(), voter_set_state(), + true, ); let set_id = 1; @@ -1494,7 +1527,7 @@ mod tests { let peer = PeerId::random(); val.note_set(SetId(set_id), vec![auth.clone()], |_, _| {}); - val.note_round(Round(0), |_, _| {}); + val.note_round(Round(1), |_, _| {}); let validate_catch_up = || { let mut inner = val.inner.write(); @@ -1530,19 +1563,19 @@ mod tests { #[test] fn unanswerable_catch_up_requests_discarded() { - // create voter set state with round 1 completed + // create voter set state with round 2 completed let set_state: SharedVoterSetState = { let mut completed_rounds = voter_set_state().read().completed_rounds(); completed_rounds.push(environment::CompletedRound { - number: 1, + number: 2, state: grandpa::round::State::genesis(Default::default()), base: Default::default(), votes: Default::default(), }); let mut current_rounds = environment::CurrentRounds::new(); - current_rounds.insert(2, environment::HasVoted::No); + current_rounds.insert(3, environment::HasVoted::No); let set_state = environment::VoterSetState::::Live { completed_rounds, @@ -1555,6 +1588,7 @@ mod tests { let (val, _) = GossipValidator::::new( config(), set_state.clone(), + true, ); let set_id = 1; @@ -1562,12 +1596,12 @@ mod tests { let peer = PeerId::random(); val.note_set(SetId(set_id), vec![auth.clone()], |_, _| {}); - val.note_round(Round(2), |_, _| {}); + val.note_round(Round(3), |_, _| {}); // 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, @@ -1578,7 +1612,7 @@ mod tests { &set_state, ); - // we're at round 2, a catch up request for round 10 is out of scope + // we're at round 3, a catch up request for round 10 is out of scope assert!(res.0.is_none()); assert_eq!(res.1, Action::Discard(cost::OUT_OF_SCOPE_MESSAGE)); @@ -1586,16 +1620,16 @@ mod tests { &peer, CatchUpRequestMessage { set_id: SetId(set_id), - round: Round(1), + round: Round(2), }, &set_state, ); - // a catch up request for round 1 should be answered successfully + // a catch up request for round 2 should be answered successfully match res.0.unwrap() { GossipMessage::CatchUp(catch_up) => { assert_eq!(catch_up.set_id, SetId(set_id)); - assert_eq!(catch_up.message.round_number, 1); + assert_eq!(catch_up.message.round_number, 2); assert_eq!(res.1, Action::Discard(cost::CATCH_UP_REPLY)); }, @@ -1609,6 +1643,7 @@ mod tests { let (val, _) = GossipValidator::::new( config(), set_state.clone(), + true, ); // the validator starts at set id 2 @@ -1617,7 +1652,7 @@ mod tests { // 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()); + val.inner.write().peers.new_peer(peer.clone(), Roles::AUTHORITY); let send_request = |set_id, round| { let mut inner = val.inner.write(); @@ -1682,4 +1717,181 @@ mod tests { 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"), + } + } + + #[test] + fn doesnt_expire_next_round_messages() { + // NOTE: this is a regression test + let (val, _) = GossipValidator::::new( + config(), + voter_set_state(), + true, + ); + + // the validator starts at set id 1. + val.note_set(SetId(1), Vec::new(), |_, _| {}); + + // we are at round 10 + val.note_round(Round(9), |_, _| {}); + val.note_round(Round(10), |_, _| {}); + + let mut is_expired = val.message_expired(); + + // we accept messages from rounds 9, 10 and 11 + // therefore neither of those should be considered expired + for round in &[9, 10, 11] { + assert!( + !is_expired( + crate::communication::round_topic::(*round, 1), + &[], + ) + ) + } + } } diff --git a/core/finality-grandpa/src/communication/mod.rs b/core/finality-grandpa/src/communication/mod.rs index 2aa2618535948821e99984b9934c17b79a46f95e..6f43b1106a54e8aaf161f32f008131966b0bdb7f 100644 --- a/core/finality-grandpa/src/communication/mod.rs +++ b/core/finality-grandpa/src/communication/mod.rs @@ -31,6 +31,7 @@ use std::sync::Arc; use futures::prelude::*; use futures::sync::{oneshot, mpsc}; +use futures03::stream::{StreamExt, TryStreamExt}; use grandpa::Message::{Prevote, Precommit, PrimaryPropose}; use grandpa::{voter, voter_set::VoterSet}; use log::{debug, trace}; @@ -38,7 +39,7 @@ use network::{consensus_gossip as network_gossip, NetworkService}; use network_gossip::ConsensusMessage; use codec::{Encode, Decode}; use primitives::Pair; -use sr_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT}; +use sr_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, NumberFor}; use substrate_telemetry::{telemetry, CONSENSUS_DEBUG, CONSENSUS_INFO}; use tokio_executor::Executor; @@ -48,9 +49,11 @@ use crate::{ }; use crate::environment::HasVoted; use gossip::{ - GossipMessage, FullCatchUpMessage, FullCommitMessage, VoteOrPrecommitMessage, GossipValidator + GossipMessage, FullCatchUpMessage, FullCommitMessage, VoteMessage, GossipValidator +}; +use fg_primitives::{ + AuthorityPair, AuthorityId, AuthoritySignature, SetId as SetIdNumber, RoundNumber, }; -use fg_primitives::{AuthorityPair, AuthorityId, AuthoritySignature}; pub mod gossip; mod periodic; @@ -98,7 +101,7 @@ mod benefit { /// Intended to be a lightweight handle such as an `Arc`. pub trait Network: Clone + Send + 'static { /// A stream of input messages for a topic. - type In: Stream; + type In: Stream; /// Get a stream of messages for a specific gossip topic. fn messages_for(&self, topic: Block::Hash) -> Self::In; @@ -125,16 +128,24 @@ 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); + + /// Notifies the sync service to try and sync the given block from the given + /// peers. + /// + /// If the given vector of peers is empty then the underlying implementation + /// should make a best effort to fetch the block from any peers it is + /// connected to (NOTE: this assumption will change in the future #3629). + fn set_sync_fork_request(&self, peers: Vec, hash: Block::Hash, number: NumberFor); } /// 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()) } @@ -143,15 +154,30 @@ impl Network for Arc> where S: network::specialization::NetworkSpecialization, H: network::ExHashT, { - type In = NetworkStream; + type In = NetworkStream< + Box + Send + 'static>, + >; fn messages_for(&self, topic: B::Hash) -> Self::In { + // Given that one can only communicate with the Substrate network via the `NetworkService` via message-passing, + // and given that methods on the network consensus gossip are not exposed but only reachable by passing a + // closure into `with_gossip` on the `NetworkService` this function needs to make use of the `NetworkStream` + // construction. + // + // We create a oneshot channel and pass the sender within a closure to the network. At some point in the future + // the network passes the message channel back through the oneshot channel. But the consumer of this function + // expects a stream, not a stream within a oneshot. This complexity is abstracted within `NetworkStream`, + // waiting for the oneshot to resolve and from there on acting like a normal message channel. let (tx, rx) = oneshot::channel(); self.with_gossip(move |gossip, _| { - let inner_rx = gossip.messages_for(GRANDPA_ENGINE_ID, topic); + let inner_rx: Box + Send> = Box::new(gossip + .messages_for(GRANDPA_ENGINE_ID, topic) + .map(|x| Ok(x)) + .compat() + ); let _ = tx.send(inner_rx); }); - NetworkStream { outer: rx, inner: None } + NetworkStream::PollingOneshot(rx) } fn register_validator(&self, validator: Arc>) { @@ -195,33 +221,52 @@ 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) + } + + fn set_sync_fork_request(&self, peers: Vec, hash: B::Hash, number: NumberFor) { + NetworkService::set_sync_fork_request(self, peers, hash, number) } } -/// A stream used by NetworkBridge in its implementation of Network. -pub struct NetworkStream { - inner: Option>, - outer: oneshot::Receiver> +/// A stream used by NetworkBridge in its implementation of Network. Given a oneshot that eventually returns a channel +/// which eventually returns messages, instead of: +/// +/// 1. polling the oneshot until it returns a message channel +/// +/// 2. polling the message channel for messages +/// +/// `NetworkStream` combines the two steps into one, requiring a consumer to only poll `NetworkStream` to retrieve +/// messages directly. +pub enum NetworkStream { + PollingOneshot(oneshot::Receiver), + PollingTopicNotifications(R), } -impl Stream for NetworkStream { - type Item = network_gossip::TopicNotification; +impl Stream for NetworkStream +where + R: Stream, +{ + type Item = R::Item; type Error = (); fn poll(&mut self) -> Poll, Self::Error> { - if let Some(ref mut inner) = self.inner { - return inner.poll(); - } - match self.outer.poll() { - Ok(futures::Async::Ready(mut inner)) => { - let poll_result = inner.poll(); - self.inner = Some(inner); - poll_result + match self { + NetworkStream::PollingOneshot(oneshot) => { + match oneshot.poll() { + Ok(futures::Async::Ready(mut stream)) => { + let poll_result = stream.poll(); + *self = NetworkStream::PollingTopicNotifications(stream); + poll_result + }, + Ok(futures::Async::NotReady) => Ok(futures::Async::NotReady), + Err(_) => Err(()) + } + }, + NetworkStream::PollingTopicNotifications(stream) => { + stream.poll() }, - Ok(futures::Async::NotReady) => Ok(futures::Async::NotReady), - Err(_) => Err(()) } } } @@ -231,24 +276,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, + on_exit: impl Future + Clone + Send + 'static, + catch_up_enabled: bool, ) -> ( Self, - impl futures::Future + Send + 'static, + impl 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()); @@ -266,8 +318,8 @@ impl> NetworkBridge { validator.note_round(Round(round.number), |_, _| {}); for signed in round.votes.iter() { - let message = gossip::GossipMessage::VoteOrPrecommit( - gossip::VoteOrPrecommitMessage:: { + let message = gossip::GossipMessage::Vote( + gossip::VoteMessage:: { message: signed.clone(), round: Round(round.number), set_id: SetId(set_id), @@ -291,9 +343,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 +354,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,22 +375,17 @@ 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), ); } - /// Get the round messages for a round in the current set ID. These are signature-checked. + /// Get a stream of signature-checked round messages from the network as well as a sink for round messages to the + /// network all within the current set. pub(crate) fn round_communication( &self, round: Round, @@ -373,7 +423,7 @@ impl> NetworkBridge { }) .and_then(move |msg| { match msg { - GossipMessage::VoteOrPrecommit(msg) => { + GossipMessage::Vote(msg) => { // check signature. if !voters.contains_key(&msg.message.id) { debug!(target: "afg", "Skipping message from unknown voter {}", msg.message.id); @@ -422,6 +472,7 @@ impl> NetworkBridge { network: self.service.clone(), locals, sender: tx, + announce_sender: self.announce_sender.clone(), has_voted, }; @@ -429,6 +480,9 @@ impl> NetworkBridge { format!("Failed to receive on unbounded receiver for round {}", round.0) )); + // Combine incoming votes from external GRANDPA nodes with outgoing + // votes from our own GRANDPA voter to have a single + // vote-import-pipeline. let incoming = incoming.select(out_rx); (incoming, outgoing) @@ -447,18 +501,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| { @@ -468,6 +529,16 @@ impl> NetworkBridge { (incoming, outgoing) } + + /// Notifies the sync service to try and sync the given block from the given + /// peers. + /// + /// If the given vector of peers is empty then the underlying implementation + /// should make a best effort to fetch the block from any peers it is + /// connected to (NOTE: this assumption will change in the future #3629). + pub(crate) fn set_sync_fork_request(&self, peers: Vec, hash: B::Hash, number: NumberFor) { + self.service.set_sync_fork_request(peers, hash, number) + } } fn incoming_global>( @@ -475,6 +546,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 +584,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 +592,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 +678,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 +721,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, } @@ -692,7 +764,7 @@ impl> Sink for OutgoingMessages id: local_id.clone(), }; - let message = GossipMessage::VoteOrPrecommit(VoteOrPrecommitMessage:: { + let message = GossipMessage::Vote(VoteMessage:: { message: signed.clone(), round: Round(self.round), set_id: SetId(self.set_id), @@ -711,10 +783,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 +917,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 +979,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 +1039,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..7b91b2ef0a95e29a098671063aeadd87c418814b 100644 --- a/core/finality-grandpa/src/communication/tests.rs +++ b/core/finality-grandpa/src/communication/tests.rs @@ -25,6 +25,7 @@ use tokio::runtime::current_thread; use std::sync::Arc; use keyring::Ed25519Keyring; use codec::Encode; +use sr_primitives::traits::NumberFor; use crate::environment::SharedVoterSetState; use super::gossip::{self, GossipValidator}; @@ -88,9 +89,12 @@ 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)); } + + /// Notify the sync service to try syncing the given chain. + fn set_sync_fork_request(&self, _peers: Vec, _hash: Hash, _number: NumberFor) {} } impl network_gossip::ValidatorContext for TestNetwork { @@ -182,6 +186,7 @@ fn make_test_network() -> ( config(), voter_set_state(), Exit, + true, ); ( @@ -216,7 +221,7 @@ fn good_commit_leads_to_relay() { let public = make_ids(&private[..]); let voter_set = Arc::new(public.iter().cloned().collect::>()); - let round = 0; + let round = 1; let set_id = 1; let commit = { @@ -331,7 +336,7 @@ fn bad_commit_leads_to_report() { let public = make_ids(&private[..]); let voter_set = Arc::new(public.iter().cloned().collect::>()); - let round = 0; + let round = 1; let set_id = 1; let commit = { @@ -447,8 +452,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 +502,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 b20e8ab5dfcbb99f3154c4e7106a7e07e60e0fd6..149b00e80f92033ff73cafc90567113cd1d7e4a5 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,8 @@ 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 crate::voting_rule::VotingRule; +use fg_primitives::{AuthorityId, AuthoritySignature, SetId, RoundNumber}; type HistoricalVotes = grandpa::HistoricalVotes< ::Hash, @@ -65,7 +67,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 +82,7 @@ pub struct CompletedRound { #[derive(Debug, Clone, PartialEq)] pub struct CompletedRounds { rounds: Vec>, - set_id: u64, + set_id: SetId, voters: Vec, } @@ -100,7 +102,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 +115,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 +128,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 +164,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 +192,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 +239,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 +346,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 { @@ -367,19 +369,20 @@ impl SharedVoterSetState { } /// The environment we run GRANDPA in. -pub(crate) struct Environment, RA, SC> { - pub(crate) inner: Arc>, +pub(crate) struct Environment, RA, SC, VR> { + pub(crate) client: Arc>, pub(crate) select_chain: SC, pub(crate) voters: Arc>, pub(crate) config: Config, 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, + pub(crate) voting_rule: VR, } -impl, RA, SC> Environment { +impl, RA, SC, VR> Environment { /// Updates the voter set state using the given closure. The write lock is /// held during evaluation of the closure and the environment's voter set /// state is set to its result if successful. @@ -395,20 +398,22 @@ impl, RA, SC> Environment, B, E, N, RA, SC> +impl, B, E, N, RA, SC, VR> grandpa::Chain> -for Environment +for Environment where Block: 'static, B: Backend + 'static, - E: CallExecutor + 'static, + E: CallExecutor + Send + Sync + 'static, N: Network + 'static, N::In: 'static, SC: SelectChain + 'static, + VR: VotingRule>, + RA: Send + Sync, NumberFor: BlockNumberOps, { fn ancestry(&self, base: Block::Hash, block: Block::Hash) -> Result, GrandpaError> { - ancestry(&self.inner, base, block) + ancestry(&self.client, base, block) } fn best_chain_containing(&self, block: Block::Hash) -> Option<(Block::Hash, NumberFor)> { @@ -428,8 +433,8 @@ where debug!(target: "afg", "Finding best chain containing block {:?} with number limit {:?}", block, limit); match self.select_chain.finality_target(block, None) { - Ok(Some(mut best_hash)) => { - let base_header = self.inner.header(&BlockId::Hash(block)).ok()? + Ok(Some(best_hash)) => { + let base_header = self.client.header(&BlockId::Hash(block)).ok()? .expect("Header known to exist after `best_containing` call; qed"); if let Some(limit) = limit { @@ -444,35 +449,51 @@ where } } - let mut best_header = self.inner.header(&BlockId::Hash(best_hash)).ok()? + let best_header = self.client.header(&BlockId::Hash(best_hash)).ok()? .expect("Header known to exist after `best_containing` call; qed"); - // we target a vote towards 3/4 of the unfinalized chain (rounding up) - let target = { - let two = NumberFor::::one() + One::one(); - let three = two + One::one(); - let four = three + One::one(); - - let diff = *best_header.number() - *base_header.number(); - let diff = ((diff * three) + two) / four; + // check if our vote is currently being limited due to a pending change + let limit = limit.filter(|limit| limit < best_header.number()); + let target; + + let target_header = if let Some(target_number) = limit { + let mut target_header = best_header.clone(); + + // walk backwards until we find the target block + loop { + if *target_header.number() < target_number { + unreachable!( + "we are traversing backwards from a known block; \ + blocks are stored contiguously; \ + qed" + ); + } + + if *target_header.number() == target_number { + break; + } + + target_header = self.client.header(&BlockId::Hash(*target_header.parent_hash())).ok()? + .expect("Header known to exist after `best_containing` call; qed"); + } - *base_header.number() + diff + target = target_header; + &target + } else { + // otherwise just use the given best as the target + &best_header }; - // unless our vote is currently being limited due to a pending change - let target = limit.map(|limit| limit.min(target)).unwrap_or(target); - - // walk backwards until we find the target block - loop { - if *best_header.number() < target { unreachable!(); } - if *best_header.number() == target { - return Some((best_hash, *best_header.number())); - } - - best_hash = *best_header.parent_hash(); - best_header = self.inner.header(&BlockId::Hash(best_hash)).ok()? - .expect("Header known to exist after `best_containing` call; qed"); - } + // restrict vote according to the given voting rule, if the + // voting rule doesn't restrict the vote then we keep the + // previous target. + // + // note that we pass the original `best_header`, i.e. before the + // authority set limit filter, which can be considered a + // mandatory/implicit voting rule. + self.voting_rule + .restrict_vote(&*self.client, &base_header, &best_header, target_header) + .or(Some((target_header.hash(), *target_header.number()))) }, Ok(None) => { debug!(target: "afg", "Encountered error finding best chain containing {:?}: couldn't find target block", block); @@ -497,12 +518,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, @@ -523,9 +539,9 @@ pub(crate) fn ancestry, E, RA>( Ok(tree_route.retracted().iter().skip(1).map(|e| e.hash).collect()) } -impl, N, RA, SC> +impl, N, RA, SC, VR> voter::Environment> -for Environment +for Environment where Block: 'static, B: Backend + 'static, @@ -534,6 +550,7 @@ where N::In: 'static + Send, RA: 'static + Send + Sync, SC: SelectChain + 'static, + VR: VotingRule>, NumberFor: BlockNumberOps, { type Timer = Box + Send>; @@ -554,7 +571,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); @@ -584,9 +601,11 @@ where // schedule incoming messages from the network to be held until // corresponding blocks are imported. let incoming = Box::new(UntilVoteTargetImported::new( - self.inner.import_notification_stream(), - self.inner.clone(), + self.client.import_notification_stream(), + self.network.clone(), + self.client.clone(), incoming, + "round", ).map_err(Into::into)); // schedule network message cleanup when sink drops. @@ -601,7 +620,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 +651,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.client, &set_state)?; Ok(Some(set_state)) })?; @@ -641,7 +659,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 +692,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.client, &set_state)?; Ok(Some(set_state)) })?; @@ -683,7 +700,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 +743,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.client, &set_state)?; Ok(Some(set_state)) })?; @@ -737,7 +753,7 @@ where fn completed( &self, - round: u64, + round: RoundNumber, state: RoundState>, base: (Block::Hash, NumberFor), historical_votes: &HistoricalVotes, @@ -785,8 +801,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.client, &set_state)?; Ok(Some(set_state)) })?; @@ -794,9 +809,15 @@ where Ok(()) } - fn finalize_block(&self, hash: Block::Hash, number: NumberFor, round: u64, commit: Commit) -> Result<(), Self::Error> { + fn finalize_block( + &self, + hash: Block::Hash, + number: NumberFor, + round: RoundNumber, + commit: Commit, + ) -> Result<(), Self::Error> { finalize_block( - &*self.inner, + &*self.client, &self.authority_set, &self.consensus_changes, Some(self.config.justification_period.into()), @@ -818,7 +839,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); @@ -827,7 +848,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); @@ -837,11 +858,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) } } @@ -869,32 +890,25 @@ pub(crate) fn finalize_block, E, RA>( E: CallExecutor + Send + Sync, RA: Send + Sync, { - use client::blockchain::HeaderBackend; - - #[allow(deprecated)] - let blockchain = client.backend().blockchain(); - let info = blockchain.info(); - if number <= info.finalized_number && blockchain.hash(number)? == Some(hash) { - // We might have a race condition on finality, since we can finalize - // through either sync (import justification) or through grandpa gossip. - // so let's make sure that this finalization request is no longer stale. - // This can also 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, - info.finalized_number, + // 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(()); } - // lock must be held through writing to DB to avoid race - let mut authority_set = authority_set.inner().write(); - // 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 @@ -911,7 +925,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 @@ -923,7 +937,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 { @@ -1016,7 +1030,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 { @@ -1047,15 +1061,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); } @@ -1064,17 +1075,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), }; @@ -1083,7 +1094,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..da5732f2f6fc8e475a409759dffae678eee63a31 100644 --- a/core/finality-grandpa/src/finality_proof.rs +++ b/core/finality-grandpa/src/finality_proof.rs @@ -40,14 +40,13 @@ 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 substrate_telemetry::{telemetry, CONSENSUS_INFO}; @@ -79,7 +78,7 @@ impl, RA> AuthoritySetForFinalityProver fo "GrandpaApi_grandpa_authorities", &[], ExecutionStrategy::NativeElseWasm, - NeverOffchainExt::new(), + None, ).and_then(|call_result| Decode::decode(&mut &call_result[..]) .map_err(|err| ClientError::CallResultDecode( "failed to decode GRANDPA authorities set proof".into(), err @@ -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 7651f9a03d965b4b1299972a7108d05882ee9da0..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()), @@ -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 428fa1aeb82323fb5e64ef163cfcdf4a272e32c1..63eddfd3f33fb27b62da9cd81877d034958495b3 100644 --- a/core/finality-grandpa/src/lib.rs +++ b/core/finality-grandpa/src/lib.rs @@ -22,11 +22,11 @@ //! //! # Usage //! -//! First, create a block-import wrapper with the `block_import` function. -//! The GRANDPA worker needs to be linked together with this block import object, -//! so a `LinkHalf` is returned as well. All blocks imported (from network or consensus or otherwise) -//! must pass through this wrapper, otherwise consensus is likely to break in -//! unexpected ways. +//! First, create a block-import wrapper with the `block_import` function. The +//! GRANDPA worker needs to be linked together with this block import object, so +//! a `LinkHalf` is returned as well. All blocks imported (from network or +//! consensus or otherwise) must pass through this wrapper, otherwise consensus +//! is likely to break in unexpected ways. //! //! Next, use the `LinkHalf` and a local configuration to `run_grandpa_voter`. //! This requires a `Network` implementation. The returned future should be @@ -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; @@ -92,23 +92,22 @@ mod justification; mod light_import; mod observer; mod until_imported; +mod voting_rule; -#[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; +pub use voting_rule::{ + BeforeBestBlock, ThreeQuartersOfTheUnfinalizedChain, VotingRule, VotingRulesBuilder +}; use aux_schema::PersistentData; 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}; @@ -243,7 +242,7 @@ impl From for Error { } /// Something which can determine if a block is known. -pub trait BlockStatus { +pub(crate) trait BlockStatus { /// Return `Ok(Some(number))` or `Ok(None)` depending on whether the block /// is definitely known and has been imported. /// If an unexpected error occurs, return that. @@ -262,13 +261,33 @@ impl, RA> BlockStatus for Arc { + /// Notifies the sync service to try and sync the given block from the given + /// peers. + /// + /// If the given vector of peers is empty then the underlying implementation + /// should make a best effort to fetch the block from any peers it is + /// connected to (NOTE: this assumption will change in the future #3629). + fn set_sync_fork_request(&self, peers: Vec, hash: Block::Hash, number: NumberFor); +} + +impl BlockSyncRequester for NetworkBridge where + Block: BlockT, + N: communication::Network, +{ + fn set_sync_fork_request(&self, peers: Vec, hash: Block::Hash, number: NumberFor) { + NetworkBridge::set_sync_fork_request(self, peers, hash, number) + } +} + /// A new authority set along with the canonical block it changed at. #[derive(Debug)] pub(crate) struct NewAuthoritySet { 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 +363,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 +383,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 +405,6 @@ where persistent_data.authority_set.clone(), voter_commands_tx, persistent_data.consensus_changes.clone(), - api, ), LinkHalf { client, @@ -399,7 +416,7 @@ where } fn global_communication, B, E, N, RA>( - set_id: u64, + set_id: SetId, voters: &Arc>, client: &Arc>, network: &NetworkBridge, @@ -432,8 +449,10 @@ fn global_communication, B, E, N, RA>( // block commit and catch up messages until relevant blocks are imported. let global_in = UntilGlobalMessageBlocksImported::new( client.import_notification_stream(), + network.clone(), client.clone(), global_in, + "global", ); let global_in = global_in.map_err(CommandOrError::from); @@ -457,7 +476,7 @@ fn register_finality_tracker_inherent_data_provider ?info.finalized_number, "finalized_hash" => ?info.finalized_hash, @@ -472,7 +491,7 @@ fn register_finality_tracker_inherent_data_provider, N, RA, SC, X> { +pub struct GrandpaParams, N, RA, SC, VR, X> { /// Configuration for the GRANDPA service. pub config: Config, /// A link to the block import worker. @@ -484,13 +503,15 @@ 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>, + /// A voting rule used to potentially restrict target votes. + pub voting_rule: VR, } /// Run a GRANDPA voter as a task. Provide configuration and a link to a /// block import worker that has already been instantiated with `block_import`. -pub fn run_grandpa_voter, N, RA, SC, X>( - grandpa_params: GrandpaParams, +pub fn run_grandpa_voter, N, RA, SC, VR, X>( + grandpa_params: GrandpaParams, ) -> client::error::Result + Send + 'static> where Block::Hash: Ord, B: Backend + 'static, @@ -498,6 +519,7 @@ pub fn run_grandpa_voter, N, RA, SC, X>( N: Network + Send + Sync + 'static, N::In: Send + 'static, SC: SelectChain + 'static, + VR: VotingRule> + Clone + 'static, NumberFor: BlockNumberOps, DigestFor: Encode, RA: Send + Sync + 'static, @@ -510,6 +532,7 @@ pub fn run_grandpa_voter, N, RA, SC, X>( inherent_data_providers, on_exit, telemetry_on_connect, + voting_rule, } = grandpa_params; let LinkHalf { @@ -524,24 +547,30 @@ pub fn run_grandpa_voter, N, RA, SC, X>( config.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 = persistent_data.authority_set.clone(); - let events = telemetry_on_connect.telemetry_connection_sinks + 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(()) }) @@ -556,8 +585,9 @@ pub fn run_grandpa_voter, N, RA, SC, X>( config, network, select_chain, + voting_rule, persistent_data, - voter_commands_rx + voter_commands_rx, ); let voter_work = voter_work @@ -578,13 +608,13 @@ pub fn run_grandpa_voter, N, RA, SC, X>( /// Future that powers the voter. #[must_use] -struct VoterWork, RA, SC> { +struct VoterWork, RA, SC, VR> { voter: Box>> + Send>, - env: Arc>, + env: Arc>, voter_commands_rx: mpsc::UnboundedReceiver>>, } -impl VoterWork +impl VoterWork where Block: BlockT, N: Network + Sync, @@ -594,20 +624,23 @@ where E: CallExecutor + Send + Sync + 'static, B: Backend + 'static, SC: SelectChain + 'static, + VR: VotingRule> + Clone + 'static, { fn new( client: Arc>, config: Config, network: NetworkBridge, select_chain: SC, + voting_rule: VR, persistent_data: PersistentData, voter_commands_rx: mpsc::UnboundedReceiver>>, ) -> Self { let voters = persistent_data.authority_set.current_authorities(); let env = Arc::new(Environment { - inner: client, + client, select_chain, + voting_rule, voters: Arc::new(voters), config, network, @@ -633,14 +666,33 @@ where /// 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" => ?self.env.config.name(), "set_id" => ?self.env.set_id + "name" => ?self.env.config.name(), + "set_id" => ?self.env.set_id, + "authority_id" => authority_id.to_string(), + ); + + let chain_info = self.env.client.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 chain_info = self.env.inner.info(); - let last_finalized = ( chain_info.chain.finalized_hash, chain_info.chain.finalized_number, @@ -649,7 +701,7 @@ where let global_comms = global_communication( self.env.set_id, &self.env.voters, - &self.env.inner, + &self.env.client, &self.env.network, &self.env.config.keystore, ); @@ -697,8 +749,7 @@ where (new.canon_hash, new.canon_number), ); - #[allow(deprecated)] - aux_schema::write_voter_set_state(&**self.env.inner.backend(), &set_state)?; + aux_schema::write_voter_set_state(&*self.env.client, &set_state)?; Ok(Some(set_state)) })?; @@ -707,12 +758,13 @@ where 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(), + client: self.env.client.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(), + voting_rule: self.env.voting_rule.clone(), }); self.rebuild_voter(); @@ -726,8 +778,7 @@ where let completed_rounds = voter_set_state.completed_rounds(); let set_state = VoterSetState::Paused { completed_rounds }; - #[allow(deprecated)] - aux_schema::write_voter_set_state(&**self.env.inner.backend(), &set_state)?; + aux_schema::write_voter_set_state(&*self.env.client, &set_state)?; Ok(Some(set_state)) })?; @@ -738,7 +789,7 @@ where } } -impl Future for VoterWork +impl Future for VoterWork where Block: BlockT, N: Network + Sync, @@ -748,6 +799,7 @@ where E: CallExecutor + Send + Sync + 'static, B: Backend + 'static, SC: SelectChain + 'static, + VR: VotingRule> + Clone + 'static, { type Item = (); type Error = Error; @@ -791,9 +843,9 @@ where } } -#[deprecated(since = "1.1", note = "Please switch to run_grandpa_voter.")] -pub fn run_grandpa, N, RA, SC, X>( - grandpa_params: GrandpaParams, +#[deprecated(since = "1.1.0", note = "Please switch to run_grandpa_voter.")] +pub fn run_grandpa, N, RA, SC, VR, X>( + grandpa_params: GrandpaParams, ) -> ::client::error::Result + Send + 'static> where Block::Hash: Ord, B: Backend + 'static, @@ -804,6 +856,7 @@ pub fn run_grandpa, N, RA, SC, X>( NumberFor: BlockNumberOps, DigestFor: Encode, RA: Send + Sync + 'static, + VR: VotingRule> + Clone + 'static, X: Future + Clone + Send + 'static, { run_grandpa_voter(grandpa_params) @@ -849,3 +902,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 dbdabe96294b115c522ba8093d7b0c83ee0b8383..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, @@ -247,7 +254,7 @@ 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.is_empty(); - let import_result = BlockImport::import_block(&mut client, block, new_cache); + 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 f634fd114ae3d7cb4eb628c94cb1452a8c4a55ff..8c0047e38bdbfccf76f5f3dcbab64eca37ecad87 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 { @@ -422,6 +385,7 @@ fn run_to_completion_with( inherent_data_providers: InherentDataProviders::new(), on_exit: Exit, telemetry_on_connect: None, + voting_rule: (), }; let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network"); @@ -451,6 +415,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(); @@ -535,6 +517,7 @@ fn finalize_3_voters_1_full_observer() { inherent_data_providers: InherentDataProviders::new(), on_exit: Exit, telemetry_on_connect: None, + voting_rule: (), }; let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network"); @@ -576,7 +559,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 +571,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 +580,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 +595,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 +609,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 +660,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); @@ -706,6 +678,7 @@ fn transition_3_voters_twice_1_full_observer() { inherent_data_providers: InherentDataProviders::new(), on_exit: Exit, telemetry_on_connect: None, + voting_rule: (), }; let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network"); @@ -787,7 +760,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 +767,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 +821,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 +828,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 +841,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, }); @@ -893,30 +864,6 @@ fn finalizes_multiple_pending_changes_in_order() { run_to_completion(&mut runtime, 30, net.clone(), all_peers); } -#[test] -fn doesnt_vote_on_the_tip_of_the_chain() { - let mut runtime = current_thread::Runtime::new().unwrap(); - let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; - let voters = make_ids(peers_a); - let api = TestApi::new(voters); - let mut net = GrandpaTestNet::new(api, 3); - - // add 100 blocks - net.peer(0).push_blocks(100, false); - net.block_until_sync(&mut runtime); - - for i in 0..3 { - assert_eq!(net.peer(i).client().info().chain.best_number, 100, - "Peer #{} failed to sync", i); - } - - let net = Arc::new(Mutex::new(net)); - let highest = run_to_completion(&mut runtime, 75, net.clone(), peers_a); - - // the highest block to be finalized will be 3/4 deep in the unfinalized chain - assert_eq!(highest, 75); -} - #[test] fn force_change_to_new_set() { let _ = env_logger::try_init(); @@ -933,27 +880,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 +909,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 +934,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 +961,7 @@ fn allows_reimporting_change_blocks() { clear_justification_requests: false, bad_justification: false, needs_finality_proof: false, + is_new_best: true, }), ); @@ -1040,8 +984,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 +1011,7 @@ fn test_bad_justification() { needs_justification: true, clear_justification_requests: false, bad_justification: true, + is_new_best: true, ..Default::default() }), ); @@ -1099,7 +1045,9 @@ 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. @@ -1153,6 +1101,7 @@ fn voter_persists_its_votes() { inherent_data_providers: InherentDataProviders::new(), on_exit: Exit, telemetry_on_connect: None, + voting_rule: VotingRulesBuilder::default().build(), }; let voter = run_grandpa_voter(grandpa_params) @@ -1215,6 +1164,7 @@ fn voter_persists_its_votes() { config.clone(), set_state, Exit, + true, ); runtime.block_on(routing_work).unwrap(); @@ -1257,9 +1207,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(); @@ -1416,20 +1365,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 @@ -1482,6 +1432,7 @@ fn voter_catches_up_to_latest_round_when_behind() { inherent_data_providers: InherentDataProviders::new(), on_exit: Exit, telemetry_on_connect: None, + voting_rule: (), }; Box::new(run_grandpa_voter(grandpa_params).expect("all in order with client and network")) @@ -1563,3 +1514,116 @@ fn voter_catches_up_to_latest_round_when_behind() { let drive_to_completion = futures::future::poll_fn(|| { net.lock().poll(); Ok(Async::NotReady) }); let _ = runtime.block_on(test.select(drive_to_completion).map_err(|_| ())).unwrap(); } + +#[test] +fn grandpa_environment_respects_voting_rules() { + use grandpa::Chain; + use network::test::TestClient; + + let peers = &[Ed25519Keyring::Alice]; + let voters = make_ids(peers); + + let mut net = GrandpaTestNet::new(TestApi::new(voters), 1); + let peer = net.peer(0); + let network_service = peer.network_service().clone(); + let link = peer.data.lock().take().unwrap(); + + // create a voter environment with a given voting rule + let environment = |voting_rule: Box>| { + let PersistentData { + ref authority_set, + ref consensus_changes, + ref set_state, + .. + } = link.persistent_data; + + let config = Config { + gossip_duration: TEST_GOSSIP_DURATION, + justification_period: 32, + keystore: None, + name: None, + }; + + let (network, _) = NetworkBridge::new( + network_service.clone(), + config.clone(), + set_state.clone(), + Exit, + true, + ); + + Environment { + authority_set: authority_set.clone(), + config: config.clone(), + consensus_changes: consensus_changes.clone(), + client: link.client.clone(), + select_chain: link.select_chain.clone(), + set_id: authority_set.set_id(), + voter_set_state: set_state.clone(), + voters: Arc::new(authority_set.current_authorities()), + network, + voting_rule, + } + }; + + // add 20 blocks + peer.push_blocks(20, false); + + // create an environment with no voting rule restrictions + let unrestricted_env = environment(Box::new(())); + + // another with 3/4 unfinalized chain voting rule restriction + let three_quarters_env = environment(Box::new( + voting_rule::ThreeQuartersOfTheUnfinalizedChain + )); + + // and another restricted with the default voting rules: i.e. 3/4 rule and + // always below best block + let default_env = environment(Box::new( + VotingRulesBuilder::default().build() + )); + + // the unrestricted environment should just return the best block + assert_eq!( + unrestricted_env.best_chain_containing( + peer.client().info().chain.finalized_hash + ).unwrap().1, + 20, + ); + + // both the other environments should return block 15, which is 3/4 of the + // way in the unfinalized chain + assert_eq!( + three_quarters_env.best_chain_containing( + peer.client().info().chain.finalized_hash + ).unwrap().1, + 15, + ); + + assert_eq!( + default_env.best_chain_containing( + peer.client().info().chain.finalized_hash + ).unwrap().1, + 15, + ); + + // we finalize block 19 with block 20 being the best block + peer.client().finalize_block(BlockId::Number(19), None, false).unwrap(); + + // the 3/4 environment should propose block 20 for voting + assert_eq!( + three_quarters_env.best_chain_containing( + peer.client().info().chain.finalized_hash + ).unwrap().1, + 20, + ); + + // while the default environment will always still make sure we don't vote + // on the best block + assert_eq!( + default_env.best_chain_containing( + peer.client().info().chain.finalized_hash + ).unwrap().1, + 19, + ); +} diff --git a/core/finality-grandpa/src/until_imported.rs b/core/finality-grandpa/src/until_imported.rs index af797c99ab39bdda781ee6d1fecfb4d781573746..5fca476a82b6a45ae47a5f63d143f8ce9ed0040d 100644 --- a/core/finality-grandpa/src/until_imported.rs +++ b/core/finality-grandpa/src/until_imported.rs @@ -20,7 +20,13 @@ //! //! This is used for votes and commit messages currently. -use super::{BlockStatus, CommunicationIn, Error, SignedMessage}; +use super::{ + BlockStatus as BlockStatusT, + BlockSyncRequester as BlockSyncRequesterT, + CommunicationIn, + Error, + SignedMessage, +}; use log::{debug, warn}; use client::{BlockImportNotification, ImportNotifications}; @@ -54,8 +60,8 @@ pub(crate) trait BlockUntilImported: Sized { wait: Wait, ready: Ready, ) -> Result<(), Error> where - S: BlockStatus, - Wait: FnMut(Block::Hash, Self), + S: BlockStatusT, + Wait: FnMut(Block::Hash, NumberFor, Self), Ready: FnMut(Self::Blocked); /// called when the wait has completed. The canonical number is passed through @@ -64,23 +70,33 @@ pub(crate) trait BlockUntilImported: Sized { } /// Buffering imported messages until blocks with given hashes are imported. -pub(crate) struct UntilImported> { +pub(crate) struct UntilImported> { import_notifications: Fuse, Error = ()> + Send>>, - status_check: Status, + block_sync_requester: BlockSyncRequester, + status_check: BlockStatus, inner: Fuse, ready: VecDeque, check_pending: Interval, - pending: HashMap)>, + /// Mapping block hashes to their block number, the point in time it was + /// first encountered (Instant) and a list of GRANDPA messages referencing + /// the block hash. + pending: HashMap, Instant, Vec)>, + identifier: &'static str, } -impl UntilImported - where Status: BlockStatus, M: BlockUntilImported +impl UntilImported where + Block: BlockT, + BlockStatus: BlockStatusT, + M: BlockUntilImported, + I: Stream, { /// Create a new `UntilImported` wrapper. pub(crate) fn new( import_notifications: ImportNotifications, - status_check: Status, + block_sync_requester: BlockSyncRequester, + status_check: BlockStatus, stream: I, + identifier: &'static str, ) -> Self { // how often to check if pending messages that are waiting for blocks to be // imported can be checked. @@ -96,17 +112,21 @@ impl UntilImported let stream = import_notifications.map::<_, fn(_) -> _>(|v| Ok::<_, ()>(v)).compat(); Box::new(stream) as Box + Send> }.fuse(), + block_sync_requester, status_check, inner: stream.fuse(), ready: VecDeque::new(), check_pending, pending: HashMap::new(), + identifier, } } } -impl Stream for UntilImported where - Status: BlockStatus, +impl Stream for UntilImported where + Block: BlockT, + BStatus: BlockStatusT, + BSyncRequester: BlockSyncRequesterT, I: Stream, M: BlockUntilImported, { @@ -125,10 +145,10 @@ impl Stream for UntilImported M::schedule_wait( input, &self.status_check, - |target_hash, wait| pending + |target_hash, target_number, wait| pending .entry(target_hash) - .or_insert_with(|| (Instant::now(), Vec::new())) - .1 + .or_insert_with(|| (target_number, Instant::now(), Vec::new())) + .2 .push(wait), |ready_item| ready.push_back(ready_item), )?; @@ -143,7 +163,7 @@ impl Stream for UntilImported Ok(Async::Ready(None)) => return Ok(Async::Ready(None)), Ok(Async::Ready(Some(notification))) => { // new block imported. queue up all messages tied to that hash. - if let Some((_, messages)) = self.pending.remove(¬ification.hash) { + if let Some((_, _, messages)) = self.pending.remove(¬ification.hash) { let canon_number = notification.header.number().clone(); let ready_messages = messages.into_iter() .filter_map(|m| m.wait_completed(canon_number)); @@ -162,18 +182,29 @@ impl Stream for UntilImported if update_interval { let mut known_keys = Vec::new(); - for (&block_hash, &mut (ref mut last_log, ref v)) in &mut self.pending { + for (&block_hash, &mut (block_number, ref mut last_log, ref v)) in &mut self.pending { if let Some(number) = self.status_check.block_number(block_hash)? { known_keys.push((block_hash, number)); } else { let next_log = *last_log + LOG_PENDING_INTERVAL; - if Instant::now() <= next_log { + 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. \ + Requesting network sync service to retrieve block from. \ Possible fork?", block_hash, v.len(), + self.identifier, + ); + + // NOTE: when sending an empty vec of peers the + // underlying should make a best effort to sync the + // block from any peers it knows about. + self.block_sync_requester.set_sync_fork_request( + vec![], + block_hash, + block_number, ); *last_log = next_log; @@ -182,7 +213,7 @@ impl Stream for UntilImported } for (known_hash, canon_number) in known_keys { - if let Some((_, pending_messages)) = self.pending.remove(&known_hash) { + if let Some((_, _, pending_messages)) = self.pending.remove(&known_hash) { let ready_messages = pending_messages.into_iter() .filter_map(|m| m.wait_completed(canon_number)); @@ -216,14 +247,14 @@ fn warn_authority_wrong_target(hash: H, id: AuthorityId) impl BlockUntilImported for SignedMessage { type Blocked = Self; - fn schedule_wait( + fn schedule_wait( msg: Self::Blocked, - status_check: &S, + status_check: &BlockStatus, mut wait: Wait, mut ready: Ready, ) -> Result<(), Error> where - S: BlockStatus, - Wait: FnMut(Block::Hash, Self), + BlockStatus: BlockStatusT, + Wait: FnMut(Block::Hash, NumberFor, Self), Ready: FnMut(Self::Blocked), { let (&target_hash, target_number) = msg.target(); @@ -235,7 +266,7 @@ impl BlockUntilImported for SignedMessage { ready(msg); } } else { - wait(target_hash, msg) + wait(target_hash, target_number, msg) } Ok(()) @@ -255,7 +286,13 @@ impl BlockUntilImported for SignedMessage { /// Helper type definition for the stream which waits until vote targets for /// signed messages are imported. -pub(crate) type UntilVoteTargetImported = UntilImported>; +pub(crate) type UntilVoteTargetImported = UntilImported< + Block, + BlockStatus, + BlockSyncRequester, + I, + SignedMessage, +>; /// This blocks a global message import, i.e. a commit or catch up messages, /// until all blocks referenced in its votes are known. @@ -270,14 +307,14 @@ pub(crate) struct BlockGlobalMessage { impl BlockUntilImported for BlockGlobalMessage { type Blocked = CommunicationIn; - fn schedule_wait( + fn schedule_wait( input: Self::Blocked, - status_check: &S, + status_check: &BlockStatus, mut wait: Wait, mut ready: Ready, ) -> Result<(), Error> where - S: BlockStatus, - Wait: FnMut(Block::Hash, Self), + BlockStatus: BlockStatusT, + Wait: FnMut(Block::Hash, NumberFor, Self), Ready: FnMut(Self::Blocked), { use std::collections::hash_map::Entry; @@ -379,7 +416,7 @@ impl BlockUntilImported for BlockGlobalMessage { // if this is taking a long time. for (hash, is_known) in checked_hashes { if let KnownOrUnknown::Unknown(target_number) = is_known { - wait(hash, BlockGlobalMessage { + wait(hash, target_number, BlockGlobalMessage { inner: locked_global.clone(), target_number, }) @@ -421,9 +458,10 @@ impl BlockUntilImported for BlockGlobalMessage { /// A stream which gates off incoming global messages, i.e. commit and catch up /// messages, until all referenced block hashes have been imported. -pub(crate) type UntilGlobalMessageBlocksImported = UntilImported< +pub(crate) type UntilGlobalMessageBlocksImported = UntilImported< Block, - Status, + BlockStatus, + BlockSyncRequester, I, BlockGlobalMessage, >; @@ -472,6 +510,7 @@ mod tests { origin: BlockOrigin::File, header, is_new_best: false, + retracted: vec![], }).unwrap(); } } @@ -480,12 +519,31 @@ mod tests { inner: Arc>>, } - impl BlockStatus for TestBlockStatus { + impl BlockStatusT for TestBlockStatus { fn block_number(&self, hash: Hash) -> Result, Error> { Ok(self.inner.lock().get(&hash).map(|x| x.clone())) } } + #[derive(Clone)] + struct TestBlockSyncRequester { + requests: Arc)>>>, + } + + impl Default for TestBlockSyncRequester { + fn default() -> Self { + TestBlockSyncRequester { + requests: Arc::new(Mutex::new(Vec::new())), + } + } + } + + impl BlockSyncRequesterT for TestBlockSyncRequester { + fn set_sync_fork_request(&self, _peers: Vec, hash: Hash, number: NumberFor) { + self.requests.lock().push((hash, number)); + } + } + fn make_header(number: u64) -> Header { Header::new( number, @@ -530,8 +588,10 @@ mod tests { let until_imported = UntilGlobalMessageBlocksImported::new( import_notifications, + TestBlockSyncRequester::default(), block_status, global_rx.map_err(|_| panic!("should never error")), + "global", ); global_tx.unbounded_send(msg).unwrap(); @@ -555,8 +615,10 @@ mod tests { let until_imported = UntilGlobalMessageBlocksImported::new( import_notifications, + TestBlockSyncRequester::default(), block_status, global_rx.map_err(|_| panic!("should never error")), + "global", ); global_tx.unbounded_send(msg).unwrap(); @@ -799,4 +861,80 @@ mod tests { unapply_catch_up(unknown_catch_up()), ); } + + #[test] + fn request_block_sync_for_needed_blocks() { + let (chain_state, import_notifications) = TestChainState::new(); + let block_status = chain_state.block_status(); + + let (global_tx, global_rx) = futures::sync::mpsc::unbounded(); + + let block_sync_requester = TestBlockSyncRequester::default(); + + let until_imported = UntilGlobalMessageBlocksImported::new( + import_notifications, + block_sync_requester.clone(), + block_status, + global_rx.map_err(|_| panic!("should never error")), + "global", + ); + + let h1 = make_header(5); + let h2 = make_header(6); + let h3 = make_header(7); + + // we create a commit message, with precommits for blocks 6 and 7 which + // we haven't imported. + let unknown_commit = CompactCommit:: { + target_hash: h1.hash(), + target_number: 5, + precommits: vec![ + Precommit { + target_hash: h2.hash(), + target_number: 6, + }, + Precommit { + target_hash: h3.hash(), + target_number: 7, + }, + ], + auth_data: Vec::new(), // not used + }; + + let unknown_commit = || voter::CommunicationIn::Commit( + 0, + unknown_commit.clone(), + voter::Callback::Blank, + ); + + // we send the commit message and spawn the until_imported stream + global_tx.unbounded_send(unknown_commit()).unwrap(); + + let mut runtime = Runtime::new().unwrap(); + runtime.spawn(until_imported.into_future().map(|_| ()).map_err(|_| ())); + + // assert that we will make sync requests + let assert = futures::future::poll_fn::<(), (), _>(|| { + let block_sync_requests = block_sync_requester.requests.lock(); + + // we request blocks targeted by the precommits that aren't imported + if block_sync_requests.contains(&(h2.hash(), *h2.number())) && + block_sync_requests.contains(&(h3.hash(), *h3.number())) + { + return Ok(Async::Ready(())); + } + + Ok(Async::NotReady) + }); + + // the `until_imported` stream doesn't request the blocks immediately, + // but it should request them after a small timeout + let timeout = Delay::new(Instant::now() + Duration::from_secs(60)); + let test = assert.select2(timeout).map(|res| match res { + Either::A(_) => {}, + Either::B(_) => panic!("timed out waiting for block sync request"), + }).map_err(|_| ()); + + runtime.block_on(test).unwrap(); + } } diff --git a/core/finality-grandpa/src/voting_rule.rs b/core/finality-grandpa/src/voting_rule.rs new file mode 100644 index 0000000000000000000000000000000000000000..355fa0cd2d08068d8b0de1197b0e01cd32e1a884 --- /dev/null +++ b/core/finality-grandpa/src/voting_rule.rs @@ -0,0 +1,270 @@ +// 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 . + +//! Handling custom voting rules for GRANDPA. +//! +//! This exposes the `VotingRule` trait used to implement arbitrary voting +//! restrictions that are taken into account by the GRANDPA environment when +//! selecting a finality target to vote on. + +use std::sync::Arc; + +use client::blockchain::HeaderBackend; +use sr_primitives::generic::BlockId; +use sr_primitives::traits::{Block as BlockT, Header, NumberFor, One, Zero}; + +/// A trait for custom voting rules in GRANDPA. +pub trait VotingRule: Send + Sync where + Block: BlockT, + B: HeaderBackend, +{ + /// Restrict the given `current_target` vote, returning the block hash and + /// number of the block to vote on, and `None` in case the vote should not + /// be restricted. `base` is the block that we're basing our votes on in + /// order to pick our target (e.g. last round estimate), and `best_target` + /// is the initial best vote target before any vote rules were applied. When + /// applying multiple `VotingRule`s both `base` and `best_target` should + /// remain unchanged. + /// + /// The contract of this interface requires that when restricting a vote, the + /// returned value **must** be an ancestor of the given `current_target`, + /// this also means that a variant must be maintained throughout the + /// execution of voting rules wherein `current_target <= best_target`. + fn restrict_vote( + &self, + backend: &B, + base: &Block::Header, + best_target: &Block::Header, + current_target: &Block::Header, + ) -> Option<(Block::Hash, NumberFor)>; +} + +impl VotingRule for () where + Block: BlockT, + B: HeaderBackend, +{ + fn restrict_vote( + &self, + _backend: &B, + _base: &Block::Header, + _best_target: &Block::Header, + _current_target: &Block::Header, + ) -> Option<(Block::Hash, NumberFor)> { + None + } +} + +/// A custom voting rule that guarantees that our vote is always behind the best +/// block, in the best case exactly one block behind it. +#[derive(Clone)] +pub struct BeforeBestBlock; +impl VotingRule for BeforeBestBlock where + Block: BlockT, + B: HeaderBackend, +{ + fn restrict_vote( + &self, + _backend: &B, + _base: &Block::Header, + best_target: &Block::Header, + current_target: &Block::Header, + ) -> Option<(Block::Hash, NumberFor)> { + if current_target.number().is_zero() { + return None; + } + + if current_target.number() == best_target.number() { + return Some(( + current_target.parent_hash().clone(), + *current_target.number() - One::one(), + )); + } + + None + } +} + +/// A custom voting rule that limits votes towards 3/4 of the unfinalized chain, +/// using the given `base` and `best_target` to figure where the 3/4 target +/// should fall. +pub struct ThreeQuartersOfTheUnfinalizedChain; + +impl VotingRule for ThreeQuartersOfTheUnfinalizedChain where + Block: BlockT, + B: HeaderBackend, +{ + fn restrict_vote( + &self, + backend: &B, + base: &Block::Header, + best_target: &Block::Header, + current_target: &Block::Header, + ) -> Option<(Block::Hash, NumberFor)> { + // target a vote towards 3/4 of the unfinalized chain (rounding up) + let target_number = { + let two = NumberFor::::one() + One::one(); + let three = two + One::one(); + let four = three + One::one(); + + let diff = *best_target.number() - *base.number(); + let diff = ((diff * three) + two) / four; + + *base.number() + diff + }; + + // our current target is already lower than this rule would restrict + if target_number >= *current_target.number() { + return None; + } + + let mut target_header = current_target.clone(); + let mut target_hash = current_target.hash(); + + // walk backwards until we find the target block + loop { + if *target_header.number() < target_number { + unreachable!( + "we are traversing backwards from a known block; \ + blocks are stored contiguously; \ + qed" + ); + } + if *target_header.number() == target_number { + return Some((target_hash, target_number)); + } + + target_hash = *target_header.parent_hash(); + target_header = backend.header(BlockId::Hash(target_hash)).ok()? + .expect("Header known to exist due to the existence of one of its descendents; qed"); + } + } +} + +struct VotingRules { + rules: Arc>>>, +} + +impl Clone for VotingRules { + fn clone(&self) -> Self { + VotingRules { + rules: self.rules.clone(), + } + } +} + +impl VotingRule for VotingRules where + Block: BlockT, + B: HeaderBackend, +{ + fn restrict_vote( + &self, + backend: &B, + base: &Block::Header, + best_target: &Block::Header, + current_target: &Block::Header, + ) -> Option<(Block::Hash, NumberFor)> { + let restricted_target = self.rules.iter().fold( + current_target.clone(), + |current_target, rule| { + rule.restrict_vote( + backend, + base, + best_target, + ¤t_target, + ) + .and_then(|(hash, _)| backend.header(BlockId::Hash(hash)).ok()) + .and_then(std::convert::identity) + .unwrap_or(current_target) + }, + ); + + let restricted_hash = restricted_target.hash(); + + if restricted_hash != current_target.hash() { + Some((restricted_hash, *restricted_target.number())) + } else { + None + } + } +} + +/// A builder of a composite voting rule that applies a set of rules to +/// progressively restrict the vote. +pub struct VotingRulesBuilder { + rules: Vec>>, +} + +impl Default for VotingRulesBuilder where + Block: BlockT, + B: HeaderBackend, +{ + fn default() -> Self { + VotingRulesBuilder::new() + .add(BeforeBestBlock) + .add(ThreeQuartersOfTheUnfinalizedChain) + } +} + +impl VotingRulesBuilder where + Block: BlockT, + B: HeaderBackend, +{ + /// Return a new voting rule builder using the given backend. + pub fn new() -> Self { + VotingRulesBuilder { + rules: Vec::new(), + } + } + + /// Add a new voting rule to the builder. + pub fn add(mut self, rule: R) -> Self where + R: VotingRule + 'static, + { + self.rules.push(Box::new(rule)); + self + } + + /// Add all given voting rules to the builder. + pub fn add_all(mut self, rules: I) -> Self where + I: IntoIterator>>, + { + self.rules.extend(rules); + self + } + + /// Return a new `VotingRule` that applies all of the previously added + /// voting rules in-order. + pub fn build(self) -> impl VotingRule + Clone { + VotingRules { + rules: Arc::new(self.rules), + } + } +} + +impl VotingRule for Box> where + Block: BlockT, + B: HeaderBackend, +{ + fn restrict_vote( + &self, + backend: &B, + base: &Block::Header, + best_target: &Block::Header, + current_target: &Block::Header, + ) -> Option<(Block::Hash, NumberFor)> { + (**self).restrict_vote(backend, base, best_target, current_target) + } +} 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/keyring/src/ed25519.rs b/core/keyring/src/ed25519.rs index 56bdb1ce8c0e60d3a43116631378b38592a8f762..c1a357fc0e427f16f58e39fd502ed7e2a56f8e33 100644 --- a/core/keyring/src/ed25519.rs +++ b/core/keyring/src/ed25519.rs @@ -20,6 +20,7 @@ use std::{collections::HashMap, ops::Deref}; use lazy_static::lazy_static; use primitives::{ed25519::{Pair, Public, Signature}, Pair as PairT, Public as PublicT, H256}; pub use primitives::ed25519; +use sr_primitives::AccountId32; /// Set of test accounts. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum_macros::Display, strum_macros::EnumIter)] @@ -39,6 +40,10 @@ impl Keyring { Self::iter().find(|&k| &Public::from(k) == who) } + pub fn from_account_id(who: &AccountId32) -> Option { + Self::iter().find(|&k| &k.to_account_id() == who) + } + pub fn from_raw_public(who: [u8; 32]) -> Option { Self::from_public(&Public::from_raw(who)) } @@ -59,6 +64,10 @@ impl Keyring { Public::from(self).to_raw_vec() } + pub fn to_account_id(self) -> AccountId32 { + self.to_raw_public().into() + } + pub fn sign(self, msg: &[u8]) -> Signature { Pair::from(self).sign(msg) } @@ -119,6 +128,12 @@ impl From for Public { } } +impl From for AccountId32 { + fn from(k: Keyring) -> Self { + k.to_account_id() + } +} + impl From for Pair { fn from(k: Keyring) -> Self { k.pair() diff --git a/core/keyring/src/sr25519.rs b/core/keyring/src/sr25519.rs index bb3aaa6b51db19569208bbad3128b269f5cb7707..b37b2bdf9b22a2f1e3f02c799f72eda5f447d719 100644 --- a/core/keyring/src/sr25519.rs +++ b/core/keyring/src/sr25519.rs @@ -21,6 +21,7 @@ use std::ops::Deref; use lazy_static::lazy_static; use primitives::{sr25519::{Pair, Public, Signature}, Pair as PairT, Public as PublicT, H256}; pub use primitives::sr25519; +use sr_primitives::AccountId32; /// Set of test accounts. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum_macros::Display, strum_macros::EnumIter)] @@ -40,6 +41,10 @@ impl Keyring { Self::iter().find(|&k| &Public::from(k) == who) } + pub fn from_account_id(who: &AccountId32) -> Option { + Self::iter().find(|&k| &k.to_account_id() == who) + } + pub fn from_raw_public(who: [u8; 32]) -> Option { Self::from_public(&Public::from_raw(who)) } @@ -60,6 +65,10 @@ impl Keyring { Public::from(self).to_raw_vec() } + pub fn to_account_id(self) -> AccountId32 { + self.to_raw_public().into() + } + pub fn sign(self, msg: &[u8]) -> Signature { Pair::from(self).sign(msg) } @@ -114,6 +123,12 @@ lazy_static! { }; } +impl From for AccountId32 { + fn from(k: Keyring) -> Self { + k.to_account_id() + } +} + impl From for Public { fn from(k: Keyring) -> Self { (*PUBLIC_KEYS).get(&k).unwrap().clone() diff --git a/core/keystore/Cargo.toml b/core/keystore/Cargo.toml index c56b9ba67dcbdf055697fac19b56c0ad97b16274..cc491337cf83a0d861f1955b76c518b0514fa4be 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.41" +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 00dc04254d0536cd2887c3f2203c3ea18aab4f8a..71e7d95bfa56ac63f96b6457800e277a83efa555 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.12.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 = ["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.41" +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.7.0" 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/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..445d4427bd91c4bc989f5e9fd8de94b5e7637125 100644 --- a/core/network/src/config.rs +++ b/core/network/src/config.rs @@ -26,10 +26,10 @@ 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}; +use libp2p::identity::{Keypair, ed25519}; use libp2p::wasm_ext; use libp2p::{PeerId, Multiaddr, multiaddr}; use std::error::Error; @@ -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 { @@ -361,15 +364,10 @@ impl NonReservedPeerMode { /// the evaluation of the node key configuration. #[derive(Clone)] pub enum NodeKeyConfig { - /// A Secp256k1 secret key configuration. - Secp256k1(Secret), /// A Ed25519 secret key configuration. Ed25519(Secret) } -/// The options for obtaining a Secp256k1 secret key. -pub type Secp256k1Secret = Secret; - /// The options for obtaining a Ed25519 secret key. pub type Ed25519Secret = Secret; @@ -382,7 +380,6 @@ pub enum Secret { /// it is created with a newly generated secret key `K`. The format /// of the file is determined by `K`: /// - /// * `secp256k1::SecretKey`: An unencoded 32 bytes Secp256k1 secret key. /// * `ed25519::SecretKey`: An unencoded 32 bytes Ed25519 secret key. File(PathBuf), /// Always generate a new secret key `K`. @@ -403,20 +400,6 @@ impl NodeKeyConfig { pub fn into_keypair(self) -> io::Result { use NodeKeyConfig::*; match self { - Secp256k1(Secret::New) => - Ok(Keypair::generate_secp256k1()), - - Secp256k1(Secret::Input(k)) => - Ok(Keypair::Secp256k1(k.into())), - - Secp256k1(Secret::File(f)) => - get_secret(f, - |mut b| secp256k1::SecretKey::from_bytes(&mut b), - secp256k1::SecretKey::generate, - |b| b.to_bytes().to_vec()) - .map(secp256k1::Keypair::from) - .map(Keypair::Secp256k1), - Ed25519(Secret::New) => Ok(Keypair::generate_ed25519()), @@ -523,9 +506,9 @@ mod tests { #[test] fn test_secret_input() { - let sk = secp256k1::SecretKey::generate(); - let kp1 = NodeKeyConfig::Secp256k1(Secret::Input(sk.clone())).into_keypair().unwrap(); - let kp2 = NodeKeyConfig::Secp256k1(Secret::Input(sk)).into_keypair().unwrap(); + let sk = ed25519::SecretKey::generate(); + let kp1 = NodeKeyConfig::Ed25519(Secret::Input(sk.clone())).into_keypair().unwrap(); + let kp2 = NodeKeyConfig::Ed25519(Secret::Input(sk)).into_keypair().unwrap(); assert!(secret_bytes(&kp1) == secret_bytes(&kp2)); } diff --git a/core/network/src/error.rs b/core/network/src/error.rs index 95a1dc5abe76b42b450835212ba9b823a2020101..c3f89e43c17107ecbcb0ae6b05f346c172d14fc2 100644 --- a/core/network/src/error.rs +++ b/core/network/src/error.rs @@ -18,16 +18,42 @@ use client; +use libp2p::{PeerId, Multiaddr}; + +use std::fmt; + /// Result type alias for the network. pub type Result = std::result::Result; /// Error type for the network. -#[derive(Debug, derive_more::Display, derive_more::From)] +#[derive(derive_more::Display, derive_more::From)] pub enum Error { /// Io error Io(std::io::Error), /// Client error Client(client::error::Error), + /// The same bootnode (based on address) is registered with two different peer ids. + #[display( + fmt = "The same bootnode (`{}`) is registered with two different peer ids: `{}` and `{}`", + address, + first_id, + second_id, + )] + DuplicateBootnode { + /// The address of the bootnode. + address: Multiaddr, + /// The first peer id that was found for the bootnode. + first_id: PeerId, + /// The second peer id that was found for the bootnode. + second_id: PeerId, + }, +} + +// Make `Debug` use the `Display` implementation. +impl fmt::Debug for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self, f) + } } impl std::error::Error for Error { @@ -35,6 +61,7 @@ impl std::error::Error for Error { match self { Error::Io(ref err) => Some(err), Error::Client(ref err) => Some(err), + Error::DuplicateBootnode { .. } => None, } } } diff --git a/core/network/src/lib.rs b/core/network/src/lib.rs index e797ffb208ec11ea03e5842e42072217cae430e4..d0977d90c90053fba40cddecd105d54bb83b9e02 100644 --- a/core/network/src/lib.rs +++ b/core/network/src/lib.rs @@ -24,9 +24,7 @@ //! # Node identities and addresses //! //! In a decentralized network, each node possesses a network private key and a network public key. -//! In Substrate, the keys are based on the ed25519 curve. As of the writing of this documentation, -//! the secp256k1 curve can also be used, but is deprecated. Our local node's keypair must be -//! passed as part of the network configuration. +//! In Substrate, the keys are based on the ed25519 curve. //! //! From a node's public key, we can derive its *identity*. In Substrate and libp2p, a node's //! identity is represented with the [`PeerId`] struct. All network communications between nodes on @@ -192,6 +190,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)] 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..2e036cf1183f17ca8a5a50156901abce55af4b82 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,36 +1105,29 @@ 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()); - match self.sync.on_block_announce(who.clone(), hash, &header) { - sync::OnBlockAnnounce::Request(peer, req) => { - self.send_message(peer, GenericMessage::BlockRequest(req)); - return CustomMessageOutcome::None - } + 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, &announce, is_their_best) { sync::OnBlockAnnounce::Nothing => { - // try_import is only true when we have all data required to import block + // `on_block_announce` returns `OnBlockAnnounce::ImportHeader` + // when we have all data required to import the block // in the BlockAnnounce message. This is only when: // 1) we're on light client; // AND - // - EITHER 2.1) announced block is stale; - // - OR 2.2) announced block is NEW and we normally only want to download this single block (i.e. - // there are no ascendants of this block scheduled for retrieval) + // 2) parent block is already imported and not pruned. return CustomMessageOutcome::None } sync::OnBlockAnnounce::ImportHeader => () // We proceed with the import. @@ -1098,7 +1150,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 +1175,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 +1191,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 +1247,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 +1322,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 +1459,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 d916e9aace7044cd1a048b641ba91cd0696ef120..f3d4e536a788d2d238c01d5d7adb794e921e3402 100644 --- a/core/network/src/protocol/consensus_gossip.rs +++ b/core/network/src/protocol/consensus_gossip.rs @@ -48,7 +48,7 @@ use std::sync::Arc; use std::iter; use std::time; use log::{trace, debug}; -use futures::sync::mpsc; +use futures03::channel::mpsc; use lru_cache::LruCache; use libp2p::PeerId; use sr_primitives::traits::{Block as BlockT, Hash, HashFor}; @@ -89,6 +89,7 @@ struct MessageEntry { message_hash: B::Hash, topic: B::Hash, message: ConsensusMessage, + sender: Option, } /// Consensus message destination. @@ -322,12 +323,14 @@ impl ConsensusGossip { message_hash: B::Hash, topic: B::Hash, message: ConsensusMessage, + sender: Option, ) { if self.known_messages.insert(message_hash.clone(), ()).is_none() { self.messages.push(MessageEntry { message_hash, topic, message, + sender, }); } } @@ -343,7 +346,7 @@ impl ConsensusGossip { message: ConsensusMessage, ) { let message_hash = HashFor::::hash(&message.data[..]); - self.register_message_hashed(message_hash, topic, message); + self.register_message_hashed(message_hash, topic, message, None); } /// Call when a peer has been disconnected to stop tracking gossip status. @@ -429,7 +432,7 @@ impl ConsensusGossip { { tx.unbounded_send(TopicNotification { message: entry.message.data.clone(), - sender: None, + sender: entry.sender.clone(), }) .expect("receiver known to be live; qed"); } @@ -498,7 +501,7 @@ impl ConsensusGossip { } } if keep { - self.register_message_hashed(message_hash, topic, message); + self.register_message_hashed(message_hash, topic, message, Some(who.clone())); } } else { trace!(target:"gossip", "Ignored statement from unregistered peer {}", who); @@ -553,7 +556,7 @@ impl ConsensusGossip { force: bool, ) { let message_hash = HashFor::::hash(&message.data); - self.register_message_hashed(message_hash, topic, message.clone()); + self.register_message_hashed(message_hash, topic, message.clone(), None); let intent = if force { MessageIntent::ForcedBroadcast } else { MessageIntent::Broadcast }; propagate(protocol, iter::once((&message_hash, &topic, &message)), intent, &mut self.peers, &self.validators); } @@ -605,7 +608,7 @@ impl Validator for DiscardAll { #[cfg(test)] mod tests { use sr_primitives::testing::{H256, Block as RawBlock, ExtrinsicWrapper}; - use futures::Stream; + use futures03::executor::block_on_stream; use super::*; @@ -618,6 +621,7 @@ mod tests { message_hash: $hash, topic: $topic, message: ConsensusMessage { data: $m, engine_id: [0, 0, 0, 0]}, + sender: None, }); } } @@ -666,7 +670,7 @@ mod tests { let m2 = vec![4, 5, 6]; push_msg!(consensus, prev_hash, m1_hash, m1); - push_msg!(consensus, best_hash, m2_hash, m2.clone()); + push_msg!(consensus, best_hash, m2_hash, m2); consensus.known_messages.insert(m1_hash, ()); consensus.known_messages.insert(m2_hash, ()); @@ -688,8 +692,6 @@ mod tests { #[test] fn message_stream_include_those_sent_before_asking_for_stream() { - use futures::Stream; - let mut consensus = ConsensusGossip::::new(); consensus.register_validator_internal([0, 0, 0, 0], Arc::new(AllowAll)); @@ -697,9 +699,9 @@ mod tests { let topic = HashFor::::hash(&[1,2,3]); consensus.register_message(topic, message.clone()); - let stream = consensus.messages_for([0, 0, 0, 0], topic); + let mut stream = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); - assert_eq!(stream.wait().next(), Some(Ok(TopicNotification { message: message.data, sender: None }))); + assert_eq!(stream.next(), Some(TopicNotification { message: message.data, sender: None })); } #[test] @@ -721,16 +723,17 @@ mod tests { let mut consensus = ConsensusGossip::::new(); consensus.register_validator_internal([0, 0, 0, 0], Arc::new(AllowAll)); - let message = ConsensusMessage { data: vec![4, 5, 6], engine_id: [0, 0, 0, 0] }; - let topic = HashFor::::hash(&[1,2,3]); + let data = vec![4, 5, 6]; + let message = ConsensusMessage { data: data.clone(), engine_id: [0, 0, 0, 0] }; + let topic = HashFor::::hash(&[1, 2, 3]); consensus.register_message(topic, message.clone()); - let stream1 = consensus.messages_for([0, 0, 0, 0], topic); - let stream2 = consensus.messages_for([0, 0, 0, 0], topic); + let mut stream1 = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); + let mut stream2 = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); - assert_eq!(stream1.wait().next(), Some(Ok(TopicNotification { message: message.data.clone(), sender: None }))); - assert_eq!(stream2.wait().next(), Some(Ok(TopicNotification { message: message.data, sender: None }))); + assert_eq!(stream1.next(), Some(TopicNotification { message: data.clone(), sender: None })); + assert_eq!(stream2.next(), Some(TopicNotification { message: data, sender: None })); } #[test] @@ -745,9 +748,10 @@ mod tests { consensus.register_message(topic, msg_a); consensus.register_message(topic, msg_b); - let mut stream = consensus.messages_for([0, 0, 0, 0], topic).wait(); + let mut stream = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); + + assert_eq!(stream.next(), Some(TopicNotification { message: vec![1, 2, 3], sender: None })); - assert_eq!(stream.next(), Some(Ok(TopicNotification { message: vec![1, 2, 3], sender: None }))); let _ = consensus.live_message_sinks.remove(&([0, 0, 0, 0], topic)); assert_eq!(stream.next(), None); } diff --git a/core/network/src/protocol/event.rs b/core/network/src/protocol/event.rs index c0c26da515f0b0bd0e9cb819759b7adb9a01c8e1..c8bee5588c704f09a9c2c14d1b5b8245cf6bd1cc 100644 --- a/core/network/src/protocol/event.rs +++ b/core/network/src/protocol/event.rs @@ -20,6 +20,7 @@ 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<(Key, Vec)>), @@ -35,6 +36,7 @@ pub enum DhtEvent { } /// 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 625d9a840a3e6f3f4b607dfeb95be133a93a40fb..4f08c942def1bfc1f118aa90aa8c4a2e0cb4beb5 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; @@ -65,9 +69,6 @@ const MAJOR_SYNC_BLOCKS: u8 = 5; /// Number of recently announced blocks to track for each peer. const ANNOUNCE_HISTORY_SIZE: usize = 64; -/// Max number of blocks to download for unknown forks. -const MAX_UNKNOWN_FORK_DOWNLOAD_LEN: u32 = 32; - /// Reputation change when a peer sent us a status message that led to a /// database read error. const BLOCKCHAIN_STATUS_READ_ERROR_REPUTATION_CHANGE: i32 = -(1 << 16); @@ -119,9 +120,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>, + /// Fork sync targets. + fork_targets: 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 +157,12 @@ pub struct PeerInfo { pub best_number: NumberFor } +struct ForkTarget { + number: NumberFor, + parent_hash: Option, + peers: HashSet, +} + /// The state of syncing between a Peer and ourselves. /// /// Generally two categories, "busy" or `Available`. If busy, the enum @@ -228,13 +240,11 @@ pub enum OnBlockData { /// Result of [`ChainSync::on_block_announce`]. #[derive(Debug, Clone, PartialEq, Eq)] -pub enum OnBlockAnnounce { +pub enum OnBlockAnnounce { /// The announcement does not require further handling. Nothing, /// The announcement header should be imported. ImportHeader, - /// Another block request to the given peer is necessary. - Request(PeerId, BlockRequest) } /// Result of [`ChainSync::on_block_justification`]. @@ -271,7 +281,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 +303,9 @@ impl ChainSync { queue_blocks: Default::default(), best_importing_number: Zero::zero(), request_builder, + fork_targets: Default::default(), is_idle: false, + block_announce_validator, } } @@ -441,6 +454,62 @@ 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, mut peers: Vec, hash: &B::Hash, number: NumberFor) { + if peers.is_empty() { + debug!( + target: "sync", + "Explicit sync request for block {:?} with no peers specified. \ + Syncing from all connected peers {:?} instead.", + hash, peers, + ); + + peers = self.peers.iter() + // Only request blocks from peers who are ahead or on a par. + .filter(|(_, peer)| peer.best_number >= number) + .map(|(id, _)| id.clone()) + .collect(); + } else { + 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.fork_targets + .entry(hash.clone()) + .or_insert_with(|| ForkTarget { + number, + peers: Default::default(), + parent_hash: None, + }) + .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 +569,34 @@ impl ChainSync { } let blocks = &mut self.blocks; let attrs = &self.required_block_attributes; + let fork_targets = &self.fork_targets; let mut have_requests = false; + let last_finalized = self.client.info().chain.finalized_number; + let best_queued = self.best_queued_number; + let client = &self.client; + let queue = &self.queue_blocks; 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)) = fork_sync_request( + id, + fork_targets, + best_queued, + last_finalized, + attrs, + |hash| if queue.contains(hash) { + BlockStatus::Queued + } else { + client.block_status(&BlockId::Hash(*hash)).unwrap_or(BlockStatus::Unknown) + }, + ) { + trace!(target: "sync", "Downloading fork {:?} 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; @@ -595,6 +685,26 @@ impl ChainSync { peer.state = PeerSyncState::AncestorSearch(next_num, next_state); return Ok(OnBlockData::Request(who, ancestry_request::(next_num))) } else { + // Ancestry search is complete. Check if peer is on a stale fork unknown to us and + // add it to sync targets if necessary. + trace!(target: "sync", "Ancestry search complete. Ours={} ({}), Theirs={} ({}), Common={}", + self.best_queued_hash, + self.best_queued_number, + peer.best_hash, + peer.best_number, + peer.common_number + ); + if peer.common_number < peer.best_number && peer.best_number < self.best_queued_number { + trace!(target: "sync", "Added fork target {} for {}" , peer.best_hash, who); + self.fork_targets + .entry(peer.best_hash.clone()) + .or_insert_with(|| ForkTarget { + number: peer.best_number, + parent_hash: None, + peers: Default::default(), + }) + .peers.insert(who); + } peer.state = PeerSyncState::Available; Vec::new() } @@ -659,8 +769,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 +923,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,11 +962,14 @@ impl ChainSync { self.best_queued_number = number; self.best_queued_hash = *hash; } + if let Some(_) = self.fork_targets.remove(&hash) { + trace!(target: "sync", "Completed fork sync {:?}", hash); + } // Update common blocks for (n, peer) in self.peers.iter_mut() { if let PeerSyncState::AncestorSearch(_, _) = peer.state { - // Abort search. - peer.state = PeerSyncState::Available; + // Wait for ancestry search to complete first. + continue; } let new_common_number = if peer.best_number >= number { number @@ -886,11 +992,14 @@ impl ChainSync { /// Call when a node announces a new block. /// - /// If true is returned, then the caller MUST try to import passed + /// If `OnBlockAnnounce::ImportHeader` is returned, then the caller MUST try to import passed /// 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 +1021,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,9 +1029,9 @@ 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 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(); @@ -932,49 +1041,23 @@ impl ChainSync { // known block case if known || self.is_already_downloading(&hash) { trace!(target: "sync", "Known block announce from {}: {}", who, hash); + if let Some(target) = self.fork_targets.get_mut(&hash) { + target.peers.insert(who); + } return OnBlockAnnounce::Nothing } - // stale block case - let requires_additional_data = !self.role.is_light(); - if number <= self.best_queued_number { - if !(known_parent || self.is_already_downloading(header.parent_hash())) { - let block_status = self.client.block_status(&BlockId::Number(*header.number())) - .unwrap_or(BlockStatus::Unknown); - if block_status == BlockStatus::InChainPruned { - trace!( - target: "sync", - "Ignored unknown ancient block announced from {}: {} {:?}", who, hash, header - ); - return OnBlockAnnounce::Nothing - } - trace!( - target: "sync", - "Considering new unknown stale block announced from {}: {} {:?}", who, hash, header - ); - if let Some(request) = self.download_unknown_stale(&who, &hash) { - if requires_additional_data { - return OnBlockAnnounce::Request(who, request) - } else { - return OnBlockAnnounce::ImportHeader - } - } else { - return OnBlockAnnounce::Nothing - } - } else { - if ancient_parent { - trace!(target: "sync", "Ignored ancient stale block announced from {}: {} {:?}", who, hash, header); - return OnBlockAnnounce::Nothing - } - if let Some(request) = self.download_stale(&who, &hash) { - if requires_additional_data { - return OnBlockAnnounce::Request(who, request) - } else { - return OnBlockAnnounce::ImportHeader - } - } else { - 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 } } @@ -983,22 +1066,28 @@ impl ChainSync { return OnBlockAnnounce::Nothing } - trace!(target: "sync", "Considering new block announced from {}: {} {:?}", who, hash, header); - - let (range, request) = match self.select_new_blocks(who.clone()) { - Some((range, request)) => (range, request), - None => return OnBlockAnnounce::Nothing - }; - - let is_required_data_available = !requires_additional_data - && range.end - range.start == One::one() - && range.start == *header.number(); + let requires_additional_data = !self.role.is_light() || !known_parent; + if !requires_additional_data { + trace!(target: "sync", "Importing new header announced from {}: {} {:?}", who, hash, header); + return OnBlockAnnounce::ImportHeader + } - if !is_required_data_available { - return OnBlockAnnounce::Request(who, request) + if number <= self.best_queued_number { + trace!( + target: "sync", + "Added sync target for block announced from {}: {} {:?}", who, hash, header + ); + self.fork_targets + .entry(hash.clone()) + .or_insert_with(|| ForkTarget { + number, + parent_hash: Some(header.parent_hash().clone()), + peers: Default::default(), + }) + .peers.insert(who); } - OnBlockAnnounce::ImportHeader + OnBlockAnnounce::Nothing } /// Call when a peer has disconnected. @@ -1034,40 +1123,6 @@ impl ChainSync { }) } - /// Download old block with known parent. - fn download_stale(&mut self, who: &PeerId, hash: &B::Hash) -> Option> { - let peer = self.peers.get_mut(who)?; - if !peer.state.is_available() { - return None - } - peer.state = PeerSyncState::DownloadingStale(*hash); - Some(message::generic::BlockRequest { - id: 0, - fields: self.required_block_attributes.clone(), - from: message::FromBlock::Hash(*hash), - to: None, - direction: message::Direction::Ascending, - max: Some(1), - }) - } - - /// Download old block with unknown parent. - fn download_unknown_stale(&mut self, who: &PeerId, hash: &B::Hash) -> Option> { - let peer = self.peers.get_mut(who)?; - if !peer.state.is_available() { - return None - } - peer.state = PeerSyncState::DownloadingStale(*hash); - Some(message::generic::BlockRequest { - id: 0, - fields: self.required_block_attributes.clone(), - from: message::FromBlock::Hash(*hash), - to: None, - direction: message::Direction::Descending, - max: Some(MAX_UNKNOWN_FORK_DOWNLOAD_LEN), - }) - } - /// Select a range of new blocks to download from the given peer. fn select_new_blocks(&mut self, who: PeerId) -> Option<(Range>, BlockRequest)> { // when there are too many blocks in the queue => do not try to download new blocks @@ -1214,3 +1269,38 @@ fn peer_block_request( None } } + +/// Get pending fork sync targets for a peer. +fn fork_sync_request( + id: &PeerId, + targets: &HashMap>, + best_num: NumberFor, + finalized: NumberFor, + attributes: &message::BlockAttributes, + check_block: impl Fn(&B::Hash) -> BlockStatus, +) -> Option<(B::Hash, BlockRequest)> +{ + for (hash, r) in targets { + if !r.peers.contains(id) { + continue + } + if r.number <= best_num { + trace!(target: "sync", "Downloading requested fork {:?} from {}", hash, id); + let parent_status = r.parent_hash.as_ref().map_or(BlockStatus::Unknown, check_block); + let mut count = (r.number - finalized).saturated_into::(); // up to the last finalized block + if parent_status != BlockStatus::Unknown { + // request only single block + count = 1; + } + 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(count), + })) + } + } + None +} diff --git a/core/network/src/protocol/sync/extra_requests.rs b/core/network/src/protocol/sync/extra_requests.rs index 9bc94d402cedaf9247770f5910a2e780d0a214b9..28ed5fed9f6829a7894f7cc18b7c578a6977ff2c 100644 --- a/core/network/src/protocol/sync/extra_requests.rs +++ b/core/network/src/protocol/sync/extra_requests.rs @@ -138,6 +138,9 @@ impl ExtraRequests { } 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, @@ -437,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 c3f773e232e7ae02459207b60503b91cb11ab3c4..48ad51bde31a63d03782bc89f1ad3fa03000d29a 100644 --- a/core/network/src/service.rs +++ b/core/network/src/service.rs @@ -42,7 +42,7 @@ use sr_primitives::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId}; use crate::{behaviour::{Behaviour, BehaviourOut}, config::{parse_str_addr, parse_addr}}; use crate::{NetworkState, NetworkStateNotConnectedPeer, NetworkStatePeer}; -use crate::{transport, config::NodeKeyConfig, config::NonReservedPeerMode}; +use crate::{transport, config::NonReservedPeerMode}; use crate::config::{Params, TransportConfig}; use crate::error::Error; use crate::protocol::{self, Protocol, Context, CustomMessageOutcome, PeerInfo}; @@ -52,21 +52,28 @@ use crate::protocol::specialization::NetworkSpecialization; use crate::protocol::sync::SyncState; /// Minimum Requirements for a Hash within Networking -pub trait ExHashT: - ::std::hash::Hash + Eq + ::std::fmt::Debug + Clone + Send + Sync + 'static -{ -} +pub trait ExHashT: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static {} + impl ExHashT for T where - T: ::std::hash::Hash + Eq + ::std::fmt::Debug + Clone + Send + Sync + 'static -{ -} + T: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static +{} /// Transaction pool interface 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 +84,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 +126,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 { @@ -138,6 +149,23 @@ impl, H: ExHashT> NetworkWorker } } + // Check for duplicate bootnodes. + known_addresses.iter() + .try_for_each(|(peer_id, addr)| + if let Some(other) = known_addresses + .iter() + .find(|o| o.1 == *addr && o.0 != *peer_id) + { + Err(Error::DuplicateBootnode { + address: addr.clone(), + first_id: peer_id.clone(), + second_id: other.0.clone(), + }) + } else { + Ok(()) + } + )?; + // Initialize the reserved peers. for reserved in params.network_config.reserved_nodes.iter() { if let Ok((peer_id, addr)) = parse_str_addr(reserved) { @@ -157,9 +185,6 @@ impl, H: ExHashT> NetworkWorker }; // Private and public keys configuration. - if let NodeKeyConfig::Secp256k1(_) = params.network_config.node_key { - warn!(target: "sub-libp2p", "Secp256k1 keys are deprecated in favour of ed25519"); - } let local_identity = params.network_config.node_key.clone().into_keypair()?; let local_public = local_identity.public(); let local_peer_id = local_public.clone().into_peer_id(); @@ -178,6 +203,7 @@ impl, H: ExHashT> NetworkWorker params.finality_proof_request_builder, params.protocol_id, peerset_config, + params.block_announce_validator )?; // Build the swarm. @@ -297,8 +323,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 +420,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 @@ -497,6 +523,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| { @@ -526,8 +564,9 @@ impl, H: ExHashT> NetworkServic } } -impl, H: ExHashT> - ::consensus::SyncOracle for NetworkService { +impl, H: ExHashT> consensus::SyncOracle + for NetworkService +{ fn is_major_syncing(&mut self) -> bool { NetworkService::is_major_syncing(self) } @@ -537,8 +576,9 @@ impl, H: ExHashT> } } -impl<'a, B: BlockT + 'static, S: NetworkSpecialization, H: ExHashT> - ::consensus::SyncOracle for &'a NetworkService { +impl<'a, B: BlockT + 'static, S: NetworkSpecialization, H: ExHashT> consensus::SyncOracle + for &'a NetworkService +{ fn is_major_syncing(&mut self) -> bool { NetworkService::is_major_syncing(self) } @@ -580,13 +620,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(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 +653,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 +677,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 +694,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 +706,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 +720,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..92e747280bbbbe90dafb2e603a6acbe18de6c73f 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, @@ -614,11 +704,13 @@ pub trait TestNetFactory: Sized { fn poll(&mut self) { self.mut_peers(|peers| { for peer in peers { + trace!(target: "sync", "-- Polling {}", peer.id()); peer.network.poll().unwrap(); + trace!(target: "sync", "-- Polling complete {}", peer.id()); // 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 +742,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 +788,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..b1b2b9d407262c7a32f25638120c4ec76aa14354 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. @@ -458,6 +457,17 @@ fn can_sync_small_non_best_forks() { } Ok(Async::Ready(())) })).unwrap(); + net.block_until_sync(&mut runtime); + + let another_fork = net.peer(0).push_blocks_at(BlockId::Number(35), 2, true); + net.peer(0).announce_block(another_fork, Vec::new()); + runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> { + net.poll(); + if net.peer(1).client().header(&BlockId::Hash(another_fork)).unwrap().is_none() { + return Ok(Async::NotReady) + } + Ok(Async::Ready(())) + })).unwrap(); } #[test] @@ -500,7 +510,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 +537,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..678d943c597cee3e7a71635c26fa65aab68ab83d 100644 --- a/core/offchain/Cargo.toml +++ b/core/offchain/Cargo.toml @@ -7,22 +7,32 @@ 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" +threadpool = "1.7" +num_cpus = "1.10" 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.7.0" 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..d4301d22ed7773898f3e801a393eeba37347ec39 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); - }, - } + info!("Submitting transaction to the pool: {:?} (isSigned: {:?})", xt, xt.is_signed()); + 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) => { warn!("Couldn't submit offchain 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..a335ca53807abc734a9017cfa7f844cbea58fec8 100644 --- a/core/offchain/src/lib.rs +++ b/core/offchain/src/lib.rs @@ -39,11 +39,13 @@ use std::{ sync::Arc, }; +use parking_lot::Mutex; +use threadpool::ThreadPool; 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}; @@ -58,6 +60,7 @@ pub struct OffchainWorkers { client: Arc, db: Storage, _block: PhantomData, + thread_pool: Mutex, } impl OffchainWorkers { @@ -67,6 +70,7 @@ impl OffchainWorkers OffchainWorkers< debug!("Spawning offchain workers at {:?}", at); let number = *number; let client = self.client.clone(); - spawn_worker(move || { + self.spawn_worker(move || { let runtime = client.runtime_api(); let api = Box::new(api); 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 { @@ -134,19 +138,18 @@ impl OffchainWorkers< futures::future::Either::Right(futures::future::ready(())) } } -} -/// Spawns a new offchain worker. -/// -/// We spawn offchain workers for each block in a separate thread, -/// since they can run for a significant amount of time -/// in a blocking fashion and we don't want to block the runtime. -/// -/// Note that we should avoid that if we switch to future-based runtime in the future, -/// alternatively: -/// TODO [ToDr] (#1458) we can consider using a thread pool instead. -fn spawn_worker(f: impl FnOnce() -> () + Send + 'static) { - std::thread::spawn(f); + /// Spawns a new offchain worker. + /// + /// We spawn offchain workers for each block in a separate thread, + /// since they can run for a significant amount of time + /// in a blocking fashion and we don't want to block the runtime. + /// + /// Note that we should avoid that if we switch to future-based runtime in the future, + /// alternatively: + fn spawn_worker(&self, f: impl FnOnce() -> () + Send + 'static) { + self.thread_pool.lock().execute(f); + } } #[cfg(test)] @@ -171,7 +174,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 1bd9d3f17ba60962f33be728fdc5f0e7b136b069..96b721b41caf0054c817555e65ed9b7855b1073e 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" +futures-preview = "0.3.0-alpha.19" libp2p = { version = "0.12.0", default-features = false } -linked-hash-map = "0.5" -log = "0.4" +linked-hash-map = "0.5.2" +log = "0.4.8" lru-cache = "0.1.2" -serde_json = "1.0.24" +serde_json = "1.0.41" [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..7377bac2f802ad4bc12a6905601523b54466a9ec --- /dev/null +++ b/core/phragmen/src/lib.rs @@ -0,0 +1,509 @@ +// 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::RuntimeDebug; +use sr_primitives::{helpers_128bit::multiply_by_rational, Perbill, Rational128}; +use sr_primitives::traits::{Zero, Convert, Member, SimpleArithmetic, Saturating, Bounded}; + +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, RuntimeDebug)] +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, RuntimeDebug)] +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, RuntimeDebug)] +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. +#[derive(RuntimeDebug)] +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, RuntimeDebug)] +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( + n.load.n(), + n.budget, + c.approval_stake, + ).unwrap_or(Bounded::max_value()); + 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( + desired_scale, + e.load.n(), + n.load.n(), + ).unwrap_or(Bounded::max_value()) + } 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 b9bb141ad76164e318e0cc5c49216405aeb67a0e..bc8106de3ab35423343be690c9a4a8bb416836a4 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -7,36 +7,42 @@ 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 } +rustc-hex = { version = "2.0.1", default-features = false } +log = { version = "0.4.8", 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 } +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 = "1.0.0-pre.1", optional = true } -base58 = { version = "0.1", optional = true } +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 } +libsecp256k1 = { version = "0.3.0", optional = true } +tiny-keccak = { version = "1.5.0", optional = true } +substrate-debug-derive = { version = "2.0.0", path = "./debug-derive" } +externalities = { package = "substrate-externalities", path = "../externalities", optional = true } +primitives-storage = { package = "substrate-primitives-storage", path = "storage", default-features = false } [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,9 +54,10 @@ bench = false [features] default = ["std"] std = [ + "log/std", "wasmi", "lazy_static", - "parking_lot", + "parking_lot", "primitive-types/std", "primitive-types/serde", "primitive-types/byteorder", @@ -77,5 +84,9 @@ std = [ "schnorrkel", "regex", "num-traits/std", - "zeroize/std" + "libsecp256k1", + "tiny-keccak", + "substrate-debug-derive/std", + "externalities", + "primitives-storage/std", ] diff --git a/core/primitives/debug-derive/Cargo.toml b/core/primitives/debug-derive/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..9c7b7aa1bad4908e5949e3f9ed667b153cdd62d7 --- /dev/null +++ b/core/primitives/debug-derive/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "substrate-debug-derive" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0.2" +syn = "1.0.5" +proc-macro2 = "1.0" + +[features] +std = [] + +[dev-dependencies] + diff --git a/core/primitives/debug-derive/src/impls.rs b/core/primitives/debug-derive/src/impls.rs new file mode 100644 index 0000000000000000000000000000000000000000..decceca044c1b5ac9fda8d749b720db79ddd0382 --- /dev/null +++ b/core/primitives/debug-derive/src/impls.rs @@ -0,0 +1,217 @@ +// 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 quote::quote; +use proc_macro2::TokenStream; +use syn::{Data, DeriveInput, parse_quote}; + +pub fn debug_derive(ast: DeriveInput) -> proc_macro::TokenStream { + let name_str = ast.ident.to_string(); + let implementation = implementation::derive(&name_str, &ast.data); + let name = &ast.ident; + let mut generics = ast.generics.clone(); + let (impl_generics, ty_generics, where_clause) = { + let wh = generics.make_where_clause(); + for t in ast.generics.type_params() { + let name = &t.ident; + wh.predicates.push(parse_quote!{ #name : core::fmt::Debug }); + } + generics.split_for_impl() + }; + let gen = quote!{ + impl #impl_generics core::fmt::Debug for #name #ty_generics #where_clause { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + #implementation + } + } + }; + + gen.into() +} + +#[cfg(not(feature = "std"))] +mod implementation { + use super::*; + + /// Derive the inner implementation of `Debug::fmt` function. + /// + /// Non-std environment. We do nothing to prevent bloating the size of runtime. + /// Implement `Printable` if you need to print the details. + pub fn derive(_name_str: &str, _data: &Data) -> TokenStream { + quote! { + fmt.write_str("") + } + } +} + +#[cfg(feature = "std")] +mod implementation { + use super::*; + use proc_macro2::Span; + use syn::{Ident, Index, token::SelfValue}; + + /// Derive the inner implementation of `Debug::fmt` function. + pub fn derive(name_str: &str, data: &Data) -> TokenStream { + match *data { + Data::Struct(ref s) => derive_struct(&name_str, &s.fields), + Data::Union(ref u) => derive_fields(&name_str, Fields::new(u.fields.named.iter(), None)), + Data::Enum(ref e) => derive_enum(&name_str, &e), + } + } + + enum Fields { + Indexed { + indices: Vec, + }, + Unnamed { + vars: Vec, + }, + Named { + names: Vec, + this: Option, + }, + } + + impl Fields { + fn new<'a>(fields: impl Iterator, this: Option) -> Self { + let mut indices = vec![]; + let mut names = vec![]; + + for (i, f) in fields.enumerate() { + if let Some(ident) = f.ident.clone() { + names.push(ident); + } else { + indices.push(Index::from(i)); + } + } + + if names.is_empty() { + Self::Indexed { + indices, + } + } else { + Self::Named { + names, + this, + } + } + } + } + + fn derive_fields<'a>( + name_str: &str, + fields: Fields, + ) -> TokenStream { + match fields { + Fields::Named { names, this } => { + let names_str: Vec<_> = names.iter() + .map(|x| x.to_string()) + .collect(); + + let fields = match this { + None => quote! { #( .field(#names_str, #names) )* }, + Some(this) => quote! { #( .field(#names_str, &#this.#names) )* }, + }; + + quote! { + fmt.debug_struct(#name_str) + #fields + .finish() + } + + }, + Fields::Indexed { indices } => { + quote! { + fmt.debug_tuple(#name_str) + #( .field(&self.#indices) )* + .finish() + } + }, + Fields::Unnamed { vars } => { + quote! { + fmt.debug_tuple(#name_str) + #( .field(#vars) )* + .finish() + } + }, + } + } + + fn derive_enum( + name: &str, + e: &syn::DataEnum, + ) -> TokenStream { + let v = e.variants + .iter() + .map(|v| { + let name = format!("{}::{}", name, v.ident); + let ident = &v.ident; + match v.fields { + syn::Fields::Named(ref f) => { + let names: Vec<_> = f.named.iter().flat_map(|f| f.ident.clone()).collect(); + let fields_impl = derive_fields(&name, Fields::Named { + names: names.clone(), + this: None, + }); + (ident, (quote!{ { #( ref #names ),* } }, fields_impl)) + }, + syn::Fields::Unnamed(ref f) => { + let names = f.unnamed.iter() + .enumerate() + .map(|(id, _)| Ident::new(&format!("a{}", id), Span::call_site())) + .collect::>(); + let fields_impl = derive_fields(&name, Fields::Unnamed { vars: names.clone() }); + (ident, (quote! { ( #( ref #names ),* ) }, fields_impl)) + }, + syn::Fields::Unit => { + let fields_impl = derive_fields(&name, Fields::Indexed { indices: vec![] }); + (ident, (quote! { }, fields_impl)) + }, + } + }); + + type Vecs = (Vec, Vec); + let (variants, others): Vecs<_, _> = v.unzip(); + let (match_fields, variants_impl): Vecs<_, _> = others.into_iter().unzip(); + + quote! { + match self { + #( Self::#variants #match_fields => #variants_impl, )* + _ => Ok(()), + } + } + } + + fn derive_struct( + name_str: &str, + fields: &syn::Fields, + ) -> TokenStream { + match *fields { + syn::Fields::Named(ref f) => derive_fields( + name_str, + Fields::new(f.named.iter(), Some(syn::Token!(self)(Span::call_site()))), + ), + syn::Fields::Unnamed(ref f) => derive_fields( + name_str, + Fields::new(f.unnamed.iter(), None), + ), + syn::Fields::Unit => derive_fields( + name_str, + Fields::Indexed { indices: vec![] }, + ), + } + } +} diff --git a/core/primitives/debug-derive/src/lib.rs b/core/primitives/debug-derive/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..5e6cf6098b30e4f0b69c7a3dd4c1a26b86e0832d --- /dev/null +++ b/core/primitives/debug-derive/src/lib.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 . + +//! Macros to derive runtime debug implementation. +//! +//! This custom derive implements a `core::fmt::Debug` trait, +//! but in case the `std` feature is enabled the implementation +//! will actually print out the structure as regular `derive(Debug)` +//! would do. If `std` is disabled the implementation will be empty. +//! +//! This behaviour is useful to prevent bloating the runtime WASM +//! blob from unneeded code. +//! +//! ```rust +//! #[derive(substrate_debug_derive::RuntimeDebug)] +//! struct MyStruct; +//! +//! assert_eq!(format!("{:?}", MyStruct), "MyStruct"); +//! ``` + +extern crate proc_macro; + +mod impls; + +use proc_macro::TokenStream; + +#[proc_macro_derive(RuntimeDebug)] +pub fn debug_derive(input: TokenStream) -> TokenStream { + impls::debug_derive(syn::parse_macro_input!(input)) +} + diff --git a/core/primitives/debug-derive/tests/tests.rs b/core/primitives/debug-derive/tests/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..63ad6a3e8d49718f8db818ee9cb4cd3370a9a8c6 --- /dev/null +++ b/core/primitives/debug-derive/tests/tests.rs @@ -0,0 +1,63 @@ +// 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 substrate_debug_derive::RuntimeDebug; + +#[derive(RuntimeDebug)] +struct Unnamed(u64, String); + +#[derive(RuntimeDebug)] +struct Named { + a: u64, + b: String, +} + +#[derive(RuntimeDebug)] +enum EnumLongName { + A, + B(A, String), + VariantLongName { + a: A, + b: String, + }, +} + + +#[test] +fn should_display_proper_debug() { + use self::EnumLongName as Enum; + + assert_eq!( + format!("{:?}", Unnamed(1, "abc".into())), + "Unnamed(1, \"abc\")" + ); + assert_eq!( + format!("{:?}", Named { a: 1, b: "abc".into() }), + "Named { a: 1, b: \"abc\" }" + ); + assert_eq!( + format!("{:?}", Enum::::A), + "EnumLongName::A" + ); + assert_eq!( + format!("{:?}", Enum::B(1, "abc".into())), + "EnumLongName::B(1, \"abc\")" + ); + assert_eq!( + format!("{:?}", Enum::VariantLongName { a: 1, b: "abc".into() }), + "EnumLongName::VariantLongName { a: 1, b: \"abc\" }" + ); +} 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/crypto.rs b/core/primitives/src/crypto.rs index 0adf50e1602f3ca40e7b222c11c52125d614f38b..6e46793432db8e21cb1133f164f64217744eef0d 100644 --- a/core/primitives/src/crypto.rs +++ b/core/primitives/src/crypto.rs @@ -43,7 +43,7 @@ pub const DEV_PHRASE: &str = "bottom drive obey lake curtain smoke basket hold r pub const DEV_ADDRESS: &str = "5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV"; /// The infallible type. -#[derive(Debug)] +#[derive(crate::RuntimeDebug)] pub enum Infallible {} /// The length of the junction identifier. Note that this is also referred to as the @@ -255,31 +255,59 @@ pub enum PublicError { /// Key that can be encoded to/from SS58. #[cfg(feature = "std")] -pub trait Ss58Codec: Sized { +pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default { /// Some if the string is a properly encoded SS58Check address. fn from_ss58check(s: &str) -> Result { 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), }) } /// Some if the string is a properly encoded SS58Check address. - fn from_ss58check_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError>; + fn from_ss58check_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> { + let mut res = Self::default(); + let len = res.as_mut().len(); + let d = s.from_base58().map_err(|_| PublicError::BadBase58)?; // failure here would be invalid encoding. + if d.len() != len + 3 { + // Invalid length. + return Err(PublicError::BadLength); + } + let ver = d[0].try_into().map_err(|_: ()| PublicError::UnknownVersion)?; + + if d[len + 1..len + 3] != ss58hash(&d[0..len + 1]).as_bytes()[0..2] { + // Invalid checksum. + return Err(PublicError::InvalidChecksum); + } + res.as_mut().copy_from_slice(&d[1..len + 1]); + Ok((res, ver)) + } /// Some if the string is a properly encoded SS58Check address, optionally with /// a derivation path following. fn from_string(s: &str) -> Result { 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), }) } /// Return the ss58-check string for this key. - fn to_ss58check_with_version(&self, version: Ss58AddressFormat) -> String; + fn to_ss58check_with_version(&self, version: Ss58AddressFormat) -> String { + let mut v = vec![version.into()]; + v.extend(self.as_ref()); + let r = ss58hash(&v); + v.extend(&r.as_bytes()[0..2]); + v.to_base58() + } /// Return the ss58-check string for this key. fn to_ss58check(&self) -> String { self.to_ss58check_with_version(*DEFAULT_VERSION.lock()) } /// Some if the string is a properly encoded SS58Check address, optionally with @@ -327,6 +355,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 +368,7 @@ impl From for u8 { Ss58AddressFormat::SubstrateAccountDirect => 42, Ss58AddressFormat::PolkadotAccountDirect => 0, Ss58AddressFormat::KusamaAccountDirect => 2, + Ss58AddressFormat::DothereumAccountDirect => 20, Ss58AddressFormat::Custom(n) => n, } } @@ -351,6 +382,7 @@ impl TryFrom for Ss58AddressFormat { 42 => Ok(Ss58AddressFormat::SubstrateAccountDirect), 0 => Ok(Ss58AddressFormat::PolkadotAccountDirect), 2 => Ok(Ss58AddressFormat::KusamaAccountDirect), + 20 => Ok(Ss58AddressFormat::DothereumAccountDirect), _ => Err(()), } } @@ -364,6 +396,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 +409,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 +421,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) { @@ -395,44 +430,28 @@ pub fn set_default_ss58_version(version: Ss58AddressFormat) { } #[cfg(feature = "std")] -impl + AsRef<[u8]> + Default + Derive> Ss58Codec for T { - fn from_ss58check_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> { - let mut res = T::default(); - let len = res.as_mut().len(); - let d = s.from_base58().map_err(|_| PublicError::BadBase58)?; // failure here would be invalid encoding. - if d.len() != len + 3 { - // Invalid length. - return Err(PublicError::BadLength); - } - let ver = d[0].try_into().map_err(|_: ()| PublicError::UnknownVersion)?; - - if d[len+1..len+3] != ss58hash(&d[0..len+1]).as_bytes()[0..2] { - // Invalid checksum. - return Err(PublicError::InvalidChecksum); - } - res.as_mut().copy_from_slice(&d[1..len+1]); - Ok((res, ver)) - } - - fn to_ss58check_with_version(&self, version: Ss58AddressFormat) -> String { - let mut v = vec![version.into()]; - v.extend(self.as_ref()); - let r = ss58hash(&v); - v.extend(&r.as_bytes()[0..2]); - v.to_base58() - } - +impl + AsRef<[u8]> + Default + Derive> Ss58Codec for T { fn from_string(s: &str) -> Result { - let re = Regex::new(r"^(?P[\w\d]+)?(?P(//?[^/]+)*)$") + let re = Regex::new(r"^(?P[\w\d ]+)?(?P(//?[^/]+)*)$") .expect("constructed from known-good static value; qed"); let cap = re.captures(s).ok_or(PublicError::InvalidFormat)?; let re_junction = Regex::new(r"/(/?[^/]+)") .expect("constructed from known-good static value; qed"); - let addr = Self::from_ss58check( - cap.name("ss58") - .map(|r| r.as_str()) - .unwrap_or(DEV_ADDRESS) - )?; + let s = cap.name("ss58") + .map(|r| r.as_str()) + .unwrap_or(DEV_ADDRESS); + let addr = if s.starts_with("0x") { + let d = hex::decode(&s[2..]).map_err(|_| PublicError::InvalidFormat)?; + let mut r = Self::default(); + if d.len() == r.as_ref().len() { + r.as_mut().copy_from_slice(&d); + r + } else { + Err(PublicError::BadLength)? + } + } else { + Self::from_ss58check(s)? + }; if cap["path"].is_empty() { Ok(addr) } else { @@ -444,7 +463,7 @@ impl + AsRef<[u8]> + Default + Derive> Ss58Codec for T { } fn from_string_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> { - let re = Regex::new(r"^(?P[\w\d]+)?(?P(//?[^/]+)*)$") + let re = Regex::new(r"^(?P[\w\d ]+)?(?P(//?[^/]+)*)$") .expect("constructed from known-good static value; qed"); let cap = re.captures(s).ok_or(PublicError::InvalidFormat)?; let re_junction = Regex::new(r"/(/?[^/]+)") @@ -482,6 +501,103 @@ pub trait Public: AsRef<[u8]> + AsMut<[u8]> + Default + Derive + CryptoType + Pa fn as_slice(&self) -> &[u8] { self.as_ref() } } +/// An opaque 32-byte cryptographic identifier. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Default, Encode, Decode)] +pub struct AccountId32([u8; 32]); + +impl UncheckedFrom for AccountId32 { + fn unchecked_from(h: crate::hash::H256) -> Self { + AccountId32(h.into()) + } +} + +#[cfg(feature = "std")] +impl Ss58Codec for AccountId32 {} + +impl AsRef<[u8]> for AccountId32 { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for AccountId32 { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +impl AsRef<[u8; 32]> for AccountId32 { + fn as_ref(&self) -> &[u8; 32] { + &self.0 + } +} + +impl AsMut<[u8; 32]> for AccountId32 { + fn as_mut(&mut self) -> &mut [u8; 32] { + &mut self.0 + } +} + +impl From<[u8; 32]> for AccountId32 { + fn from(x: [u8; 32]) -> AccountId32 { + AccountId32(x) + } +} + +impl<'a> rstd::convert::TryFrom<&'a [u8]> for AccountId32 { + type Error = (); + fn try_from(x: &'a [u8]) -> Result { + if x.len() == 32 { + let mut r = AccountId32::default(); + r.0.copy_from_slice(x); + Ok(r) + } else { + Err(()) + } + } +} + +impl From for [u8; 32] { + fn from(x: AccountId32) -> [u8; 32] { + x.0 + } +} + +#[cfg(feature = "std")] +impl std::fmt::Display for AccountId32 { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_ss58check()) + } +} + +impl rstd::fmt::Debug for AccountId32 { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + let s = self.to_ss58check(); + write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } +} + +#[cfg(feature = "std")] +impl serde::Serialize for AccountId32 { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + serializer.serialize_str(&self.to_ss58check()) + } +} + +#[cfg(feature = "std")] +impl<'de> serde::Deserialize<'de> for AccountId32 { + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { + Ss58Codec::from_ss58check(&String::deserialize(deserializer)?) + .map_err(|e| serde::de::Error::custom(format!("{:?}", e))) + } +} + #[cfg(feature = "std")] pub use self::dummy::*; @@ -531,17 +647,10 @@ mod dummy { Ok(Default::default()) } fn derive< - Iter: Iterator - >(&self, _: Iter) -> Result { Ok(Self) } + Iter: Iterator, + >(&self, _: Iter, _: Option) -> Result<(Self, Option), Self::DeriveError> { Ok((Self, None)) } fn from_seed(_: &Self::Seed) -> Self { Self } fn from_seed_slice(_: &[u8]) -> Result { Ok(Self) } - fn from_standard_components< - I: Iterator - >( - _: &str, - _: Option<&str>, - _: I - ) -> Result { Ok(Self) } fn sign(&self, _: &[u8]) -> Self::Signature { Self } fn verify>(_: &Self::Signature, _: M, _: &Self::Public) -> bool { true } fn verify_weak, M: AsRef<[u8]>>(_: &[u8], _: M, _: P) -> bool { true } @@ -574,9 +683,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) } @@ -592,7 +700,10 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static { fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Self, Self::Seed), SecretStringError>; /// Derive a child key from a series of given junctions. - fn derive>(&self, path: Iter) -> Result; + fn derive>(&self, + path: Iter, + seed: Option, + ) -> Result<(Self, Option), Self::DeriveError>; /// Generate new key pair from the provided `seed`. /// @@ -607,11 +718,6 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static { /// by an attacker then they can also derive your key. fn from_seed_slice(seed: &[u8]) -> Result; - /// Construct a key from a phrase, password and path. - fn from_standard_components< - I: Iterator - >(phrase: &str, password: Option<&str>, path: I) -> Result; - /// Sign a message. fn sign(&self, message: &[u8]) -> Self::Signature; @@ -624,7 +730,9 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static { /// Get the public key. fn public(&self) -> Self::Public; - /// Interprets the string `s` in order to generate a key Pair. + /// Interprets the string `s` in order to generate a key Pair. Returns both the pair and an optional seed, in the + /// case that the pair can be expressed as a direct derivation from a seed (some cases, such as Sr25519 derivations + /// with path components, cannot). /// /// This takes a helper function to do the key generation from a phrase, password and /// junction iterator. @@ -650,31 +758,43 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static { /// be equivalent to no password at all. /// /// `None` is returned if no matches are found. - fn from_string(s: &str, password_override: Option<&str>) -> Result { - let hex_seed = if s.starts_with("0x") { - &s[2..] - } else { - s - }; - - if let Ok(d) = hex::decode(hex_seed) { - if let Ok(r) = Self::from_seed_slice(&d) { - return Ok(r) - } - } - - let re = Regex::new(r"^(?P\w+( \w+)*)?(?P(//?[^/]+)*)(///(?P.*))?$") + fn from_string_with_seed(s: &str, password_override: Option<&str>) -> Result<(Self, Option), SecretStringError> { + let re = Regex::new(r"^(?P[\d\w ]+)?(?P(//?[^/]+)*)(///(?P.*))?$") .expect("constructed from known-good static value; qed"); let cap = re.captures(s).ok_or(SecretStringError::InvalidFormat)?; + let re_junction = Regex::new(r"/(/?[^/]+)") .expect("constructed from known-good static value; qed"); let path = re_junction.captures_iter(&cap["path"]) .map(|f| DeriveJunction::from(&f[1])); - Self::from_standard_components( - cap.name("phrase").map(|r| r.as_str()).unwrap_or(DEV_PHRASE), - password_override.or_else(|| cap.name("password").map(|m| m.as_str())), - path, - ) + + let phrase = cap.name("phrase").map(|r| r.as_str()).unwrap_or(DEV_PHRASE); + let password = password_override.or_else(|| cap.name("password").map(|m| m.as_str())); + + let (root, seed) = if phrase.starts_with("0x") { + hex::decode(&phrase[2..]).ok() + .and_then(|seed_vec| { + let mut seed = Self::Seed::default(); + if seed.as_ref().len() == seed_vec.len() { + seed.as_mut().copy_from_slice(&seed_vec); + Some((Self::from_seed(&seed), seed)) + } else { + None + } + }) + .ok_or(SecretStringError::InvalidSeed)? + } else { + Self::from_phrase(phrase, password) + .map_err(|_| SecretStringError::InvalidPhrase)? + }; + root.derive(path, Some(seed)).map_err(|_| SecretStringError::InvalidPath) + } + + /// Interprets the string `s` in order to generate a key pair. + /// + /// See [`from_string_with_seed`](Self::from_string_with_seed) for more extensive documentation. + fn from_string(s: &str, password_override: Option<&str>) -> Result { + Self::from_string_with_seed(s, password_override).map(|x| x.0) } /// Return a vec filled with raw data. @@ -731,7 +851,7 @@ pub trait CryptoType { /// Values whose first character is `_` are reserved for private use and won't conflict with any /// public modules. #[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(crate::RuntimeDebug)] pub struct KeyTypeId(pub [u8; 4]); impl From for KeyTypeId { @@ -767,10 +887,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. @@ -838,13 +954,13 @@ mod tests { } impl Pair for TestPair { type Public = TestPublic; - type Seed = [u8; 0]; + type Seed = [u8; 8]; type Signature = [u8; 0]; type DeriveError = (); - fn generate() -> (Self, ::Seed) { (TestPair::Generated, []) } + fn generate() -> (Self, ::Seed) { (TestPair::Generated, [0u8; 8]) } fn generate_with_phrase(_password: Option<&str>) -> (Self, String, ::Seed) { - (TestPair::GeneratedWithPhrase, "".into(), []) + (TestPair::GeneratedWithPhrase, "".into(), [0u8; 8]) } fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Self, ::Seed), SecretStringError> @@ -852,14 +968,20 @@ mod tests { Ok((TestPair::GeneratedFromPhrase { phrase: phrase.to_owned(), password: password.map(Into::into) - }, [])) + }, [0u8; 8])) } - fn derive>(&self, _path: Iter) - -> Result + fn derive>(&self, path_iter: Iter, _: Option<[u8; 8]>) + -> Result<(Self, Option<[u8; 8]>), Self::DeriveError> { - Err(()) + Ok((match self.clone() { + TestPair::Standard {phrase, password, path} => + TestPair::Standard { phrase, password, path: path.into_iter().chain(path_iter).collect() }, + TestPair::GeneratedFromPhrase {phrase, password} => + TestPair::Standard { phrase, password, path: path_iter.collect() }, + x => if path_iter.count() == 0 { x } else { return Err(()) }, + }, None)) } - fn from_seed(_seed: &::Seed) -> Self { TestPair::Seed(vec![]) } + fn from_seed(_seed: &::Seed) -> Self { TestPair::Seed(_seed.as_ref().to_owned()) } fn sign(&self, _message: &[u8]) -> Self::Signature { [] } fn verify>(_: &Self::Signature, _: M, _: &Self::Public) -> bool { true } fn verify_weak, M: AsRef<[u8]>>( @@ -868,17 +990,6 @@ mod tests { _pubkey: P ) -> bool { true } fn public(&self) -> Self::Public { TestPublic } - fn from_standard_components>( - phrase: &str, - password: Option<&str>, - path: I - ) -> Result { - Ok(TestPair::Standard { - phrase: phrase.to_owned(), - password: password.map(ToOwned::to_owned), - path: path.collect() - }) - } fn from_seed_slice(seed: &[u8]) -> Result { @@ -895,10 +1006,6 @@ mod tests { TestPair::from_string("0x0123456789abcdef", None), Ok(TestPair::Seed(hex!["0123456789abcdef"][..].to_owned())) ); - assert_eq!( - TestPair::from_string("0123456789abcdef", None), - Ok(TestPair::Seed(hex!["0123456789abcdef"][..].to_owned())) - ); } #[test] diff --git a/core/primitives/src/ecdsa.rs b/core/primitives/src/ecdsa.rs new file mode 100644 index 0000000000000000000000000000000000000000..abff460c91034613c982b46b7d16d33d6113404d --- /dev/null +++ b/core/primitives/src/ecdsa.rs @@ -0,0 +1,608 @@ +// 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 . + +// tag::description[] +//! Simple ECDSA API. +// end::description[] + +use rstd::cmp::Ordering; +use codec::{Encode, Decode}; + +#[cfg(feature = "std")] +use std::convert::{TryFrom, TryInto}; +#[cfg(feature = "std")] +use substrate_bip39::seed_from_entropy; +#[cfg(feature = "std")] +use bip39::{Mnemonic, Language, MnemonicType}; +#[cfg(feature = "std")] +use crate::{hashing::blake2_256, crypto::{Pair as TraitPair, DeriveJunction, SecretStringError, Ss58Codec}}; +#[cfg(feature = "std")] +use serde::{de, Serializer, Serialize, Deserializer, Deserialize}; +use crate::crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}; +#[cfg(feature = "std")] +use secp256k1::{PublicKey, SecretKey}; + +/// A secret seed (which is bytewise essentially equivalent to a SecretKey). +/// +/// We need it as a different type because `Seed` is expected to be AsRef<[u8]>. +#[cfg(feature = "std")] +type Seed = [u8; 32]; + +/// The ECDSA 33-byte compressed public key. +#[derive(Clone, Encode, Decode)] +pub struct Public(pub [u8; 33]); + +impl PartialOrd for Public { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Public { + fn cmp(&self, other: &Self) -> Ordering { + self.0[..].cmp(&other.0[..]) + } +} + +impl PartialEq for Public { + fn eq(&self, other: &Self) -> bool { + &self.0[..] == &other.0[..] + } +} + +impl Eq for Public {} + +impl Default for Public { + fn default() -> Self { + Public([0u8; 33]) + } +} + +/// A key pair. +#[cfg(feature = "std")] +#[derive(Clone)] +pub struct Pair { + public: PublicKey, + secret: SecretKey, +} + +impl AsRef<[u8; 33]> for Public { + fn as_ref(&self) -> &[u8; 33] { + &self.0 + } +} + +impl AsRef<[u8]> for Public { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for Public { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +impl rstd::convert::TryFrom<&[u8]> for Public { + type Error = (); + + fn try_from(data: &[u8]) -> Result { + if data.len() == 33 { + let mut inner = [0u8; 33]; + inner.copy_from_slice(data); + Ok(Public(inner)) + } else { + Err(()) + } + } +} + +impl From for [u8; 33] { + fn from(x: Public) -> Self { + x.0 + } +} + +#[cfg(feature = "std")] +impl From for Public { + fn from(x: Pair) -> Self { + x.public() + } +} + +impl UncheckedFrom<[u8; 33]> for Public { + fn unchecked_from(x: [u8; 33]) -> Self { + Public(x) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Display for Public { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_ss58check()) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Debug for Public { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let s = self.to_ss58check(); + write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&&self.0[..]), &s[0..8]) + } +} + +#[cfg(feature = "std")] +impl Serialize for Public { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + serializer.serialize_str(&self.to_ss58check()) + } +} + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for Public { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { + Public::from_ss58check(&String::deserialize(deserializer)?) + .map_err(|e| de::Error::custom(format!("{:?}", e))) + } +} + +#[cfg(feature = "std")] +impl std::hash::Hash for Public { + fn hash(&self, state: &mut H) { + self.0.hash(state); + } +} + +/// A signature (a 512-bit value). +#[derive(Encode, Decode)] +pub struct Signature([u8; 65]); + +impl rstd::convert::TryFrom<&[u8]> for Signature { + type Error = (); + + fn try_from(data: &[u8]) -> Result { + if data.len() == 65 { + let mut inner = [0u8; 65]; + inner.copy_from_slice(data); + Ok(Signature(inner)) + } else { + Err(()) + } + } +} + +impl Clone for Signature { + fn clone(&self) -> Self { + let mut r = [0u8; 65]; + r.copy_from_slice(&self.0[..]); + Signature(r) + } +} + +impl Default for Signature { + fn default() -> Self { + Signature([0u8; 65]) + } +} + +impl PartialEq for Signature { + fn eq(&self, b: &Self) -> bool { + self.0[..] == b.0[..] + } +} + +impl Eq for Signature {} + +impl From for [u8; 65] { + fn from(v: Signature) -> [u8; 65] { + v.0 + } +} + +impl AsRef<[u8; 65]> for Signature { + fn as_ref(&self) -> &[u8; 65] { + &self.0 + } +} + +impl AsRef<[u8]> for Signature { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for Signature { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +#[cfg(feature = "std")] +impl std::fmt::Debug for Signature { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) + } +} + +#[cfg(feature = "std")] +impl std::hash::Hash for Signature { + fn hash(&self, state: &mut H) { + std::hash::Hash::hash(&self.0[..], state); + } +} + +impl Signature { + /// A new instance from the given 65-byte `data`. + /// + /// NOTE: No checking goes on to ensure this is a real signature. Only use it if + /// you are certain that the array actually is a signature. GIGO! + pub fn from_raw(data: [u8; 65]) -> Signature { + Signature(data) + } + + /// Recover the public key from this signature and a message. + #[cfg(feature = "std")] + pub fn recover>(&self, message: M) -> Option { + let message = secp256k1::Message::parse(&blake2_256(message.as_ref())); + let sig: (_, _) = self.try_into().ok()?; + secp256k1::recover(&message, &sig.0, &sig.1).ok() + .map(|recovered| Public(recovered.serialize_compressed())) + } +} + +#[cfg(feature = "std")] +impl From<(secp256k1::Signature, secp256k1::RecoveryId)> for Signature { + fn from(x: (secp256k1::Signature, secp256k1::RecoveryId)) -> Signature { + let mut r = Self::default(); + r.0[0..64].copy_from_slice(&x.0.serialize()[..]); + r.0[64] = x.1.serialize(); + r + } +} + +#[cfg(feature = "std")] +impl<'a> TryFrom<&'a Signature> for (secp256k1::Signature, secp256k1::RecoveryId) { + type Error = (); + fn try_from(x: &'a Signature) -> Result<(secp256k1::Signature, secp256k1::RecoveryId), Self::Error> { + Ok(( + secp256k1::Signature::parse_slice(&x.0[0..64]).expect("hardcoded to 64 bytes; qed"), + secp256k1::RecoveryId::parse(x.0[64]).map_err(|_| ())?, + )) + } +} + +/// An error type for SS58 decoding. +#[cfg(feature = "std")] +#[derive(Clone, Copy, Eq, PartialEq, Debug)] +pub enum PublicError { + /// Bad alphabet. + BadBase58, + /// Bad length. + BadLength, + /// Unknown version. + UnknownVersion, + /// Invalid checksum. + InvalidChecksum, +} + +impl Public { + /// A new instance from the given 33-byte `data`. + /// + /// NOTE: No checking goes on to ensure this is a real public key. Only use it if + /// you are certain that the array actually is a pubkey. GIGO! + pub fn from_raw(data: [u8; 33]) -> Self { + Public(data) + } + + /// Return a slice filled with raw data. + pub fn as_array_ref(&self) -> &[u8; 33] { + self.as_ref() + } +} + +impl TraitPublic for Public { + /// A new instance from the given slice that should be 33 bytes long. + /// + /// NOTE: No checking goes on to ensure this is a real public key. Only use it if + /// you are certain that the array actually is a pubkey. GIGO! + fn from_slice(data: &[u8]) -> Self { + let mut r = [0u8; 33]; + r.copy_from_slice(data); + Public(r) + } +} + +impl Derive for Public {} + +/// Derive a single hard junction. +#[cfg(feature = "std")] +fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed { + ("Secp256k1HDKD", secret_seed, cc).using_encoded(|data| { + let mut res = [0u8; 32]; + res.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], data).as_bytes()); + res + }) +} + +/// An error when deriving a key. +#[cfg(feature = "std")] +pub enum DeriveError { + /// A soft key was found in the path (and is unsupported). + SoftKeyInPath, +} + +#[cfg(feature = "std")] +impl TraitPair for Pair { + type Public = Public; + type Seed = Seed; + type Signature = Signature; + type DeriveError = DeriveError; + + /// Generate new secure (random) key pair and provide the recovery phrase. + /// + /// You can recover the same key later with `from_phrase`. + fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) { + let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); + let phrase = mnemonic.phrase(); + let (pair, seed) = Self::from_phrase(phrase, password) + .expect("All phrases generated by Mnemonic are valid; qed"); + ( + pair, + phrase.to_owned(), + seed, + ) + } + + /// Generate key pair from given recovery phrase and password. + fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> { + let big_seed = seed_from_entropy( + Mnemonic::from_phrase(phrase, Language::English) + .map_err(|_| SecretStringError::InvalidPhrase)?.entropy(), + password.unwrap_or(""), + ).map_err(|_| SecretStringError::InvalidSeed)?; + let mut seed = Seed::default(); + seed.copy_from_slice(&big_seed[0..32]); + Self::from_seed_slice(&big_seed[0..32]).map(|x| (x, seed)) + } + + /// Make a new key pair from secret seed material. + /// + /// You should never need to use this; generate(), generate_with_phrase + fn from_seed(seed: &Seed) -> Pair { + Self::from_seed_slice(&seed[..]).expect("seed has valid length; qed") + } + + /// Make a new key pair from secret seed material. The slice must be 32 bytes long or it + /// will return `None`. + /// + /// You should never need to use this; generate(), generate_with_phrase + fn from_seed_slice(seed_slice: &[u8]) -> Result { + let secret = SecretKey::parse_slice(seed_slice) + .map_err(|_| SecretStringError::InvalidSeedLength)?; + let public = PublicKey::from_secret_key(&secret); + Ok(Pair{ secret, public }) + } + + /// Derive a child key from a series of given junctions. + fn derive>(&self, + path: Iter, + _seed: Option + ) -> Result<(Pair, Option), DeriveError> { + let mut acc = self.secret.serialize(); + for j in path { + match j { + DeriveJunction::Soft(_cc) => return Err(DeriveError::SoftKeyInPath), + DeriveJunction::Hard(cc) => acc = derive_hard_junction(&acc, &cc), + } + } + Ok((Self::from_seed(&acc), Some(acc))) + } + + /// Get the public key. + fn public(&self) -> Public { + Public(self.public.serialize_compressed()) + } + + /// Sign a message. + fn sign(&self, message: &[u8]) -> Signature { + let message = secp256k1::Message::parse(&blake2_256(message)); + secp256k1::sign(&message, &self.secret).into() + } + + /// Verify a signature on a message. Returns true if the signature is good. + fn verify>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool { + let message = secp256k1::Message::parse(&blake2_256(message.as_ref())); + let sig: (_, _) = match sig.try_into() { Ok(x) => x, _ => return false }; + match secp256k1::recover(&message, &sig.0, &sig.1) { + Ok(actual) => &pubkey.0[..] == &actual.serialize_compressed()[..], + _ => false, + } + } + + /// Verify a signature on a message. Returns true if the signature is good. + /// + /// This doesn't use the type system to ensure that `sig` and `pubkey` are the correct + /// size. Use it only if you're coming from byte buffers and need the speed. + fn verify_weak, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool { + let message = secp256k1::Message::parse(&blake2_256(message.as_ref())); + if sig.len() != 65 { return false } + let ri = match secp256k1::RecoveryId::parse(sig[64]) { Ok(x) => x, _ => return false }; + let sig = match secp256k1::Signature::parse_slice(&sig[0..64]) { Ok(x) => x, _ => return false }; + match secp256k1::recover(&message, &sig, &ri) { + Ok(actual) => pubkey.as_ref() == &actual.serialize_compressed()[..], + _ => false, + } + } + + /// Return a vec filled with raw data. + fn to_raw_vec(&self) -> Vec { + self.seed().to_vec() + } +} + +#[cfg(feature = "std")] +impl Pair { + /// Get the seed for this key. + pub fn seed(&self) -> Seed { + self.secret.serialize() + } + + /// Exactly as `from_string` except that if no matches are found then, the the first 32 + /// characters are taken (padded with spaces as necessary) and used as the MiniSecretKey. + pub fn from_legacy_string(s: &str, password_override: Option<&str>) -> Pair { + Self::from_string(s, password_override).unwrap_or_else(|_| { + let mut padded_seed: Seed = [' ' as u8; 32]; + let len = s.len().min(32); + padded_seed[..len].copy_from_slice(&s.as_bytes()[..len]); + Self::from_seed(&padded_seed) + }) + } +} + +impl CryptoType for Public { + #[cfg(feature="std")] + type Pair = Pair; +} + +impl CryptoType for Signature { + #[cfg(feature="std")] + type Pair = Pair; +} + +#[cfg(feature = "std")] +impl CryptoType for Pair { + type Pair = Pair; +} + +#[cfg(test)] +mod test { + use super::*; + use hex_literal::hex; + use crate::crypto::DEV_PHRASE; + + #[test] + fn default_phrase_should_be_used() { + assert_eq!( + Pair::from_string("//Alice///password", None).unwrap().public(), + Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password")).unwrap().public(), + ); + } + + #[test] + fn seed_and_derive_should_work() { + let seed = hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"); + let pair = Pair::from_seed(&seed); + assert_eq!(pair.seed(), seed); + let path = vec![DeriveJunction::Hard([0u8; 32])]; + let derived = pair.derive(path.into_iter(), None).ok().unwrap(); + assert_eq!( + derived.0.seed(), + hex!("b8eefc4937200a8382d00050e050ced2d4ab72cc2ef1b061477afb51564fdd61") + ); + } + + #[test] + fn test_vector_should_work() { + let pair = Pair::from_seed( + &hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60") + ); + let public = pair.public(); + assert_eq!(public, Public::from_raw( + hex!("028db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd91") + )); + let message = b""; + let signature = hex!("3dde91174bd9359027be59a428b8146513df80a2a3c7eda2194f64de04a69ab97b753169e94db6ffd50921a2668a48b94ca11e3d32c1ff19cfe88890aa7e8f3c00"); + let signature = Signature::from_raw(signature); + assert!(&pair.sign(&message[..]) == &signature); + assert!(Pair::verify(&signature, &message[..], &public)); + } + + #[test] + fn test_vector_by_string_should_work() { + let pair = Pair::from_string( + "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", + None + ).unwrap(); + let public = pair.public(); + assert_eq!(public, Public::from_raw( + hex!("028db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd91") + )); + let message = b""; + let signature = hex!("3dde91174bd9359027be59a428b8146513df80a2a3c7eda2194f64de04a69ab97b753169e94db6ffd50921a2668a48b94ca11e3d32c1ff19cfe88890aa7e8f3c00"); + let signature = Signature::from_raw(signature); + assert!(&pair.sign(&message[..]) == &signature); + assert!(Pair::verify(&signature, &message[..], &public)); + } + + #[test] + fn generated_pair_should_work() { + let (pair, _) = Pair::generate(); + let public = pair.public(); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + assert!(Pair::verify(&signature, &message[..], &public)); + assert!(!Pair::verify(&signature, b"Something else", &public)); + } + + #[test] + fn seeded_pair_should_work() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let public = pair.public(); + assert_eq!(public, Public::from_raw( + hex!("035676109c54b9a16d271abeb4954316a40a32bcce023ac14c8e26e958aa68fba9") + )); + let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000"); + let signature = pair.sign(&message[..]); + println!("Correct signature: {:?}", signature); + assert!(Pair::verify(&signature, &message[..], &public)); + assert!(!Pair::verify(&signature, "Other message", &public)); + } + + #[test] + fn generate_with_phrase_recovery_possible() { + let (pair1, phrase, _) = Pair::generate_with_phrase(None); + let (pair2, _) = Pair::from_phrase(&phrase, None).unwrap(); + + assert_eq!(pair1.public(), pair2.public()); + } + + #[test] + fn generate_with_password_phrase_recovery_possible() { + let (pair1, phrase, _) = Pair::generate_with_phrase(Some("password")); + let (pair2, _) = Pair::from_phrase(&phrase, Some("password")).unwrap(); + + assert_eq!(pair1.public(), pair2.public()); + } + + #[test] + fn password_does_something() { + let (pair1, phrase, _) = Pair::generate_with_phrase(Some("password")); + let (pair2, _) = Pair::from_phrase(&phrase, None).unwrap(); + + assert_ne!(pair1.public(), pair2.public()); + } + + #[test] + fn ss58check_roundtrip_works() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let public = pair.public(); + let s = public.to_ss58check(); + println!("Correct: {}", s); + let cmp = Public::from_ss58check(&s).unwrap(); + assert_eq!(cmp, public); + } +} diff --git a/core/primitives/src/ed25519.rs b/core/primitives/src/ed25519.rs index 810e86767d8e365ce9026e91c932134285ed830a..8c3aa9f89dbdc0de8375bb16d8866ee546726e8a 100644 --- a/core/primitives/src/ed25519.rs +++ b/core/primitives/src/ed25519.rs @@ -41,6 +41,7 @@ use crate::{crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}}; type Seed = [u8; 32]; /// A public key. +#[cfg_attr(feature = "std", derive(Hash))] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default)] pub struct Public(pub [u8; 32]); @@ -129,12 +130,17 @@ impl std::fmt::Display for Public { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for Public { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl rstd::fmt::Debug for Public { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { let s = self.to_ss58check(); write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } #[cfg(feature = "std")] @@ -152,13 +158,6 @@ impl<'de> Deserialize<'de> for Public { } } -#[cfg(feature = "std")] -impl std::hash::Hash for Public { - fn hash(&self, state: &mut H) { - self.0.hash(state); - } -} - /// A signature (a 512-bit value). #[derive(Encode, Decode)] pub struct Signature(pub [u8; 64]); @@ -229,11 +228,16 @@ impl AsMut<[u8]> for Signature { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for Signature { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl rstd::fmt::Debug for Signature { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } #[cfg(feature = "std")] @@ -397,12 +401,15 @@ 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 })) } /// Derive a child key from a series of given junctions. - fn derive>(&self, path: Iter) -> Result { + fn derive>(&self, + path: Iter, + _seed: Option, + ) -> Result<(Pair, Option), DeriveError> { let mut acc = self.0.secret.to_bytes(); for j in path { match j { @@ -410,18 +417,7 @@ impl TraitPair for Pair { DeriveJunction::Hard(cc) => acc = derive_hard_junction(&acc, &cc), } } - Ok(Self::from_seed(&acc)) - } - - /// Generate a key from the phrase, password and derivation path. - fn from_standard_components>( - phrase: &str, - password: Option<&str>, - path: I - ) -> Result { - Self::from_phrase(phrase, password)?.0 - .derive(path) - .map_err(|_| SecretStringError::InvalidPath) + Ok((Self::from_seed(&acc), Some(acc))) } /// Get the public key. @@ -434,7 +430,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 +454,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, } @@ -524,7 +520,7 @@ mod test { let pair = Pair::from_seed(&seed); assert_eq!(pair.seed(), &seed); let path = vec![DeriveJunction::Hard([0u8; 32])]; - let derived = pair.derive(path.into_iter()).ok().unwrap(); + let derived = pair.derive(path.into_iter(), None).ok().unwrap().0; assert_eq!( derived.seed(), &hex!("ede3354e133f9c8e337ddd6ee5415ed4b4ffe5fc7d21e933f4930a3730e5b21c") diff --git a/core/primitives/src/hexdisplay.rs b/core/primitives/src/hexdisplay.rs index cd2b6c18cb7fed04ecb08a2a6ac936c7853a1762..2c8533e25b5f88808d2e973bc2223fe3dc534ae4 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> { +impl<'a> rstd::fmt::Display for HexDisplay<'a> { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> Result<(), rstd::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> rstd::fmt::Debug for HexDisplay<'a> { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> Result<(), rstd::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]`. @@ -71,7 +80,7 @@ macro_rules! impl_non_endians { impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], - [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); + [u8; 48], [u8; 56], [u8; 64], [u8; 65], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); /// Format into ASCII + # + hex, suitable for storage key preimages. pub fn ascii_format(asciish: &[u8]) -> String { diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index 21e7c878082ad85f4aade22a8711b2633f2f89df..d1b42766a08f0c970e045f75984dae1d9b4fa1ce 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -26,9 +26,9 @@ /// Can be used to create a `HashMap`. #[macro_export] macro_rules! map { - ($( $name:expr => $value:expr ),*) => ( + ($( $name:expr => $value:expr ),* $(,)? ) => ( vec![ $( ( $name, $value ) ),* ].into_iter().collect() - ) + ); } use rstd::prelude::*; @@ -39,8 +39,11 @@ use std::borrow::Cow; use serde::{Serialize, Deserialize}; #[cfg(feature = "std")] pub use serde;// << for macro +#[doc(hidden)] pub use codec::{Encode, Decode};// << for macro +pub use substrate_debug_derive::RuntimeDebug; + #[cfg(feature = "std")] pub use impl_serde::serialize as bytes; @@ -56,13 +59,14 @@ pub mod u32_trait; pub mod ed25519; pub mod sr25519; +pub mod ecdsa; pub mod hash; mod hasher; pub mod offchain; pub mod sandbox; -pub mod storage; pub mod uint; mod changes_trie; +#[cfg(feature = "std")] pub mod traits; pub mod testing; @@ -80,6 +84,11 @@ pub use hash_db::Hasher; // pub use self::hasher::blake::BlakeHasher; pub use self::hasher::blake2::Blake2Hasher; +pub use primitives_storage as storage; + +#[doc(hidden)] +pub use rstd; + /// Context for executing a call into the runtime. pub enum ExecutionContext { /// Context for general importing (including own blocks). @@ -88,26 +97,30 @@ 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, } } } /// Hex-serialized shim for `Vec`. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord))] +#[derive(PartialEq, Eq, Clone, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord))] pub struct Bytes(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec); impl From> for Bytes { @@ -152,9 +165,9 @@ 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) +impl rstd::fmt::Debug for NativeOrEncoded { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + hexdisplay::HexDisplay::from(&self.as_encoded().as_ref()).fmt(f) } } @@ -214,3 +227,63 @@ 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]; +} + +/// A log level matching the one from `log` crate. +/// +/// Used internally by `runtime_io::log` method. +#[repr(u32)] +pub enum LogLevel { + /// `Error` log level. + Error = 1, + /// `Warn` log level. + Warn = 2, + /// `Info` log level. + Info = 3, + /// `Debug` log level. + Debug = 4, + /// `Trace` log level. + Trace = 5, +} + +impl From for LogLevel { + fn from(val: u32) -> Self { + match val { + x if x == LogLevel::Warn as u32 => LogLevel::Warn, + x if x == LogLevel::Info as u32 => LogLevel::Info, + x if x == LogLevel::Debug as u32 => LogLevel::Debug, + x if x == LogLevel::Trace as u32 => LogLevel::Trace, + _ => LogLevel::Error, + } + } +} + +impl From for LogLevel { + fn from(l: log::Level) -> Self { + use log::Level::*; + match l { + Error => Self::Error, + Warn => Self::Warn, + Info => Self::Info, + Debug => Self::Debug, + Trace => Self::Trace, + } + } +} + +impl From for log::Level { + fn from(l: LogLevel) -> Self { + use self::LogLevel::*; + match l { + Error => Self::Error, + Warn => Self::Warn, + Info => Self::Info, + Debug => Self::Debug, + Trace => Self::Trace, + } + } +} diff --git a/core/primitives/src/offchain.rs b/core/primitives/src/offchain.rs index 52dbf5fbee3566433f2664ea1ce790a641599fdb..27bd29a00df8db696404b9324f49b77deecd8820 100644 --- a/core/primitives/src/offchain.rs +++ b/core/primitives/src/offchain.rs @@ -17,14 +17,13 @@ //! Offchain workers types use codec::{Encode, Decode}; -use rstd::prelude::{Vec, Box}; -use rstd::convert::TryFrom; +use rstd::{prelude::{Vec, Box}, convert::TryFrom}; +use crate::RuntimeDebug; pub use crate::crypto::KeyTypeId; /// A type of supported crypto. -#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, RuntimeDebug)] #[repr(C)] pub enum StorageKind { /// Persistent storage is non-revertible and not fork-aware. It means that any value @@ -60,8 +59,8 @@ impl From for u32 { } /// Opaque type for offchain http requests. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] pub struct HttpRequestId(pub u16); impl From for u32 { @@ -71,14 +70,15 @@ impl From for u32 { } /// An error enum returned by some http methods. -#[derive(Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug)] #[repr(C)] pub enum HttpError { /// The requested action couldn't been completed within a deadline. 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 +88,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(()) } } @@ -100,23 +101,21 @@ impl From for u32 { } /// Status of the HTTP request -#[derive(Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug)] 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 +123,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 +136,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(()), } @@ -148,8 +147,7 @@ impl TryFrom for HttpRequestStatus { /// A blob to hold information about the local node's network state /// without committing to its format. -#[derive(Clone, Eq, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] pub struct OpaqueNetworkState { /// PeerId of the local node. pub peer_id: OpaquePeerId, @@ -158,8 +156,7 @@ pub struct OpaqueNetworkState { } /// Simple blob to hold a `PeerId` without committing to its format. -#[derive(Clone, Eq, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Default, Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] pub struct OpaquePeerId(pub Vec); impl OpaquePeerId { @@ -170,8 +167,7 @@ impl OpaquePeerId { } /// Simple blob to hold a `Multiaddr` without committing to its format. -#[derive(Clone, Eq, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] pub struct OpaqueMultiaddr(pub Vec); impl OpaqueMultiaddr { @@ -182,13 +178,11 @@ impl OpaqueMultiaddr { } /// Opaque timestamp type -#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default, RuntimeDebug)] pub struct Timestamp(u64); /// Duration type -#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default, RuntimeDebug)] pub struct Duration(u64); impl Duration { @@ -230,6 +224,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 +349,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 +362,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 +383,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 +409,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 +422,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 +435,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 +537,137 @@ 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) + } +} + +#[cfg(feature = "std")] +externalities::decl_extension! { + /// The offchain extension that will be registered at the Substrate externalities. + pub struct OffchainExt(Box); +} + +#[cfg(feature = "std")] +impl OffchainExt { + /// Create a new instance of `Self`. + pub fn new(offchain: O) -> Self { + Self(Box::new(offchain)) + } +} #[cfg(test)] mod tests { @@ -443,4 +680,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/sandbox.rs b/core/primitives/src/sandbox.rs index e47a30ca5bbb7abb91c4901d9e05d0df33836b2d..dd91ad6a1f5c0ef00966c57b4a20ab93359118af 100644 --- a/core/primitives/src/sandbox.rs +++ b/core/primitives/src/sandbox.rs @@ -21,12 +21,12 @@ use rstd::vec::Vec; /// Error error that can be returned from host function. #[derive(Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(crate::RuntimeDebug)] pub struct HostError; /// Representation of a typed wasm value. #[derive(Clone, Copy, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(crate::RuntimeDebug)] pub enum TypedValue { /// Value of 32-bit signed or unsigned integer. #[codec(index = "1")] @@ -86,7 +86,7 @@ impl From for ::wasmi::RuntimeValue { /// /// Basically a `TypedValue` plus `Unit`, for functions which return nothing. #[derive(Clone, Copy, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(crate::RuntimeDebug)] pub enum ReturnValue { /// For returning nothing. Unit, @@ -119,7 +119,7 @@ fn return_value_encoded_max_size() { /// Describes an entity to define or import into the environment. #[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(crate::RuntimeDebug)] pub enum ExternEntity { /// Function that is specified by an index in a default table of /// a module that creates the sandbox. @@ -137,7 +137,7 @@ pub enum ExternEntity { /// Each entry has a two-level name and description of an entity /// being defined. #[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(crate::RuntimeDebug)] pub struct Entry { /// Module name of which corresponding entity being defined. pub module_name: Vec, @@ -149,7 +149,7 @@ pub struct Entry { /// Definition of runtime that could be used by sandboxed code. #[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(crate::RuntimeDebug)] pub struct EnvironmentDefinition { /// Vector of all entries in the environment definition. pub entries: Vec, diff --git a/core/primitives/src/sr25519.rs b/core/primitives/src/sr25519.rs index 0e573f49ce34c3de29565df0fc318b6214aae2d3..bb319b8221828b03e5266f579966977ba12c2140 100644 --- a/core/primitives/src/sr25519.rs +++ b/core/primitives/src/sr25519.rs @@ -47,6 +47,7 @@ use schnorrkel::keys::{MINI_SECRET_KEY_LENGTH, SECRET_KEY_LENGTH}; const SIGNING_CTX: &[u8] = b"substrate"; /// An Schnorrkel/Ristretto x25519 ("sr25519") public key. +#[cfg_attr(feature = "std", derive(Hash))] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default)] pub struct Public(pub [u8; 32]); @@ -128,12 +129,20 @@ impl std::fmt::Display for Public { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for Public { - fn fmt(&self, f: &mut std::fmt::Formatter) -> ::std::fmt::Result { +#[cfg(not(feature = "std"))] +use core as std; + +impl rstd::fmt::Debug for Public { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { let s = self.to_ss58check(); write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } #[cfg(feature = "std")] @@ -151,13 +160,6 @@ impl<'de> Deserialize<'de> for Public { } } -#[cfg(feature = "std")] -impl std::hash::Hash for Public { - fn hash(&self, state: &mut H) { - self.0.hash(state); - } -} - /// An Schnorrkel/Ristretto x25519 ("sr25519") signature. /// /// Instead of importing it for the local module, alias it to be available as a public type @@ -237,11 +239,16 @@ impl From for Signature { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for Signature { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { +impl rstd::fmt::Debug for Signature { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } #[cfg(feature = "std")] @@ -381,8 +388,8 @@ impl AsRef for Pair { /// Derive a single hard junction. #[cfg(feature = "std")] -fn derive_hard_junction(secret: &SecretKey, cc: &[u8; CHAIN_CODE_LENGTH]) -> SecretKey { - secret.hard_derive_mini_secret_key(Some(ChainCode(cc.clone())), b"").0.expand(ExpansionMode::Ed25519) +fn derive_hard_junction(secret: &SecretKey, cc: &[u8; CHAIN_CODE_LENGTH]) -> MiniSecretKey { + secret.hard_derive_mini_secret_key(Some(ChainCode(cc.clone())), b"").0 } /// The raw secret seed, which can be used to recreate the `Pair`. @@ -437,17 +444,6 @@ impl TraitPair for Pair { } } - /// Generate a key from the phrase, password and derivation path. - fn from_standard_components>( - phrase: &str, - password: Option<&str>, - path: I - ) -> Result { - Self::from_phrase(phrase, password)?.0 - .derive(path) - .map_err(|_| SecretStringError::InvalidPath) - } - fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) { let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); let phrase = mnemonic.phrase(); @@ -466,13 +462,27 @@ impl TraitPair for Pair { .map(|m| Self::from_entropy(m.entropy(), password)) } - fn derive>(&self, path: Iter) -> Result { + fn derive>(&self, + path: Iter, + seed: Option, + ) -> Result<(Pair, Option), Self::DeriveError> { + let seed = if let Some(s) = seed { + if let Ok(msk) = MiniSecretKey::from_bytes(&s) { + if msk.expand(ExpansionMode::Ed25519) == self.0.secret { + Some(msk) + } else { None } + } else { None } + } else { None }; let init = self.0.secret.clone(); - let result = path.fold(init, |acc, j| match j { - DeriveJunction::Soft(cc) => acc.derived_key_simple(ChainCode(cc), &[]).0, - DeriveJunction::Hard(cc) => derive_hard_junction(&acc, &cc), + let (result, seed) = path.fold((init, seed), |(acc, acc_seed), j| match (j, acc_seed) { + (DeriveJunction::Soft(cc), _) => + (acc.derived_key_simple(ChainCode(cc), &[]).0, None), + (DeriveJunction::Hard(cc), maybe_seed) => { + let seed = derive_hard_junction(&acc, &cc); + (seed.expand(ExpansionMode::Ed25519), maybe_seed.map(|_| seed)) + } }); - Ok(Self(result.into())) + Ok((Self(result.into()), seed.map(|s| MiniSecretKey::to_bytes(&s)))) } fn sign(&self, message: &[u8]) -> Signature { @@ -614,9 +624,9 @@ mod test { let pair = Pair::from_seed(&hex!( "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" )); - let derive_1 = pair.derive(Some(DeriveJunction::soft(1)).into_iter()).unwrap(); - let derive_1b = pair.derive(Some(DeriveJunction::soft(1)).into_iter()).unwrap(); - let derive_2 = pair.derive(Some(DeriveJunction::soft(2)).into_iter()).unwrap(); + let derive_1 = pair.derive(Some(DeriveJunction::soft(1)).into_iter(), None).unwrap().0; + let derive_1b = pair.derive(Some(DeriveJunction::soft(1)).into_iter(), None).unwrap().0; + let derive_2 = pair.derive(Some(DeriveJunction::soft(2)).into_iter(), None).unwrap().0; assert_eq!(derive_1.public(), derive_1b.public()); assert_ne!(derive_1.public(), derive_2.public()); } @@ -626,9 +636,9 @@ mod test { let pair = Pair::from_seed(&hex!( "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" )); - let derive_1 = pair.derive(Some(DeriveJunction::hard(1)).into_iter()).unwrap(); - let derive_1b = pair.derive(Some(DeriveJunction::hard(1)).into_iter()).unwrap(); - let derive_2 = pair.derive(Some(DeriveJunction::hard(2)).into_iter()).unwrap(); + let derive_1 = pair.derive(Some(DeriveJunction::hard(1)).into_iter(), None).unwrap().0; + let derive_1b = pair.derive(Some(DeriveJunction::hard(1)).into_iter(), None).unwrap().0; + let derive_2 = pair.derive(Some(DeriveJunction::hard(2)).into_iter(), None).unwrap().0; assert_eq!(derive_1.public(), derive_1b.public()); assert_ne!(derive_1.public(), derive_2.public()); } @@ -639,7 +649,7 @@ mod test { "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" )); let path = Some(DeriveJunction::soft(1)); - let pair_1 = pair.derive(path.clone().into_iter()).unwrap(); + let pair_1 = pair.derive(path.clone().into_iter(), None).unwrap().0; let public_1 = pair.public().derive(path.into_iter()).unwrap(); assert_eq!(pair_1.public(), public_1); } diff --git a/core/primitives/src/storage.rs b/core/primitives/src/storage.rs deleted file mode 100644 index 8fdb7bdcc40c03618ea1eb3f02f7356676452c1e..0000000000000000000000000000000000000000 --- a/core/primitives/src/storage.rs +++ /dev/null @@ -1,78 +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 . - -//! Contract execution data. - -#[cfg(feature = "std")] -use serde::{Serialize, Deserialize}; -#[cfg(feature = "std")] -use crate::bytes; -use rstd::vec::Vec; - -/// Contract storage key. -#[derive(PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord, Clone))] -pub struct StorageKey(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec); - -/// Contract storage entry data. -#[derive(PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord, Clone))] -pub struct StorageData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec); - -/// Storage change set -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, PartialEq, Eq))] -#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] -pub struct StorageChangeSet { - /// Block hash - pub block: Hash, - /// A list of changes - pub changes: Vec<( - StorageKey, - Option, - )>, -} - -/// List of all well known keys and prefixes in storage. -pub mod well_known_keys { - - /// Wasm code of the runtime. - /// - /// Stored as a raw byte vector. Required by substrate. - pub const CODE: &'static [u8] = b":code"; - - /// Number of wasm linear memory pages required for execution of the runtime. - /// - /// The type of this value is encoded `u64`. - pub const HEAP_PAGES: &'static [u8] = b":heappages"; - - /// Current extrinsic index (u32) is stored under this key. - pub const EXTRINSIC_INDEX: &'static [u8] = b":extrinsic_index"; - - /// Changes trie configuration is stored under this key. - pub const CHANGES_TRIE_CONFIG: &'static [u8] = b":changes_trie"; - - /// Prefix of child storage keys. - pub const CHILD_STORAGE_KEY_PREFIX: &'static [u8] = b":child_storage:"; - - /// Whether a key is a child storage key. - /// - /// This is convenience function which basically checks if the given `key` starts - /// with `CHILD_STORAGE_KEY_PREFIX` and doesn't do anything apart from that. - pub fn is_child_storage_key(key: &[u8]) -> bool { - // Other code might depend on this, so be careful changing this. - key.starts_with(CHILD_STORAGE_KEY_PREFIX) - } -} diff --git a/core/primitives/src/testing.rs b/core/primitives/src/testing.rs index 932c8b9cb1e75707b10beb5870d39486e3e2d722..92a09ff044f773c2f43675040ebdd065e4082a20 100644 --- a/core/primitives/src/testing.rs +++ b/core/primitives/src/testing.rs @@ -17,7 +17,13 @@ //! 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; + +/// 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")] @@ -30,7 +36,7 @@ pub struct KeyStore { #[cfg(feature = "std")] impl KeyStore { /// Creates a new instance of `Self`. - pub fn new() -> std::sync::Arc> { + pub fn new() -> crate::traits::BareCryptoStorePtr { std::sync::Arc::new(parking_lot::RwLock::new(Self::default())) } } @@ -123,21 +129,137 @@ impl crate::traits::BareCryptoStore for KeyStore { } } +/// Macro for exporting functions from wasm in with the expected signature for using it with the +/// wasm executor. This is useful for tests where you need to call a function in wasm. +/// +/// The input parameters are expected to be SCALE encoded and will be automatically decoded for you. +/// The output value is also SCALE encoded when returned back to the host. +/// +/// The functions are feature-gated with `#[cfg(not(feature = "std"))]`, so they are only available +/// from within wasm. +/// +/// # Example +/// +/// ``` +/// # use substrate_primitives::wasm_export_functions; +/// +/// wasm_export_functions! { +/// fn test_in_wasm(value: bool, another_value: Vec) -> bool { +/// value && another_value.is_empty() +/// } +/// +/// fn without_return_value() { +/// // do something +/// } +/// } +/// ``` +#[macro_export] +macro_rules! wasm_export_functions { + ( + $( + fn $name:ident ( + $( $arg_name:ident: $arg_ty:ty ),* $(,)? + ) $( -> $ret_ty:ty )? { $( $fn_impl:tt )* } + )* + ) => { + $( + $crate::wasm_export_functions! { + @IMPL + fn $name ( + $( $arg_name: $arg_ty ),* + ) $( -> $ret_ty )? { $( $fn_impl )* } + } + )* + }; + (@IMPL + fn $name:ident ( + $( $arg_name:ident: $arg_ty:ty ),* + ) { $( $fn_impl:tt )* } + ) => { + #[no_mangle] + #[allow(unreachable_code)] + #[cfg(not(feature = "std"))] + pub fn $name(input_data: *mut u8, input_len: usize) -> u64 { + let input: &[u8] = if input_len == 0 { + &[0u8; 0] + } else { + unsafe { + $crate::rstd::slice::from_raw_parts(input_data, input_len) + } + }; + + { + let ($( $arg_name ),*) : ($( $arg_ty ),*) = $crate::Decode::decode( + &mut &input[..], + ).expect("Input data is correctly encoded"); + + $( $fn_impl )* + } + + // We need to return *something* + let output = Vec::::new(); + let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); + + // Leak the output vector to avoid it being freed. + // This is fine in a WASM context since the heap + // will be discarded after the call. + $crate::rstd::mem::forget(output); + res + } + }; + (@IMPL + fn $name:ident ( + $( $arg_name:ident: $arg_ty:ty ),* + ) $( -> $ret_ty:ty )? { $( $fn_impl:tt )* } + ) => { + #[no_mangle] + #[allow(unreachable_code)] + #[cfg(not(feature = "std"))] + pub fn $name(input_data: *mut u8, input_len: usize) -> u64 { + let input: &[u8] = if input_len == 0 { + &[0u8; 0] + } else { + unsafe { + $crate::rstd::slice::from_raw_parts(input_data, input_len) + } + }; + + let output $( : $ret_ty )? = { + let ($( $arg_name ),*) : ($( $arg_ty ),*) = $crate::Decode::decode( + &mut &input[..], + ).expect("Input data is correctly encoded"); + + $( $fn_impl )* + }; + + let output = $crate::Encode::encode(&output); + let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); + + // Leak the output vector to avoid it being freed. + // This is fine in a WASM context since the heap + // will be discarded after the call. + $crate::rstd::mem::forget(output); + res + } + }; +} + #[cfg(test)] mod tests { use super::*; - use crate::{sr25519, crypto::key_types, traits::BareCryptoStore}; + use crate::sr25519; + 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 +273,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..1ef665032eed4cb9cba4787450035c4d36c5c752 100644 --- a/core/primitives/src/traits.rs +++ b/core/primitives/src/traits.rs @@ -16,11 +16,13 @@ //! Shareable Substrate traits. -#[cfg(feature = "std")] use crate::{crypto::KeyTypeId, ed25519, sr25519}; +use std::{fmt::{Debug, Display}, panic::UnwindSafe}; + +pub use externalities::{Externalities, ExternalitiesExt}; + /// Something that generates, stores and provides access to keys. -#[cfg(feature = "std")] pub trait BareCryptoStore: Send + Sync { /// Returns all sr25519 public keys for the given key type. fn sr25519_public_keys(&self, id: KeyTypeId) -> Vec; @@ -66,5 +68,30 @@ pub trait BareCryptoStore: Send + Sync { } /// A pointer to the key store. -#[cfg(feature = "std")] pub type BareCryptoStorePtr = std::sync::Arc>; + +externalities::decl_extension! { + /// The keystore extension to register/retrieve from the externalities. + pub struct KeystoreExt(BareCryptoStorePtr); +} + +/// Code execution engine. +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/primitives/storage/Cargo.toml b/core/primitives/storage/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..7bb2b95623c89cdff81f522929ee4e00dce217b2 --- /dev/null +++ b/core/primitives/storage/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "substrate-primitives-storage" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" +description = "Storage related primitives" + +[dependencies] +rstd = { package = "sr-std", path = "../../sr-std", default-features = false } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +impl-serde = { version = "0.2.1", optional = true } +substrate-debug-derive = { version = "2.0.0", path = "../debug-derive" } + +[features] +default = [ "std" ] +std = [ "rstd/std", "serde", "impl-serde" ] diff --git a/core/primitives/storage/src/lib.rs b/core/primitives/storage/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..dcdc223994e269af7903df68e13830658e4d5e71 --- /dev/null +++ b/core/primitives/storage/src/lib.rs @@ -0,0 +1,150 @@ +// 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 . + +//! Primitive types for storage related stuff. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; +use substrate_debug_derive::RuntimeDebug; + +use rstd::{vec::Vec, borrow::Cow}; + +/// Storage key. +#[derive(PartialEq, Eq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord, Clone))] +pub struct StorageKey( + #[cfg_attr(feature = "std", serde(with="impl_serde::serialize"))] + pub Vec, +); + +/// Storage data associated to a [`StorageKey`]. +#[derive(PartialEq, Eq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord, Clone))] +pub struct StorageData( + #[cfg_attr(feature = "std", serde(with="impl_serde::serialize"))] + pub Vec, +); + +/// Storage change set +#[derive(RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, PartialEq, Eq))] +#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] +pub struct StorageChangeSet { + /// Block hash + pub block: Hash, + /// A list of changes + pub changes: Vec<(StorageKey, Option)>, +} + +/// List of all well known keys and prefixes in storage. +pub mod well_known_keys { + /// Wasm code of the runtime. + /// + /// Stored as a raw byte vector. Required by substrate. + pub const CODE: &'static [u8] = b":code"; + + /// Number of wasm linear memory pages required for execution of the runtime. + /// + /// The type of this value is encoded `u64`. + pub const HEAP_PAGES: &'static [u8] = b":heappages"; + + /// Current extrinsic index (u32) is stored under this key. + pub const EXTRINSIC_INDEX: &'static [u8] = b":extrinsic_index"; + + /// Changes trie configuration is stored under this key. + pub const CHANGES_TRIE_CONFIG: &'static [u8] = b":changes_trie"; + + /// Prefix of child storage keys. + pub const CHILD_STORAGE_KEY_PREFIX: &'static [u8] = b":child_storage:"; + + /// Whether a key is a child storage key. + /// + /// This is convenience function which basically checks if the given `key` starts + /// with `CHILD_STORAGE_KEY_PREFIX` and doesn't do anything apart from that. + pub fn is_child_storage_key(key: &[u8]) -> bool { + // 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 + } +} + +/// 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> { + /// Create new instance of `Self`. + fn new(storage_key: Cow<'a, [u8]>) -> Option { + if well_known_keys::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/rpc-servers/Cargo.toml b/core/rpc-servers/Cargo.toml index 54a4b68eab9bf877848fb65db643da19d8ef1ae8..80e16bc5ae5be385c03ed0c5f4fa0cda1729ee06 100644 --- a/core/rpc-servers/Cargo.toml +++ b/core/rpc-servers/Cargo.toml @@ -5,12 +5,13 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -jsonrpc-core = "13.0.0" -pubsub = { package = "jsonrpc-pubsub", version = "13.0.0" } -log = "0.4" -serde = "1.0" +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.41" sr-primitives = { path = "../sr-primitives" } [target.'cfg(not(target_os = "unknown"))'.dependencies] -http = { package = "jsonrpc-http-server", version = "13.0.0" } -ws = { package = "jsonrpc-ws-server", version = "13.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 05d24a230233967bbff0e4ef13669b2e2f32c690..3f408f6684a0395ae940d14aa841afd3623175fe 100644 --- a/core/rpc-servers/src/lib.rs +++ b/core/rpc-servers/src/lib.rs @@ -16,7 +16,7 @@ //! Substrate RPC servers. -#[warn(missing_docs)] +#![warn(missing_docs)] use std::io; use jsonrpc_core::IoHandlerExtension; @@ -40,6 +40,19 @@ pub fn rpc_handler( ) -> RpcHandler { let mut io = pubsub::PubSubHandler::default(); 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 } diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 0a9cf108c9ede0857c656c4afe9107fb05636c41..85998feb1b88789e2d67848eb9edbac051d0498c 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 = "13.0.0" -jsonrpc-core-client = "13.0.0" -jsonrpc-pubsub = "13.0.0" -jsonrpc-derive = "13.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.41" 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..bccafc2a85dd7619984d881f27525526204b4657 --- /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.41" +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..454c0887abf820c284ce2eaa74da852cecb082b0 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; +/// Chain 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 80% rename from core/rpc/src/subscriptions.rs rename to core/rpc/api/src/subscriptions.rs index 77df0c09fdc7887441294b6acfd1495f30e4016d..d5ca74fa60bc7e441b6f2645725b6babbba64528 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(), @@ -66,18 +69,26 @@ impl Subscriptions { } } + /// Borrows the internal task executor. + /// + /// This can be used to spawn additional tasks on the underyling event loop. + pub fn executor(&self) -> &TaskExecutor { + &self.executor + } + /// 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 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 +100,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 90% rename from core/rpc/src/system/helpers.rs rename to core/rpc/api/src/system/helpers.rs index 00e2ba9f408b7658ccb45a10d62642bbfed1209c..10319d57b693b0fb0e7847cb6b024c122b60b930 100644 --- a/core/rpc/src/system/helpers.rs +++ b/core/rpc/api/src/system/helpers.rs @@ -50,6 +50,14 @@ pub struct Health { pub should_have_peers: bool, } +impl fmt::Display for Health { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "{} peers ({})", self.peers, if self.is_syncing { + "syncing" + } else { "idle" }) + } +} + /// Network Peer information #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -66,12 +74,17 @@ pub struct PeerInfo { pub best_number: Number, } -impl fmt::Display for Health { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{} peers ({})", self.peers, if self.is_syncing { - "syncing" - } else { "idle" }) - } +/// The role the node is running as +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum NodeRole { + /// The node is a full node + Full, + /// The node is a light client + LightClient, + /// The node is an authority + Authority, + /// An unknown role with a bit number + UnknownRole(u8) } #[cfg(test)] diff --git a/core/rpc/api/src/system/mod.rs b/core/rpc/api/src/system/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..f59fd84c7c027bc891cd664e5be386c44dbe2885 --- /dev/null +++ b/core/rpc/api/src/system/mod.rs @@ -0,0 +1,71 @@ +// 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, NodeRole}; +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; + + /// Returns the roles the node is running as. + #[rpc(name = "system_nodeRoles", returns = "Vec")] + fn system_node_roles(&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 6e2d7aa92abc99a461898cef1fb109b77b72b104..82122dcf3d21f90041b890b90fc43ed2dd984a75 100644 --- a/core/rpc/src/author/mod.rs +++ b/core/rpc/src/author/mod.rs @@ -16,28 +16,24 @@ //! 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, Future}; -use crate::subscriptions::Subscriptions; -use futures03::{StreamExt as _, compat::Compat}; -use jsonrpc_derive::rpc; +use rpc::futures::{ + Sink, Future, + future::result, +}; +use futures03::{StreamExt as _, compat::Compat, future::ready}; +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, @@ -50,63 +46,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 { @@ -153,29 +95,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 { @@ -183,18 +109,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> { @@ -229,30 +159,46 @@ 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 - .submit_and_watch(&generic::BlockId::hash(best_block_hash), dxt) - .map_err(|e| e.into_pool_error() - .map(Into::into) - .unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into()) - ) + 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) + .map_err(|e| e.into_pool_error() + .map(error::Error::from) + .unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into()) + ) + ) }; - let watcher = match submit() { - Ok(watcher) => watcher, - Err(err) => { - // reject the subscriber (ignore errors - we don't care if subscriber is no longer there). - let _ = subscriber.reject(err.into()); - return; - }, - }; + let subscriptions = self.subscriptions.clone(); + let future = ready(submit()) + .and_then(|res| res) + // convert the watcher into a `Stream` + .map(|res| res.map(|watcher| watcher.into_stream().map(|v| Ok::<_, ()>(Ok(v))))) + // now handle the import result, + // start a new subscrition + .map(move |result| match result { + Ok(watcher) => { + subscriptions.add(subscriber, move |sink| { + sink + .sink_map_err(|_| unimplemented!()) + .send_all(Compat::new(watcher)) + .map(|_| ()) + }); + }, + Err(err) => { + warn!("Failed to submit extrinsic: {}", err); + // reject the subscriber (ignore errors - we don't care if subscriber is no longer there). + let _ = subscriber.reject(err.into()); + }, + }); - self.subscriptions.add(subscriber, move |sink| { - sink - .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) - .send_all(Compat::new(watcher.into_stream().map(|v| Ok::<_, ()>(Ok(v))))) - .map(|_| ()) - }) + let res = self.subscriptions.executor() + .execute(Box::new(Compat::new(future.map(|_| Ok(()))))); + if res.is_err() { + warn!("Error spawning subscription RPC task."); + } } 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 e7cf84c9270696fca5b51b18aeb15671093c49c9..5ae044ff49ede78ab20adca9d9c3da1b108fd489 100644 --- a/core/rpc/src/author/tests.rs +++ b/core/rpc/src/author/tests.rs @@ -19,18 +19,18 @@ use super::*; use std::sync::Arc; use assert_matches::assert_matches; use codec::Encode; -use transaction_pool::{ - txpool::Pool, - ChainApi, -}; -use futures::Stream; use primitives::{ - H256, blake2_256, hexdisplay::HexDisplay, traits::BareCryptoStore, testing::KeyStore, - ed25519, crypto::key_types, + H256, blake2_256, hexdisplay::HexDisplay, testing::{ED25519, SR25519, KeyStore}, traits::BareCryptoStorePtr, ed25519, + crypto::Pair, }; +use rpc::futures::Stream as _; use test_client::{ - self, AccountKeyring, runtime::{Extrinsic, Transfer, SessionKeys}, DefaultTestClientBuilderExt, - TestClientBuilderExt, + self, AccountKeyring, runtime::{Extrinsic, Transfer, SessionKeys, RuntimeApi, Block}, DefaultTestClientBuilderExt, + TestClientBuilderExt, Backend, Client, Executor +}; +use transaction_pool::{ + txpool::Pool, + FullChainApi, }; use tokio::runtime; @@ -44,72 +44,81 @@ fn uxt(sender: AccountKeyring, nonce: u64) -> Extrinsic { tx.into_signed_tx() } +struct TestSetup { + pub runtime: runtime::Runtime, + pub client: Arc>, + pub keystore: BareCryptoStorePtr, + pub pool: Arc, Block>>>, +} + +impl Default for TestSetup { + fn default() -> Self { + let keystore = KeyStore::new(); + let client = Arc::new(test_client::TestClientBuilder::new().set_keystore(keystore.clone()).build()); + let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))); + TestSetup { + runtime: runtime::Runtime::new().expect("Failed to create runtime in test setup"), + client, + keystore, + pool, + } + } +} + +impl TestSetup { + fn author(&self) -> Author, Block>, RuntimeApi> { + Author { + client: self.client.clone(), + pool: self.pool.clone(), + subscriptions: Subscriptions::new(Arc::new(self.runtime.executor())), + keystore: self.keystore.clone(), + } + } +} + #[test] fn submit_transaction_should_not_cause_error() { - let runtime = runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::new()); - let keystore = KeyStore::new(); - let p = Author { - client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), ChainApi::new(client))), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; + let p = TestSetup::default().author(); let xt = uxt(AccountKeyring::Alice, 1).encode(); 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() ); } #[test] fn submit_rich_transaction_should_not_cause_error() { - let runtime = runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::new()); - let keystore = KeyStore::new(); - let p = Author { - client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), ChainApi::new(client.clone()))), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; + let p = TestSetup::default().author(); let xt = uxt(AccountKeyring::Alice, 0).encode(); 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() ); } #[test] 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 keystore = KeyStore::new(); - let p = Author { - client, - pool: pool.clone(), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; - let (subscriber, id_rx, data) = ::jsonrpc_pubsub::typed::Subscriber::new_test("test"); + let mut setup = TestSetup::default(); + let p = setup.author(); + + let (subscriber, id_rx, data) = jsonrpc_pubsub::typed::Subscriber::new_test("test"); // when p.watch_extrinsic(Default::default(), subscriber, uxt(AccountKeyring::Alice, 0).encode().into()); // then - assert_eq!(runtime.block_on(id_rx), Ok(Ok(1.into()))); + assert_eq!(setup.runtime.block_on(id_rx), Ok(Ok(1.into()))); // check notifications let replacement = { let tx = Transfer { @@ -120,33 +129,41 @@ fn should_watch_extrinsic() { }; tx.into_signed_tx() }; - AuthorApi::submit_extrinsic(&p, replacement.encode().into()).unwrap(); - let (res, data) = runtime.block_on(data.into_future()).unwrap(); + AuthorApi::submit_extrinsic(&p, replacement.encode().into()).wait().unwrap(); + let (res, data) = setup.runtime.block_on(data.into_future()).unwrap(); assert_eq!( res, Some(r#"{"jsonrpc":"2.0","method":"test","params":{"result":"ready","subscription":1}}"#.into()) ); let h = blake2_256(&replacement.encode()); assert_eq!( - runtime.block_on(data.into_future()).unwrap().0, + setup.runtime.block_on(data.into_future()).unwrap().0, Some(format!(r#"{{"jsonrpc":"2.0","method":"test","params":{{"result":{{"usurped":"0x{}"}},"subscription":1}}}}"#, HexDisplay::from(&h))) ); } +#[test] +fn should_return_watch_validation_error() { + //given + let mut setup = TestSetup::default(); + let p = setup.author(); + + let (subscriber, id_rx, _data) = jsonrpc_pubsub::typed::Subscriber::new_test("test"); + + // when + p.watch_extrinsic(Default::default(), subscriber, uxt(AccountKeyring::Alice, 179).encode().into()); + + // then + let res = setup.runtime.block_on(id_rx).unwrap(); + assert!(res.is_err(), "Expected the transaction to be rejected as invalid."); +} + #[test] 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 keystore = KeyStore::new(); - let p = Author { - client, - pool: pool.clone(), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; + let p = TestSetup::default().author(); + 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())] @@ -155,23 +172,16 @@ fn should_return_pending_extrinsics() { #[test] 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 keystore = KeyStore::new(); - let p = Author { - client, - pool: pool.clone(), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; + let setup = TestSetup::default(); + let p = setup.author(); + 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(); - assert_eq!(pool.status().ready, 3); + let hash3 = p.submit_extrinsic(ex3.encode().into()).wait().unwrap(); + assert_eq!(setup.pool.status().ready, 3); // now remove all 3 let removed = p.remove_extrinsic(vec![ @@ -185,57 +195,43 @@ fn should_remove_extrinsics() { #[test] fn should_insert_key() { - let runtime = runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::new()); - let keystore = KeyStore::new(); - let p = Author { - client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), ChainApi::new(client))), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; + let setup = TestSetup::default(); + let p = setup.author(); 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"); + let store_key_pair = setup.keystore.read() + .ed25519_key_pair(ED25519, &key_pair.public()).expect("Key exists in store"); assert_eq!(key_pair.public(), store_key_pair.public()); } #[test] fn should_rotate_keys() { - let runtime = runtime::Runtime::new().unwrap(); - let keystore = KeyStore::new(); - 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))), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; + let setup = TestSetup::default(); + let p = setup.author(); let new_public_keys = p.rotate_keys().expect("Rotates the keys"); let session_keys = SessionKeys::decode(&mut &new_public_keys[..]) .expect("SessionKeys decode successfully"); - let ed25519_key_pair = keystore.read().ed25519_key_pair( - key_types::ED25519, + let ed25519_key_pair = setup.keystore.read().ed25519_key_pair( + ED25519, &session_keys.ed25519.clone().into(), ).expect("ed25519 key exists in store"); - let sr25519_key_pair = keystore.read().sr25519_key_pair( - key_types::SR25519, + let sr25519_key_pair = setup.keystore.read().sr25519_key_pair( + 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 7ca3fde01de46709cbd58140d8d205034c31ef91..9ce9f82fdad2c3413247017378529d0313d3073e 100644 --- a/core/rpc/src/lib.rs +++ b/core/rpc/src/lib.rs @@ -14,22 +14,18 @@ // 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 collection of RPC methods and subscriptions supported by all substrate clients. +//! A core implementation of Substrate RPC interfaces. #![warn(missing_docs)] -mod errors; mod helpers; mod metadata; -mod subscriptions; -use jsonrpc_core as rpc; - -pub use metadata::Metadata; +pub use api::Subscriptions; +pub use self::metadata::Metadata; pub use rpc::IoHandlerExtension as RpcExtension; -pub use subscriptions::Subscriptions; pub mod author; pub mod chain; diff --git a/core/rpc/src/metadata.rs b/core/rpc/src/metadata.rs index 4567b8fabc7841a004ea24ec30a821e812f31a62..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() 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..cd05093c3a8cb8b8fa403e6109d1ae00d9313cd6 --- /dev/null +++ b/core/rpc/src/state/state_full.rs @@ -0,0 +1,509 @@ +// 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, 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, + None, + ) + .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..5dfa234337afa18f8d511226ab53dd2f9d0ebd94 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,18 +276,20 @@ 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],\ [\"0x37e397fc7c91f5e4\",1],[\"0xd2bc9897eed08f15\",1],[\"0x40fe3ad401f8959a\",3],\ [\"0xc6e9a76309f39b09\",1],[\"0xdd718d5cc53262d4\",1],[\"0xcbca25e39f142387\",1],\ - [\"0xf78b278be53f454c\",1],[\"0xab3c0572291feb8b\",1]]}"; + [\"0xf78b278be53f454c\",1],[\"0xab3c0572291feb8b\",1],[\"0xbc9d89904f5b923f\",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); @@ -289,3 +313,11 @@ fn should_notify_on_runtime_version_initially() { // no more notifications on this channel assert_eq!(core.block_on(next.into_future()).unwrap().0, None); } + +#[test] +fn should_deserialize_storage_key() { + let k = "\"0x7f864e18e3dd8b58386310d2fe0919eef27c6e558564b7f67f22d99d20f587b\""; + let k: StorageKey = serde_json::from_str(k).unwrap(); + + assert_eq!(k.0.len(), 32); +} diff --git a/core/rpc/src/system/mod.rs b/core/rpc/src/system/mod.rs index 9e347c6503fb8adbb7a93588b511de3b97867f95..8907151d9ac6984bb8396c3f7af263b1b9994ee3 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, NodeRole}; 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,9 @@ 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), + /// Must return the node role. + NodeRoles(oneshot::Sender>) } impl System { @@ -133,9 +91,15 @@ 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)) } + + fn system_node_roles(&self) -> Receiver> { + let (tx, rx) = oneshot::channel(); + let _ = self.send_back.unbounded_send(Request::NodeRoles(tx)); + Receiver(Compat::new(rx)) + } } diff --git a/core/rpc/src/system/tests.rs b/core/rpc/src/system/tests.rs index 70e8b4b95b67608451d33cd35217b448852660f4..1c532be372660fbee4c8210a56c15842413e553e 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,10 @@ fn api>>(sync: T) -> System { average_download_per_sec: 0, average_upload_per_sec: 0, peerset: serde_json::Value::Null, - }); + }).unwrap()); + }, + Request::NodeRoles(sender) => { + let _ = sender.send(vec![NodeRole::Authority]); } }; @@ -206,8 +209,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(), @@ -220,3 +224,11 @@ fn system_network_state() { } ); } + +#[test] +fn system_node_roles() { + assert_eq!( + wait_receiver(api(None).system_node_roles()), + vec![NodeRole::Authority] + ); +} \ No newline at end of file diff --git a/core/serializer/Cargo.toml b/core/serializer/Cargo.toml index ae320e4277bb5d54a492efc324b04d7796d70298..4e0e706e2fab232ff516ade2bfa22a2ed9ad598c 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.41" diff --git a/core/service/Cargo.toml b/core/service/Cargo.toml index 7afd59ebc0679e9a52675b556b72304b3da0f1c6..04371087eff2e7fce3fb60e6955cd31098d69434 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.41" +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,16 +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-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" } @@ -46,3 +49,4 @@ node-runtime = { path = "../../node/runtime" } 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" } +tokio = "0.1" diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs new file mode 100644 index 0000000000000000000000000000000000000000..b2a6cc731ac3b398ea3514d743127f7b31f4e7a0 --- /dev/null +++ b/core/service/src/builder.rs @@ -0,0 +1,1277 @@ +// 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::{Service, NetworkStatus, NetworkState, error::{self, Error}, DEFAULT_PROTOCOL_ID}; +use crate::{SpawnTaskHandle, start_rpc_servers, build_network_future, TransactionPoolAdapter}; +use crate::status_sinks; +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}; +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; +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, + remote_backend: Option>>, + 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, + Arc>, + (), + (), + (), + 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.wasm_method, + 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); + + 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(), + remote_backend: None, + 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, + Arc>, + (), + (), + (), + 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.wasm_method, + 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, + )?); + + 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(), + remote_backend: Some(remote_blockchain), + 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, + remote_backend: self.remote_backend, + 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, + remote_backend: self.remote_backend, + 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, + remote_backend: self.remote_backend, + 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, + 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, + remote_backend: self.remote_backend, + 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, + 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, + remote_backend: self.remote_backend, + 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, + remote_backend: self.remote_backend, + 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, + remote_backend: self.remote_backend, + 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, + remote_backend: self.remote_backend, + dht_event_tx: Some(dht_event_tx), + marker: self.marker, + }) + } +} + +/// 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, Backend +> ServiceBuilderImport for ServiceBuilder< + TBl, TRtApi, TCfg, TGen, TCSExt, Client, + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, 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, 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, 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, + 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, +{ + /// 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: on_demand, + backend, + keystore, + select_chain, + import_queue, + finality_proof_request_builder, + finality_proof_provider, + network_protocol, + transaction_pool, + rpc_extensions, + remote_backend, + dht_event_tx, + } = self; + + session::generate_initial_session_keys( + client.clone(), + config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default() + )?; + + 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>>(); + + let import_queue = Box::new(import_queue); + let chain_info = client.info().chain; + + let version = config.full_version(); + info!("Highest known block at #{}", chain_info.best_number); + telemetry!( + SUBSTRATE_INFO; + "node.start"; + "height" => chain_info.best_number.saturated_into::(), + "best" => ?chain_info.best_hash + ); + + 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() { + Some(pid) => pid, + None => { + warn!("Using default protocol ID {:?} because none is configured in the \ + chain specs", DEFAULT_PROTOCOL_ID + ); + DEFAULT_PROTOCOL_ID + } + }.as_bytes(); + 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(), + chain: client.clone(), + finality_proof_provider, + finality_proof_request_builder, + on_demand: on_demand.clone(), + transaction_pool: transaction_pool_adapter.clone() as _, + import_queue, + protocol_id, + specialization: network_protocol, + block_announce_validator, + }; + + let has_bootnodes = !network_params.network_config.boot_nodes.is_empty(); + let network_mut = network::NetworkWorker::new(network_params)?; + let network = network_mut.service().clone(); + let network_status_sinks = Arc::new(Mutex::new(status_sinks::StatusSinks::new())); + + 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))) + }, + (true, None) => { + log::warn!("Offchain workers disabled, due to lack of offchain storage support in backend."); + None + }, + _ => None, + }; + + { + // block notifications + let txpool = Arc::downgrade(&transaction_pool); + let wclient = Arc::downgrade(&client); + 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 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.as_ref(), wclient.upgrade()) { + let future = maintain_transaction_pool( + &BlockId::hash(notification.hash), + &client, + &*txpool, + ¬ification.retracted, + ).map_err(|e| warn!("Pool error processing new block: {:?}", e))?; + let _ = to_spawn_tx_.unbounded_send(future); + } + + let offchain = offchain.as_ref().and_then(|o| o.upgrade()); + if let (Some(txpool), Some(offchain)) = (txpool, offchain) { + let future = offchain.on_block_imported(&number, &txpool, network_state_info.clone(), is_validator) + .map(|()| Ok(())); + let _ = to_spawn_tx_.unbounded_send(Box::new(Compat::new(future))); + } + + Ok(()) + }) + .select(exit.clone()) + .then(|_| Ok(())); + let _ = to_spawn_tx.unbounded_send(Box::new(events)); + } + + { + // extrinsic notifications + 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(); + } + let status = transaction_pool_.status(); + telemetry!(SUBSTRATE_INFO; "txpool.import"; + "ready" => status.ready, + "future" => status.future + ); + Ok(()) + }) + .select(exit.clone()) + .then(|_| Ok(())); + + let _ = to_spawn_tx.unbounded_send(Box::new(events)); + } + + // Periodically notify the telemetry. + let transaction_pool_ = transaction_pool.clone(); + let client_ = client.clone(); + let mut sys = System::new(); + let self_pid = get_current_pid().ok(); + let (state_tx, state_rx) = mpsc::unbounded::<(NetworkStatus<_>, NetworkState)>(); + network_status_sinks.lock().push(std::time::Duration::from_millis(5000), state_tx); + let tel_task = state_rx.for_each(move |(net_status, _)| { + let info = client_.info(); + let best_number = info.chain.best_number.saturated_into::(); + let best_hash = info.chain.best_hash; + let num_peers = net_status.num_connected_peers; + let txpool_status = transaction_pool_.status(); + let finalized_number: u64 = info.chain.finalized_number.saturated_into::(); + let bandwidth_download = net_status.average_download_per_sec; + let bandwidth_upload = net_status.average_upload_per_sec; + + let used_state_cache_size = match info.used_state_cache_size { + Some(size) => size, + None => 0, + }; + + // get cpu usage and memory usage of this process + let (cpu_usage, memory) = if let Some(self_pid) = self_pid { + if sys.refresh_process(self_pid) { + let proc = sys.get_process(self_pid) + .expect("Above refresh_process succeeds, this should be Some(), qed"); + (proc.cpu_usage(), proc.memory()) + } else { (0.0, 0) } + } else { (0.0, 0) }; + + telemetry!( + SUBSTRATE_INFO; + "system.interval"; + "peers" => num_peers, + "height" => best_number, + "best" => ?best_hash, + "txcount" => txpool_status.ready, + "cpu" => cpu_usage, + "memory" => memory, + "finalized_height" => finalized_number, + "finalized_hash" => ?info.chain.finalized_hash, + "bandwidth_download" => bandwidth_download, + "bandwidth_upload" => bandwidth_upload, + "used_state_cache_size" => used_state_cache_size, + ); + + Ok(()) + }).select(exit.clone()).then(|_| Ok(())); + let _ = to_spawn_tx.unbounded_send(Box::new(tel_task)); + + // Periodically send the network state to the telemetry. + let (netstat_tx, netstat_rx) = mpsc::unbounded::<(NetworkStatus<_>, NetworkState)>(); + network_status_sinks.lock().push(std::time::Duration::from_secs(30), netstat_tx); + let tel_task_2 = netstat_rx.for_each(move |(_, network_state)| { + telemetry!( + SUBSTRATE_INFO; + "system.network_state"; + "state" => network_state, + ); + Ok(()) + }).select(exit.clone()).then(|_| Ok(())); + let _ = to_spawn_tx.unbounded_send(Box::new(tel_task_2)); + + // RPC + let (system_rpc_tx, system_rpc_rx) = futures03::channel::mpsc::unbounded(); + let gen_handler = || { + use rpc::{chain, state, author, system}; + + 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(), + }; + + let subscriptions = rpc::Subscriptions::new(Arc::new(SpawnTaskHandle { + sender: to_spawn_tx.clone(), + on_exit: exit.clone() + })); + + let (chain, state) = if let (Some(remote_backend), Some(on_demand)) = + (remote_backend.as_ref(), on_demand.as_ref()) { + // Light clients + let chain = rpc::chain::new_light( + client.clone(), + subscriptions.clone(), + remote_backend.clone(), + on_demand.clone() + ); + let state = rpc::state::new_light( + client.clone(), + subscriptions.clone(), + remote_backend.clone(), + on_demand.clone() + ); + (chain, state) + + } else { + // Full nodes + let chain = rpc::chain::new_full(client.clone(), subscriptions.clone()); + let state = rpc::state::new_full(client.clone(), subscriptions.clone()); + (chain, state) + }; + + let author = rpc::author::Author::new( + client.clone(), + transaction_pool.clone(), + subscriptions, + keystore.clone(), + ); + let system = system::System::new(system_info, system_rpc_tx.clone()); + + 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.clone(), + )) + }; + let rpc_handlers = gen_handler(); + let rpc = start_rpc_servers(&config, gen_handler)?; + + + let _ = to_spawn_tx.unbounded_send(Box::new(build_network_future( + config.roles, + network_mut, + client.clone(), + network_status_sinks.clone(), + system_rpc_rx, + has_bootnodes, + dht_event_tx, + ) + .map_err(|_| ()) + .select(exit.clone()) + .then(|_| Ok(())))); + + let telemetry_connection_sinks: Arc>>> = Default::default(); + + // Telemetry + 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 version = version.clone(); + 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(), + }); + let future = telemetry.clone() + .map(|ev| Ok::<_, ()>(ev)) + .compat() + .for_each(move |event| { + // Safe-guard in case we add more events in the future. + let tel::TelemetryEvent::Connected = event; + + telemetry!(SUBSTRATE_INFO; "system.connected"; + "name" => name.clone(), + "implementation" => impl_name.clone(), + "version" => version.clone(), + "config" => "", + "chain" => chain_name.clone(), + "authority" => is_authority, + "network_id" => network_id.clone() + ); + + telemetry_connection_sinks_.lock().retain(|sink| { + sink.unbounded_send(()).is_ok() + }); + Ok(()) + }); + let _ = to_spawn_tx.unbounded_send(Box::new(future + .select(exit.clone()) + .then(|_| Ok(())))); + telemetry + }); + + Ok(Service { + client, + network, + network_status_sinks, + select_chain, + transaction_pool, + exit, + signal: Some(signal), + essential_failed: Arc::new(AtomicBool::new(false)), + to_spawn_tx, + to_spawn_rx, + to_poll: Vec::new(), + rpc_handlers, + _rpc: rpc, + _telemetry: telemetry, + _offchain_workers: offchain_workers, + _telemetry_on_connect_sinks: telemetry_connection_sinks.clone(), + keystore, + marker: PhantomData::, + }) + } +} + +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), + }) +} + +#[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..e6d7df33c2a1d3b4994761722ee558397f5783d3 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_all(&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_all(&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 a9aa2129f2498f1d4438fba8cf7badeba3201378..0000000000000000000000000000000000000000 --- a/core/service/src/components.rs +++ /dev/null @@ -1,808 +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, 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 {} - -/// A transport-agnostic handler of the RPC queries. -pub type RpcHandler = rpc_servers::RpcHandler; - -/// 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>, - rpc_extensions: impl rpc::RpcExtension, - keystore: KeyStorePtr, - ) -> 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>, - rpc_extensions: impl rpc::RpcExtension, - keystore: KeyStorePtr, - ) -> RpcHandler { - use rpc::{chain, state, author, system}; - let subscriptions = rpc::Subscriptions::new(task_executor.clone()); - let chain = chain::Chain::new(client.clone(), subscriptions.clone()); - let state = state::State::new(client.clone(), 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, - )) - } -} - -/// 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; - /// RPC initialisation. - type RpcExtensions: rpc::RpcExtension; - /// 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()) - } - } - - /// Create custom RPC method handlers for full node. - fn build_full_rpc_extensions( - client: Arc>, - transaction_pool: Arc>, - ) -> Self::RpcExtensions; - - /// Create custom RPC method handlers for light node. - fn build_light_rpc_extensions( - client: Arc>, - transaction_pool: Arc>, - ) -> Self::RpcExtensions; -} - -/// 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; - /// The type that can start all runtime-dependent services. - type RuntimeServices: ServiceTrait; - /// The type that can extend the RPC methods. - type RpcExtensions: rpc::RpcExtension; - // 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>; - - /// Build RPC extensions - fn build_rpc_extensions( - client: Arc>, - transaction_pool: Arc>, - ) -> Self::RpcExtensions; -} - -/// 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 RpcExtensions = Factory::RpcExtensions; - 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) - } - - fn build_rpc_extensions( - client: Arc>, - transaction_pool: Arc>, - ) -> Self::RpcExtensions { - Factory::build_full_rpc_extensions(client, transaction_pool) - } -} - -/// 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 RpcExtensions = Factory::RpcExtensions; - 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) - } - - fn build_rpc_extensions( - client: Arc>, - transaction_pool: Arc>, - ) -> Self::RpcExtensions { - Factory::build_light_rpc_extensions(client, transaction_pool) - } -} - -#[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..a1ba83753f4025d927993c06370a60b0a6612f4e 100644 --- a/core/service/src/config.rs +++ b/core/service/src/config.rs @@ -19,19 +19,18 @@ pub use client::ExecutionStrategies; pub use client_db::PruningMode; pub use network::config::{ExtTransport, NetworkConfiguration, Roles}; +pub use substrate_executor::WasmExecutionMethod; 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,11 +56,13 @@ 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. pub name: String, + /// Wasm execution method. + pub wasm_method: WasmExecutionMethod, /// Execution strategies. pub execution_strategies: ExecutionStrategies, /// RPC over HTTP binding address. `None` if disabled. @@ -95,9 +96,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", @@ -114,6 +119,7 @@ impl Configuration { - client: Arc>, - select_chain: Option, - network: Arc>, +pub struct Service { + client: Arc, + select_chain: Option, + network: Arc, /// Sinks to propagate network status updates. - network_status_sinks: Arc>, NetworkState - )>>>>, - transaction_pool: Arc>, + /// For each element, every time the `Interval` fires we push an element on the sender. + network_status_sinks: 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 +96,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: components::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,433 +130,166 @@ 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 { - 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()), - )?; - 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(); - info!("Highest known block at #{}", chain_info.best_number); - telemetry!( - SUBSTRATE_INFO; - "node.start"; - "height" => chain_info.best_number.saturated_into::(), - "best" => ?chain_info.best_hash - ); - - let network_protocol = ::build_network_protocol(&config)?; +/// 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; - let 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 \ - chain specs", DEFAULT_PROTOCOL_ID - ); - DEFAULT_PROTOCOL_ID - } - }.as_bytes(); - network::config::ProtocolId::from(protocol_id_full) - }; + /// Get event stream for telemetry connection established events. + fn telemetry_on_connect_stream(&self) -> mpsc::UnboundedReceiver<()>; - let network_params = network::config::Params { - roles: config.roles, - network_config: config.network.clone(), - chain: client.clone(), - finality_proof_provider, - finality_proof_request_builder, - on_demand, - transaction_pool: transaction_pool_adapter.clone() as _, - import_queue, - protocol_id, - specialization: network_protocol, - }; + /// return a shared instance of Telemetry (if enabled) + fn telemetry(&self) -> Option; - let has_bootnodes = !network_params.network_config.boot_nodes.is_empty(); - let network_mut = network::NetworkWorker::new(network_params)?; - 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) { - (true, Some(db)) => { - Some(Arc::new(offchain::OffchainWorkers::new(client.clone(), db))) - }, - (true, None) => { - log::warn!("Offchain workers disabled, due to lack of offchain storage support in backend."); - None - }, - _ => None, - }; + /// Spawns a task in the background that runs the future passed as parameter. + fn spawn_task(&self, task: impl Future + Send + 'static); - { - // block notifications - let txpool = Arc::downgrade(&transaction_pool); - let wclient = Arc::downgrade(&client); - 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 events = client.import_notification_stream() - .map(|v| Ok::<_, ()>(v)).compat() - .for_each(move |notification| { - let number = *notification.header.number(); - - if let (Some(txpool), Some(client)) = (txpool.upgrade(), wclient.upgrade()) { - Components::RuntimeServices::maintain_transaction_pool( - &BlockId::hash(notification.hash), - &*client, - &*txpool, - ).map_err(|e| warn!("Pool error processing new block: {:?}", e))?; - } + /// 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); - if let (Some(txpool), Some(offchain)) = (txpool.upgrade(), offchain.as_ref().and_then(|o| o.upgrade())) { - let future = Components::RuntimeServices::offchain_workers( - &number, - &offchain, - &txpool, - &network_state_info, - is_validator, - ).map_err(|e| warn!("Offchain workers error processing new block: {:?}", e))?; - let _ = to_spawn_tx_.unbounded_send(future); - } + /// Returns a handle for spawning tasks. + fn spawn_task_handle(&self) -> SpawnTaskHandle; - Ok(()) - }) - .select(exit.clone()) - .then(|_| Ok(())); - let _ = to_spawn_tx.unbounded_send(Box::new(events)); - } + /// Returns the keystore that stores keys. + fn keystore(&self) -> keystore::KeyStorePtr; - { - // extrinsic notifications - 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(); - } - let status = transaction_pool_.status(); - telemetry!(SUBSTRATE_INFO; "txpool.import"; - "ready" => status.ready, - "future" => status.future - ); - Ok(()) - }) - .select(exit.clone()) - .then(|_| Ok(())); - - let _ = to_spawn_tx.unbounded_send(Box::new(events)); - } + /// 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. + fn rpc_query(&self, mem: &RpcSession, request: &str) -> Box, Error = ()> + Send>; - // Periodically notify the telemetry. - let transaction_pool_ = transaction_pool.clone(); - 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)>(); - network_status_sinks.lock().push(netstat_tx); - let tel_task = netstat_rx.for_each(move |(net_status, network_state)| { - let info = client_.info(); - let best_number = info.chain.best_number.saturated_into::(); - let best_hash = info.chain.best_hash; - let num_peers = net_status.num_connected_peers; - let txpool_status = transaction_pool_.status(); - let finalized_number: u64 = info.chain.finalized_number.saturated_into::(); - 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(){ - Some(size) => size, - None => 0, - }; + /// Get shared client instance. + fn client(&self) -> Arc>; - // get cpu usage and memory usage of this process - let (cpu_usage, memory) = if let Some(self_pid) = self_pid { - if sys.refresh_process(self_pid) { - let proc = sys.get_process(self_pid) - .expect("Above refresh_process succeeds, this should be Some(), qed"); - (proc.cpu_usage(), proc.memory()) - } else { (0.0, 0) } - } else { (0.0, 0) }; - - telemetry!( - SUBSTRATE_INFO; - "system.interval"; - "network_state" => network_state, - "peers" => num_peers, - "height" => best_number, - "best" => ?best_hash, - "txcount" => txpool_status.ready, - "cpu" => cpu_usage, - "memory" => memory, - "finalized_height" => finalized_number, - "finalized_hash" => ?info.chain.finalized_hash, - "bandwidth_download" => bandwidth_download, - "bandwidth_upload" => bandwidth_upload, - "used_state_cache_size" => used_state_cache_size, - ); + /// Get clone of select chain. + fn select_chain(&self) -> Option; - Ok(()) - }).select(exit.clone()).then(|_| Ok(())); - let _ = to_spawn_tx.unbounded_send(Box::new(tel_task)); - - // RPC - let (system_rpc_tx, system_rpc_rx) = futures03::channel::mpsc::unbounded(); - let gen_handler = || { - 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(), - }; - Components::RuntimeServices::start_rpc( - client.clone(), - system_rpc_tx.clone(), - system_info.clone(), - Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone() }), - transaction_pool.clone(), - Components::build_rpc_extensions(client.clone(), transaction_pool.clone()), - keystore.clone(), - ) - }; - let rpc_handlers = 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 - ) - .map_err(|_| ()) - .select(exit.clone()) - .then(|_| Ok(())))); - - let telemetry_connection_sinks: Arc>>> = Default::default(); - - // Telemetry - 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 version = version.clone(); - 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(), - }); - let future = telemetry.clone() - .map(|ev| Ok::<_, ()>(ev)) - .compat() - .for_each(move |event| { - // Safe-guard in case we add more events in the future. - let tel::TelemetryEvent::Connected = event; - - telemetry!(SUBSTRATE_INFO; "system.connected"; - "name" => name.clone(), - "implementation" => impl_name.clone(), - "version" => version.clone(), - "config" => "", - "chain" => chain_name.clone(), - "authority" => is_authority, - "network_id" => network_id.clone() - ); - - telemetry_connection_sinks_.lock().retain(|sink| { - sink.unbounded_send(()).is_ok() - }); - Ok(()) - }); - let _ = to_spawn_tx.unbounded_send(Box::new(future - .select(exit.clone()) - .then(|_| Ok(())))); - telemetry - }); + /// Get shared network instance. + fn network(&self) -> Arc>; - Ok(Service { - client, - network, - network_status_sinks, - select_chain, - transaction_pool, - exit, - signal: Some(signal), - essential_failed: Arc::new(AtomicBool::new(false)), - 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, - }) - } + /// Returns a receiver that periodically receives a status of the network. + fn network_status(&self, interval: Duration) -> mpsc::UnboundedReceiver<(NetworkStatus, NetworkState)>; - /// Returns a reference to the config passed at initialization. - pub fn config(&self) -> &FactoryFullConfiguration { - &self.config - } + /// Get shared transaction pool instance. + fn transaction_pool(&self) -> Arc>; - /// Returns a reference to the config passed at initialization. - /// - /// > **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 - } + /// Get a handle to a future that will resolve on exit. + fn on_exit(&self) -> ::exit_future::Exit; +} - /// Get event stream for telemetry connection established events. - pub fn telemetry_on_connect_stream(&self) -> TelemetryOnConnectNotifications { +impl AbstractService for + Service, 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, interval: Duration) -> mpsc::UnboundedReceiver<(NetworkStatus, NetworkState)> { let (sink, stream) = mpsc::unbounded(); - self.network_status_sinks.lock().push(sink); + self.network_status_sinks.lock().push(interval, 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 + Service +{ type Item = (); type Error = Error; @@ -595,7 +312,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. @@ -603,8 +320,8 @@ impl Future for Service where Components: components::Co } } -impl Executor + Send>> - for Service where Components: components::Components +impl Executor + Send>> for + Service { fn execute( &self, @@ -628,20 +345,18 @@ fn build_network_future< S: network::specialization::NetworkSpecialization, H: network::ExHashT > ( + roles: Roles, mut network: network::NetworkWorker, client: Arc, - status_sinks: Arc, NetworkState)>>>>, + status_sinks: Arc, NetworkState)>>>, 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. + // Compatibility shim while we're transitioning to stable Futures. // See https://github.com/paritytech/substrate/issues/3099 let mut rpc_rx = futures03::compat::Compat::new(rpc_rx.map(|v| Ok::<_, ()>(v))); - // Interval at which we send status updates on the status stream. - const STATUS_INTERVAL: Duration = Duration::from_millis(5000); - let mut status_interval = tokio_timer::Interval::new_interval(STATUS_INTERVAL); - let mut imported_blocks_stream = client.import_notification_stream().fuse() .map(|v| Ok::<_, ()>(v)).compat(); let mut finality_notification_stream = client.finality_notification_stream().fuse() @@ -652,7 +367,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. @@ -686,13 +401,30 @@ fn build_network_future< ).collect()); } rpc::system::Request::NetworkState(sender) => { - let _ = sender.send(network.network_state()); + if let Some(network_state) = serde_json::to_value(&network.network_state()).ok() { + let _ = sender.send(network_state); + } + } + rpc::system::Request::NodeRoles(sender) => { + use rpc::system::NodeRole; + + let node_roles = (0 .. 8) + .filter(|&bit_number| (roles.bits() >> bit_number) & 1 == 1) + .map(|bit_number| match Roles::from_bits(1 << bit_number) { + Some(Roles::AUTHORITY) => NodeRole::Authority, + Some(Roles::LIGHT) => NodeRole::LightClient, + Some(Roles::FULL) => NodeRole::Full, + _ => NodeRole::UnknownRole(bit_number), + }) + .collect(); + + let _ = sender.send(node_roles); } }; } // Interval report for the external API. - while let Ok(Async::Ready(_)) = status_interval.poll() { + status_sinks.lock().poll(|| { let status = NetworkStatus { sync_state: network.sync_state(), best_seen_block: network.best_seen_block(), @@ -703,16 +435,25 @@ fn build_network_future< average_upload_per_sec: network.average_upload_per_sec(), }; let state = network.network_state(); - - status_sinks.lock().retain(|sink| sink.unbounded_send((status.clone(), state.clone())).is_ok()); - } + (status, state) + }); // 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(); @@ -746,7 +487,9 @@ pub struct NetworkStatus { pub average_upload_per_sec: u64, } -impl Drop for Service where Components: components::Components { +impl Drop for + Service +{ fn drop(&mut self) { debug!(target: "service", "Substrate service shutdown"); if let Some(signal) = self.signal.take() { @@ -757,8 +500,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 components::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> @@ -798,8 +541,8 @@ fn start_rpc_servers components::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 components::RpcHandler>( - _: &Configuration, +fn start_rpc_servers components::RpcHandler>( + _: &Configuration, _: H ) -> Result, error::Error> { Ok(Box::new(())) @@ -830,6 +573,7 @@ pub struct TransactionPoolAdapter { imports_external_transactions: bool, pool: Arc

, client: Arc, + executor: TaskExecutor, } /// Get transactions for propagation. @@ -840,7 +584,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() @@ -857,47 +601,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), } } @@ -906,228 +652,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 _)) -/// }}, -/// RpcExtensions = (), -/// } -/// } -/// ``` -#[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 )* }, - RpcExtensions = $rpc_extensions_ty:ty - $( { $( $rpc_extensions: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; - type RpcExtensions = $rpc_extensions_ty; - - 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) - }) - } - - fn build_full_rpc_extensions( - client: Arc<$crate::FullClient>, - transaction_pool: Arc<$crate::TransactionPool>, - ) -> Self::RpcExtensions { - $( ( $( $rpc_extensions )* ) (client, transaction_pool) )? - } - - fn build_light_rpc_extensions( - client: Arc<$crate::LightClient>, - transaction_pool: Arc<$crate::TransactionPool>, - ) -> Self::RpcExtensions { - $( ( $( $rpc_extensions )* ) (client, transaction_pool) )? - } - } - } -} - #[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}}; @@ -1139,7 +667,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 { @@ -1148,8 +676,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/src/status_sinks.rs b/core/service/src/status_sinks.rs new file mode 100644 index 0000000000000000000000000000000000000000..079ecf6353b1fe125028e91dc13aabb0e7729f6f --- /dev/null +++ b/core/service/src/status_sinks.rs @@ -0,0 +1,149 @@ +// 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 futures::prelude::*; +use futures::sync::mpsc; +use futures::stream::futures_unordered::FuturesUnordered; +use std::time::{Duration, Instant}; +use tokio_timer::Delay; + +/// Holds a list of `UnboundedSender`s, each associated with a certain time period. Every time the +/// period elapses, we push an element on the sender. +/// +/// Senders are removed only when they are closed. +pub struct StatusSinks { + entries: FuturesUnordered>, +} + +struct YieldAfter { + delay: tokio_timer::Delay, + interval: Duration, + sender: Option>, +} + +impl StatusSinks { + /// Builds a new empty collection. + pub fn new() -> StatusSinks { + StatusSinks { + entries: FuturesUnordered::new(), + } + } + + /// Adds a sender to the collection. + /// + /// The `interval` is the time period between two pushes on the sender. + pub fn push(&mut self, interval: Duration, sender: mpsc::UnboundedSender) { + self.entries.push(YieldAfter { + delay: Delay::new(Instant::now() + interval), + interval, + sender: Some(sender), + }) + } + + /// Processes all the senders. If any sender is ready, calls the `status_grab` function and + /// pushes what it returns to the sender. + /// + /// This function doesn't return anything, but it should be treated as if it implicitly + /// returns `Ok(Async::NotReady)`. In particular, it should be called again when the task + /// is waken up. + /// + /// # Panic + /// + /// Panics if not called within the context of a task. + pub fn poll(&mut self, mut status_grab: impl FnMut() -> T) { + loop { + match self.entries.poll() { + Ok(Async::Ready(Some((sender, interval)))) => { + let status = status_grab(); + if sender.unbounded_send(status).is_ok() { + self.entries.push(YieldAfter { + // Note that since there's a small delay between the moment a task is + // waken up and the moment it is polled, the period is actually not + // `interval` but `interval + `. We ignore this problem in + // practice. + delay: Delay::new(Instant::now() + interval), + interval, + sender: Some(sender), + }); + } + } + Err(()) | + Ok(Async::Ready(None)) | + Ok(Async::NotReady) => break, + } + } + } +} + +impl Future for YieldAfter { + type Item = (mpsc::UnboundedSender, Duration); + type Error = (); + + fn poll(&mut self) -> Poll { + match self.delay.poll() { + Ok(Async::NotReady) => Ok(Async::NotReady), + Ok(Async::Ready(())) => { + let sender = self.sender.take() + .expect("sender is always Some unless the future is finished; qed"); + Ok(Async::Ready((sender, self.interval))) + }, + Err(_) => Err(()), + } + } +} + +#[cfg(test)] +mod tests { + use super::StatusSinks; + use futures::prelude::*; + use futures::sync::mpsc; + use std::time::Duration; + + #[test] + fn basic_usage() { + let mut status_sinks = StatusSinks::new(); + + let (tx1, rx1) = mpsc::unbounded(); + status_sinks.push(Duration::from_millis(200), tx1); + + let (tx2, rx2) = mpsc::unbounded(); + status_sinks.push(Duration::from_millis(500), tx2); + + let mut runtime = tokio::runtime::Runtime::new().unwrap(); + + let mut val_order = 5; + runtime.spawn(futures::future::poll_fn(move || { + status_sinks.poll(|| { val_order += 1; val_order }); + Ok(Async::NotReady) + })); + + let done = rx1 + .into_future() + .and_then(|(item, rest)| { + assert_eq!(item, Some(6)); + rest.into_future() + }) + .and_then(|(item, _)| { + assert_eq!(item, Some(7)); + rx2.into_future() + }) + .map(|(item, _)| { + assert_eq!(item, Some(8)); + }); + + runtime.block_on(done).unwrap(); + } +} diff --git a/core/service/test/Cargo.toml b/core/service/test/Cargo.toml index aa3dddfc1851e77580fad547ee561d404c0c65d1..872d63415f4e88d5e0e9b88eda8d80ec0c3a7037 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.7.0" +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 c2895c53294965a097e9c98f6a911e492622cdbc..806996576ff90268f2f146c1bd9dfe7ee7ad6eb7 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)); @@ -179,6 +178,7 @@ fn node_config ( chain_spec: (*spec).clone(), custom: Default::default(), name: format!("Node {}", index), + wasm_method: service::config::WasmExecutionMethod::Interpreted, execution_strategies: Default::default(), rpc_http: None, rpc_ws: None, @@ -194,18 +194,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 +226,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 +343,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 = 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 +443,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 = 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 +497,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..ce6300bc4128287e893b47ec4492ce331341619a 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(); @@ -183,7 +186,7 @@ fn record_proof_works() { // Use the proof backend to execute `execute_block`. let mut overlay = Default::default(); - let executor = NativeExecutor::::new(None); + let executor = NativeExecutor::::new(WasmExecutionMethod::Interpreted, None); execution_proof_check_on_trie_backend( &backend, &mut overlay, 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-arithmetic/Cargo.toml b/core/sr-arithmetic/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..3962daf493146929888daafdf9b7c7b5da3a98fd --- /dev/null +++ b/core/sr-arithmetic/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "sr-arithmetic" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +integer-sqrt = "0.1.2" +num-traits = { version = "0.2.8", default-features = false } +rstd = { package = "sr-std", path = "../sr-std", default-features = false } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +substrate-debug-derive = { path = "../primitives/debug-derive", default-features = false } + +[dev-dependencies] +primitive-types = "0.6.0" +rand = "0.7.2" + +[features] +bench = [] +default = ["std"] +std = [ + "codec/std", + "num-traits/std", + "rstd/std", + "serde", + "substrate-debug-derive/std", +] diff --git a/core/sr-arithmetic/fuzzer/.gitignore b/core/sr-arithmetic/fuzzer/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..3ebcb104d4a50a19959dc7ff2bc06ee6bb48b31f --- /dev/null +++ b/core/sr-arithmetic/fuzzer/.gitignore @@ -0,0 +1,2 @@ +hfuzz_target +hfuzz_workspace diff --git a/core/sr-arithmetic/fuzzer/Cargo.lock b/core/sr-arithmetic/fuzzer/Cargo.lock new file mode 100644 index 0000000000000000000000000000000000000000..f6ce6f1d4797dca029231bbe726851badf3e9ddb --- /dev/null +++ b/core/sr-arithmetic/fuzzer/Cargo.lock @@ -0,0 +1,465 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "arbitrary" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitvec" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byte-slice-cast" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byteorder" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "c2-chacha" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +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 = "fixed-hash" +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)", + "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)", + "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "getrandom" +version = "0.1.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)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "honggfuzz" +version = "0.5.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arbitrary 0.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)", + "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "impl-codec" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "parity-scale-codec 1.0.6 (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 = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.65" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num-bigint" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (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)", +] + +[[package]] +name = "num-integer" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parity-scale-codec" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.12 (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.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.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.44 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "primitive-types" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fixed-hash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-codec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "toml 0.5.3 (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 = "proc-macro2" +version = "1.0.6" +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 = "quote" +version = "0.6.13" +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 = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.7.2" +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.65 (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.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_chacha" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.5.1 (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 = "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 = "serde" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (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 = "sr-arithmetic" +version = "2.0.0" +dependencies = [ + "integer-sqrt 0.1.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.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", +] + +[[package]] +name = "sr-arithmetic-fuzzer" +version = "2.0.0" +dependencies = [ + "honggfuzz 0.5.45 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-arithmetic 2.0.0", +] + +[[package]] +name = "sr-std" +version = "2.0.0" +dependencies = [ + "rustc_version 0.2.3 (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 = "syn" +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)", + "quote 0.6.13 (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 = "syn" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (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 = "toml" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "uint" +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)", + "crunchy 0.2.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 = "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 = "wasi" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +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)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (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-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum arbitrary 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64cf76cb6e2222ed0ea86b2b0ee2f71c96ec6edd5af42e84d59160e91b836ec4" +"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" +"checksum bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9633b74910e1870f50f5af189b08487195cdb83c0e27a71d6f64d5e09dd0538b" +"checksum byte-slice-cast 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7cbcbf18128ec71d8d4a0d054461ec59fff5b75b7d10a4c9b7c7cb1a379c3e77" +"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" +"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" +"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +"checksum crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +"checksum fixed-hash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6357b15872f8126e4ea7cf79d579473f132ccd2de239494ad1bf4aa892faea68" +"checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" +"checksum honggfuzz 0.5.45 (registry+https://github.com/rust-lang/crates.io-index)" = "24c27b4aa3049d6d10d8e33d52c9d03ca9aec18f8a449b246f8c4a5b0c10fb34" +"checksum impl-codec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3fa0086251524c50fd53b32e7b05eb6d79e2f97221eaf0c53c0ca9c3096f21d3" +"checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" +"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +"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-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" +"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 ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +"checksum primitive-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97b5a08dda18910f056e5c2060c034e77cab18e0bd7d895e44f03207af4c71d5" +"checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" +"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" +"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.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" +"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" +"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +"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 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 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 static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" +"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 toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" +"checksum uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8f0f47ed099f0db671ce82c66548c5de012e3c0cba3963514d1db15c7588701" +"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 wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" +"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/core/sr-arithmetic/fuzzer/Cargo.toml b/core/sr-arithmetic/fuzzer/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..482905c4350106cffa386455c487c030fab16829 --- /dev/null +++ b/core/sr-arithmetic/fuzzer/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "sr-arithmetic-fuzzer" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sr-arithmetic = { path = ".." } +honggfuzz = "0.5" +primitive-types = "0.6" +num-bigint = "0.2" +num-traits = "0.2" + +[workspace] + +[[bin]] +name = "biguint" +path = "src/biguint.rs" + +[[bin]] +name = "rational128" +path = "src/rational128.rs" diff --git a/core/sr-arithmetic/fuzzer/src/biguint.rs b/core/sr-arithmetic/fuzzer/src/biguint.rs new file mode 100644 index 0000000000000000000000000000000000000000..bd270a97cac7102b37d3bd400f7c02c080e6cdaf --- /dev/null +++ b/core/sr-arithmetic/fuzzer/src/biguint.rs @@ -0,0 +1,181 @@ +// 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 . + +//! # Running +//! Running this fuzzer can be done with `cargo hfuzz run biguint`. `honggfuzz` CLI options can +//! be used by setting `HFUZZ_RUN_ARGS`, such as `-n 4` to use 4 threads. +//! +//! # Debugging a panic +//! Once a panic is found, it can be debugged with +//! `cargo hfuzz run-debug biguint hfuzz_workspace/biguint/*.fuzz`. +//! +//! # More infomation +//! More information about `honggfuzz` can be found +//! [here](https://docs.rs/honggfuzz/). + +use honggfuzz::fuzz; +use sr_arithmetic::biguint::{BigUint, Single}; +use std::convert::TryFrom; + +fn main() { + loop { + fuzz!(|data: (Vec, Vec, bool)| { + let (mut digits_u, mut digits_v, return_remainder) = data; + + let mut u = BigUint::from_limbs(&digits_u); + let mut v = BigUint::from_limbs(&digits_v); + + u.lstrip(); + v.lstrip(); + + let ue = u128::try_from(u.clone()); + let ve = u128::try_from(v.clone()); + + digits_u.reverse(); + digits_v.reverse(); + + let num_u = num_bigint::BigUint::new(digits_u.clone()); + let num_v = num_bigint::BigUint::new(digits_v.clone()); + + if check_digit_lengths(&u, &v, 4) { + assert_eq!(u.cmp(&v), ue.cmp(&ve)); + assert_eq!(u.eq(&v), ue.eq(&ve)); + } + + if check_digit_lengths(&u, &v, 3) { + let expected = ue.unwrap() + ve.unwrap(); + let t = u.clone().add(&v); + assert_eq!( + u128::try_from(t.clone()).unwrap(), expected, + "{:?} + {:?} ===> {:?} != {:?}", u, v, t, expected, + ); + } + + if check_digit_lengths(&u, &v, 4) { + let expected = ue.unwrap().checked_sub(ve.unwrap()); + let t = u.clone().sub(&v); + if expected.is_none() { + assert!(t.is_err()) + } else { + let t = t.unwrap(); + let expected = expected.unwrap(); + assert_eq!( + u128::try_from(t.clone()).unwrap(), expected, + "{:?} - {:?} ===> {:?} != {:?}", u, v, t, expected, + ); + } + } + + if check_digit_lengths(&u, &v, 2) { + let expected = ue.unwrap() * ve.unwrap(); + let t = u.clone().mul(&v); + assert_eq!( + u128::try_from(t.clone()).unwrap(), expected, + "{:?} * {:?} ===> {:?} != {:?}", u, v, t, expected, + ); + } + + if check_digit_lengths(&u, &v, 4) { + let (ue, ve) = (ue.unwrap(), ve.unwrap()); + if ve == 0 { + return; + } + let (q, r) = (ue / ve, ue % ve); + if let Some((qq, rr)) = u.clone().div(&v, true) { + assert_eq!( + u128::try_from(qq.clone()).unwrap(), q, + "{:?} / {:?} ===> {:?} != {:?}", u, v, qq, q, + ); + assert_eq!( + u128::try_from(rr.clone()).unwrap(), r, + "{:?} % {:?} ===> {:?} != {:?}", u, v, rr, r, + ); + } else if v.len() == 1 { + let qq = u.clone().div_unit(ve as Single); + assert_eq!( + u128::try_from(qq.clone()).unwrap(), q, + "[single] {:?} / {:?} ===> {:?} != {:?}", u, v, qq, q, + ); + } else if v.msb() != 0 && u.msb() != 0 && u.len() > v.len() { + panic!("div returned none for an unexpected reason"); + } + } + + // Test against num_bigint + + // Equality + + assert_eq!(u.cmp(&v), num_u.cmp(&num_v)); + + // Addition + + let w = u.clone().add(&v); + let num_w = num_u.clone() + &num_v; + + assert_biguints_eq(&w, &num_w); + + // Subtraction + + if let Ok(w) = u.clone().sub(&v) { + let num_w = num_u.clone() - &num_v; + + assert_biguints_eq(&w, &num_w); + } + + // Multiplication + + let w = u.clone().mul(&v); + let num_w = num_u.clone() * &num_v; + + assert_biguints_eq(&w, &num_w); + + // Division + + if v.len() == 1 && v.get(0) != 0 { + let w = u.clone().div_unit(v.get(0)); + let num_w = num_u.clone() / &num_v; + assert_biguints_eq(&w, &num_w); + } else if u.len() > v.len() && v.len() > 0 { + let num_remainder = num_u.clone() % num_v.clone(); + + let (w, remainder) = u.clone().div(&v, return_remainder).unwrap(); + let num_w = num_u.clone() / &num_v; + + assert_biguints_eq(&w, &num_w); + + if return_remainder { + assert_biguints_eq(&remainder, &num_remainder); + } + } + }); + } +} + +fn check_digit_lengths(u: &BigUint, v: &BigUint, max_limbs: usize) -> bool { + 1 <= u.len() && u.len() <= max_limbs && 1 <= v.len() && v.len() <= max_limbs +} + +fn assert_biguints_eq(a: &BigUint, b: &num_bigint::BigUint) { + let mut a = a.clone(); + a.lstrip(); + + // `num_bigint::BigUint` doesn't expose it's internals, so we need to convert into that to + // compare. + let limbs = (0 .. a.len()).map(|i| a.get(i)).collect(); + let num_a = num_bigint::BigUint::new(limbs); + + assert!(&num_a == b, "\narithmetic: {:?}\nnum-bigint: {:?}", a, b); +} diff --git a/core/sr-arithmetic/fuzzer/src/rational128.rs b/core/sr-arithmetic/fuzzer/src/rational128.rs new file mode 100644 index 0000000000000000000000000000000000000000..b2a00d754527f042cec53f4f6986d8571ad7530e --- /dev/null +++ b/core/sr-arithmetic/fuzzer/src/rational128.rs @@ -0,0 +1,77 @@ +// 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 . + +//! # Running +//! Running this fuzzer can be done with `cargo hfuzz run rational128`. `honggfuzz` CLI options can +//! be used by setting `HFUZZ_RUN_ARGS`, such as `-n 4` to use 4 threads. +//! +//! # Debugging a panic +//! Once a panic is found, it can be debugged with +//! `cargo hfuzz run-debug rational128 hfuzz_workspace/rational128/*.fuzz`. +//! +//! # More infomation +//! More information about `honggfuzz` can be found +//! [here](https://docs.rs/honggfuzz/). + +use honggfuzz::fuzz; +use sr_arithmetic::{helpers_128bit::multiply_by_rational, traits::Zero}; + +fn main() { + loop { + fuzz!(|data: ([u8; 16], [u8; 16], [u8; 16])| { + let (a_bytes, b_bytes, c_bytes) = data; + let (a, b, c) = ( + u128::from_be_bytes(a_bytes), + u128::from_be_bytes(b_bytes), + u128::from_be_bytes(c_bytes), + ); + + println!("++ Equation: {} * {} / {}", a, b, c); + + // The point of this fuzzing is to make sure that `multiply_by_rational` is 100% + // accurate as long as the value fits in a u128. + if let Ok(result) = multiply_by_rational(a, b, c) { + let truth = mul_div(a, b, c); + + if result != truth && result != truth + 1 { + println!("++ Expected {}", truth); + println!("+++++++ Got {}", result); + panic!(); + } + } + }) + } +} + +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() + } +} diff --git a/core/sr-arithmetic/src/biguint.rs b/core/sr-arithmetic/src/biguint.rs new file mode 100644 index 0000000000000000000000000000000000000000..c0836e09b301f4e74d973abb5e90b32481c5dd4f --- /dev/null +++ b/core/sr-arithmetic/src/biguint.rs @@ -0,0 +1,815 @@ +// 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 . + +//! Infinite precision unsigned integer for substrate runtime. + +use num_traits::Zero; +use rstd::{cmp::Ordering, ops, prelude::*, cell::RefCell, convert::TryFrom}; + +// A sensible value for this would be half of the dword size of the host machine. Since the +// runtime is compiled to 32bit webassembly, using 32 and 64 for single and double respectively +// should yield the most performance. +/// Representation of a single limb. +pub type Single = u32; +/// Representation of two limbs. +pub type Double = u64; +/// Difference in the number of bits of [`Single`] and [`Double`]. +const SHIFT: usize = 32; +/// short form of _Base_. Analogous to the value 10 in base-10 decimal numbers. +const B: Double = Single::max_value() as Double + 1; + +/// Splits a [`Double`] limb number into a tuple of two [`Single`] limb numbers. +pub fn split(a: Double) -> (Single, Single) { + let al = a as Single; + let ah = (a >> SHIFT) as Single; + (ah, al) +} + +/// Assumed as a given primitive. +/// +/// Multiplication of two singles, which at most yields 1 double. +pub fn mul_single(a: Single, b: Single) -> Double { + let a: Double = a.into(); + let b: Double = b.into(); + a * b +} + +/// Assumed as a given primitive. +/// +/// Addition of two singles, which at most takes a single limb of result and a carry, +/// returned as a tuple respectively. +pub fn add_single(a: Single, b: Single) -> (Single, Single) { + let a: Double = a.into(); + let b: Double = b.into(); + let q = a + b; + let (carry, r) = split(q); + (r, carry) +} + +/// Assumed as a given primitive. +/// +/// Division of double by a single limb. Always returns a double limb of quotient and a single +/// limb of remainder. +fn div_single(a: Double, b: Single) -> (Double, Single) { + let b: Double = b.into(); + let q = a / b; + let r = a % b; + // both conversions are trivially safe. + (q, r as Single) +} + +/// Simple wrapper around an infinitely large integer, represented as limbs of [`Single`]. +#[derive(Clone, Default)] +pub struct BigUint { + /// digits (limbs) of this number (sorted as msb -> lsd). + pub(crate) digits: Vec, +} + +impl BigUint { + /// Create a new instance with `size` limbs. This prevents any number with zero limbs to be + /// created. + /// + /// The behavior of the type is undefined with zero limbs. + pub fn with_capacity(size: usize) -> Self { + Self { digits: vec![0; size.max(1)] } + } + + /// Raw constructor from custom limbs. If `limbs` is empty, `Zero::zero()` implementation is + /// used. + pub fn from_limbs(limbs: &[Single]) -> Self { + if !limbs.is_empty() { + Self { digits: limbs.to_vec() } + } else { + Zero::zero() + } + } + + /// Number of limbs. + pub fn len(&self) -> usize { self.digits.len() } + + /// A naive getter for limb at `index`. Note that the order is lsb -> msb. + /// + /// #### Panics + /// + /// This panics if index is out of range. + pub fn get(&self, index: usize) -> Single { + self.digits[self.len() - 1 - index] + } + + /// A naive getter for limb at `index`. Note that the order is lsb -> msb. + pub fn checked_get(&self, index: usize) -> Option { + let i = self.len().checked_sub(1)?; + let j = i.checked_sub(index)?; + self.digits.get(j).cloned() + } + + /// A naive setter for limb at `index`. Note that the order is lsb -> msb. + /// + /// #### Panics + /// + /// This panics if index is out of range. + pub fn set(&mut self, index: usize, value: Single) { + let len = self.digits.len(); + self.digits[len - 1 - index] = value; + } + + /// returns the least significant limb of the number. + /// + /// #### Panics + /// + /// While the constructor of the type prevents this, this can panic if `self` has no digits. + pub fn lsb(&self) -> Single { + self.digits[self.len() - 1] + } + + /// returns the most significant limb of the number. + /// + /// #### Panics + /// + /// While the constructor of the type prevents this, this can panic if `self` has no digits. + pub fn msb(&self) -> Single { + self.digits[0] + } + + /// Strips zeros from the left side (the most significant limbs) of `self`, if any. + pub fn lstrip(&mut self) { + // by definition, a big-int number should never have leading zero limbs. This function + // has the ability to cause this. There is nothing to do if the number already has 1 + // limb only. call it a day and return. + if self.len().is_zero() { return; } + let index = self.digits.iter().position(|&elem| elem != 0).unwrap_or(0); + + if index > 0 { + self.digits = self.digits[index..].to_vec() + } + } + + /// Zero-pad `self` from left to reach `size` limbs. Will not make any difference if `self` + /// is already bigger than `size` limbs. + pub fn lpad(&mut self, size: usize) { + let n = self.len(); + if n >= size { return; } + let pad = size - n; + let mut new_digits = (0..pad).map(|_| 0).collect::>(); + new_digits.extend(self.digits.iter()); + self.digits = new_digits; + } + + /// Adds `self` with `other`. self and other do not have to have any particular size. Given + /// that the `n = max{size(self), size(other)}`, it will produce a number with `n + 1` + /// limbs. + /// + /// This function does not strip the output and returns the original allocated `n + 1` + /// limbs. The caller may strip the output if desired. + /// + /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. + pub fn add(self, other: &Self) -> Self { + let n = self.len().max(other.len()); + let mut k: Double = 0; + let mut w = Self::with_capacity(n + 1); + + for j in 0..n { + let u = Double::from(self.checked_get(j).unwrap_or(0)); + let v = Double::from(other.checked_get(j).unwrap_or(0)); + let s = u + v + k; + w.set(j, (s % B) as Single); + k = s / B; + } + // k is always 0 or 1. + w.set(n, k as Single); + w + } + + /// Subtracts `other` from `self`. self and other do not have to have any particular size. + /// Given that the `n = max{size(self), size(other)}`, it will produce a number of size `n`. + /// + /// If `other` is bigger than `self`, `Err(B - borrow)` is returned. + /// + /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. + pub fn sub(self, other: &Self) -> Result { + let n = self.len().max(other.len()); + let mut k = 0; + let mut w = Self::with_capacity(n); + for j in 0..n { + let s = { + let u = Double::from(self.checked_get(j).unwrap_or(0)); + let v = Double::from(other.checked_get(j).unwrap_or(0)); + let mut needs_borrow = false; + let mut t = 0; + + if let Some(v) = u.checked_sub(v) { + if let Some(v2) = v.checked_sub(k) { + t = v2 % B; + k = 0; + } else { + needs_borrow = true; + } + } else { + needs_borrow = true; + } + if needs_borrow { + t = u + B - v - k; + k = 1; + } + t + }; + // PROOF: t either comes from `v2 % B`, or from `u + B - v - k`. The former is + // trivial. The latter will not overflow this branch will only happen if the sum of + // `u - v - k` part has been negative, hence `u + B - v - k < b`. + w.set(j, s as Single); + } + + if k.is_zero() { + Ok(w) + } else { + Err(w) + } + } + + /// Multiplies n-limb number `self` with m-limb number `other`. + /// + /// The resulting number will always have `n + m` limbs. + /// + /// This function does not strip the output and returns the original allocated `n + m` + /// limbs. The caller may strip the output if desired. + /// + /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. + pub fn mul(self, other: &Self) -> Self { + let n = self.len(); + let m = other.len(); + let mut w = Self::with_capacity(m + n); + + for j in 0..n { + if self.get(j) == 0 { + // Note: `with_capacity` allocates with 0. Explicitly set j + m to zero if + // otherwise. + continue; + } + + let mut k = 0; + for i in 0..m { + // PROOF: (B−1) × (B−1) + (B−1) + (B−1) = B^2 −1 < B^2. addition is safe. + let t = + mul_single(self.get(j), other.get(i)) + + Double::from(w.get(i + j)) + + Double::from(k); + w.set(i + j, (t % B) as Single); + // PROOF: (B^2 - 1) / B < B. conversion is safe. + k = (t / B) as Single; + } + w.set(j + m, k); + } + w + } + + /// Divides `self` by a single limb `other`. This can be used in cases where the original + /// division cannot work due to the divisor (`other`) being just one limb. + /// + /// Invariant: `other` cannot be zero. + pub fn div_unit(self, mut other: Single) -> Self { + other = other.max(1); + let n = self.len(); + let mut out = Self::with_capacity(n); + let mut r: Single = 0; + // PROOF: (B-1) * B + (B-1) still fits in double + let with_r = |x: Double, r: Single| { Double::from(r) * B + x }; + for d in (0..n).rev() { + let (q, rr) = div_single(with_r(self.get(d).into(), r), other) ; + out.set(d, q as Single); + r = rr; + } + out + } + + /// Divides an `n + m` limb self by a `n` limb `other`. The result is a `m + 1` limb + /// quotient and a `n` limb remainder, if enabled by passing `true` in `rem` argument, both + /// in the form of an option's `Ok`. + /// + /// - requires `other` to be stripped and have no leading zeros. + /// - requires `self` to be stripped and have no leading zeros. + /// - requires `other` to have at least two limbs. + /// - requires `self` to have a greater length compared to `other`. + /// + /// All arguments are examined without being stripped for the above conditions. If any of + /// the above fails, `None` is returned.` + /// + /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. + pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> { + if other.len() <= 1 + || other.msb() == 0 + || self.msb() == 0 + || self.len() <= other.len() + { + return None + } + let n = other.len(); + let m = self.len() - n; + + let mut q = Self::with_capacity(m + 1); + let mut r = Self::with_capacity(n); + + // PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are + // safe. + let normalizer_bits = other.msb().leading_zeros() as Single; + let normalizer = (2 as Single).pow(normalizer_bits as u32) as Single; + + // step D1. + let mut self_norm = self.mul(&Self::from(normalizer)); + let mut other_norm = other.clone().mul(&Self::from(normalizer)); + + // defensive only; the mul implementation should always create this. + self_norm.lpad(n + m + 1); + other_norm.lstrip(); + + // step D2. + for j in (0..=m).rev() { + // step D3.0 Find an estimate of q[j], named qhat. + let (qhat, rhat) = { + // PROOF: this always fits into `Double`. In the context of Single = u8, and + // Double = u16, think of 255 * 256 + 255 which is just u16::max_value(). + let dividend = + Double::from(self_norm.get(j + n)) + * B + + Double::from(self_norm.get(j + n - 1)); + let divisor = other_norm.get(n - 1); + div_single(dividend, divisor) + }; + + // D3.1 test qhat + // replace qhat and rhat with RefCells. This helps share state with the closure + let qhat = RefCell::new(qhat); + let rhat = RefCell::new(Double::from(rhat)); + + let test = || { + // decrease qhat if it is bigger than the base (B) + let qhat_local = *qhat.borrow(); + let rhat_local = *rhat.borrow(); + let predicate_1 = qhat_local >= B; + let predicate_2 = { + let lhs = qhat_local * Double::from(other_norm.get(n - 2)); + let rhs = B * rhat_local + Double::from(self_norm.get(j + n - 2)); + lhs > rhs + }; + if predicate_1 || predicate_2 { + *qhat.borrow_mut() -= 1; + *rhat.borrow_mut() += Double::from(other_norm.get(n - 1)); + true + } else { + false + } + }; + + test(); + while (*rhat.borrow() as Double) < B { + if !test() { break; } + } + + let qhat = qhat.into_inner(); + // we don't need rhat anymore. just let it go out of scope when it does. + + // step D4 + let lhs = Self { digits: (j..=j+n).rev().map(|d| self_norm.get(d)).collect() }; + let rhs = other_norm.clone().mul(&Self::from(qhat)); + + let maybe_sub = lhs.sub(&rhs); + let mut negative = false; + let sub = match maybe_sub { + Ok(t) => t, + Err(t) => { negative = true; t } + }; + (j..=j+n).for_each(|d| { self_norm.set(d, sub.get(d - j)); }); + + // step D5 + // PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion + // is safe. + q.set(j, qhat as Single); + + // step D6: add back if negative happened. + if negative { + q.set(j, q.get(j) - 1); + let u = Self { digits: (j..=j+n).rev().map(|d| self_norm.get(d)).collect() }; + let r = other_norm.clone().add(&u); + (j..=j+n).rev().for_each(|d| { self_norm.set(d, r.get(d - j)); }) + } + } + + // if requested, calculate remainder. + if rem { + // undo the normalization. + if normalizer_bits > 0 { + let s = SHIFT as u32; + let nb = normalizer_bits; + for d in 0..n-1 { + let v = self_norm.get(d) >> nb + | self_norm.get(d + 1).overflowing_shl(s - nb).0; + r.set(d, v); + } + r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits); + } else { + r = self_norm; + } + } + + Some((q, r)) + } +} + +impl rstd::fmt::Debug for BigUint { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { + write!( + f, + "BigUint {{ {:?} ({:?})}}", + self.digits, + u128::try_from(self.clone()).unwrap_or(0), + ) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { + Ok(()) + } + +} + +impl PartialEq for BigUint { + fn eq(&self, other: &Self) -> bool { + self.cmp(other) == Ordering::Equal + } +} + +impl Eq for BigUint {} + +impl Ord for BigUint { + fn cmp(&self, other: &Self) -> Ordering { + let lhs_first = self.digits.iter().position(|&e| e != 0); + let rhs_first = other.digits.iter().position(|&e| e != 0); + + match (lhs_first, rhs_first) { + // edge cases that should not happen. This basically means that one or both were + // zero. + (None, None) => Ordering::Equal, + (Some(_), None) => Ordering::Greater, + (None, Some(_)) => Ordering::Less, + (Some(lhs_idx), Some(rhs_idx)) => { + let lhs = &self.digits[lhs_idx..]; + let rhs = &other.digits[rhs_idx..]; + let len_cmp = lhs.len().cmp(&rhs.len()); + match len_cmp { + Ordering::Equal => lhs.cmp(rhs), + _ => len_cmp, + } + } + } + } +} + +impl PartialOrd for BigUint { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl ops::Add for BigUint { + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + self.add(&rhs) + } +} + +impl ops::Sub for BigUint { + type Output = Self; + fn sub(self, rhs: Self) -> Self::Output { + self.sub(&rhs).unwrap_or_else(|e| e) + } +} + +impl ops::Mul for BigUint { + type Output = Self; + fn mul(self, rhs: Self) -> Self::Output { + self.mul(&rhs) + } +} + +impl Zero for BigUint { + fn zero() -> Self { + Self { digits: vec![Zero::zero()] } + } + + fn is_zero(&self) -> bool { + self.digits.iter().all(|d| d.is_zero()) + } +} + +macro_rules! impl_try_from_number_for { + ($([$type:ty, $len:expr]),+) => { + $( + impl TryFrom for $type { + type Error = &'static str; + fn try_from(mut value: BigUint) -> Result<$type, Self::Error> { + value.lstrip(); + let error_message = concat!("cannot fit a number into ", stringify!($type)); + if value.len() * SHIFT > $len { + Err(error_message) + } else { + let mut acc: $type = Zero::zero(); + for (i, d) in value.digits.iter().rev().cloned().enumerate() { + let d: $type = d.into(); + acc += d << (SHIFT * i); + } + Ok(acc) + } + } + } + )* + }; +} +// can only be implemented for sizes bigger than two limb. +impl_try_from_number_for!([u128, 128], [u64, 64]); + +macro_rules! impl_from_for_smaller_than_word { + ($($type:ty),+) => { + $(impl From<$type> for BigUint { + fn from(a: $type) -> Self { + Self { digits: vec! [a.into()] } + } + })* + } +} +impl_from_for_smaller_than_word!(u8, u16, Single); + +impl From for BigUint { + fn from(a: Double) -> Self { + let (ah, al) = split(a); + Self { digits: vec![ah, al] } + } +} + +#[cfg(test)] +pub mod tests { + use super::*; + #[cfg(feature = "bench")] + use test::Bencher; + + fn with_limbs(n: usize) -> BigUint { + BigUint { digits: vec![1; n] } + } + + #[test] + fn split_works() { + let a = SHIFT / 2; + let b = SHIFT * 3 / 2; + let num: Double = 1 << a | 1 << b; + // example when `Single = u8` + // assert_eq!(num, 0b_0001_0000_0001_0000) + assert_eq!(split(num), (1 << a, 1 << a)); + } + + #[test] + fn strip_works() { + let mut a = BigUint::from_limbs(&[0, 1, 0]); + a.lstrip(); + assert_eq!(a, BigUint { digits: vec![1, 0] }); + + let mut a = BigUint::from_limbs(&[0, 0, 1]); + a.lstrip(); + assert_eq!(a, BigUint { digits: vec![1] }); + + let mut a = BigUint::from_limbs(&[0, 0]); + a.lstrip(); + assert_eq!(a, BigUint { digits: vec![0] }); + + let mut a = BigUint::from_limbs(&[0, 0, 0]); + a.lstrip(); + assert_eq!(a, BigUint { digits: vec![0] }); + } + + #[test] + fn lpad_works() { + let mut a = BigUint::from_limbs(&[0, 1, 0]); + a.lpad(2); + assert_eq!(a.digits, vec![0, 1, 0]); + + let mut a = BigUint::from_limbs(&[0, 1, 0]); + a.lpad(3); + assert_eq!(a.digits, vec![0, 1, 0]); + + let mut a = BigUint::from_limbs(&[0, 1, 0]); + a.lpad(4); + assert_eq!(a.digits, vec![0, 0, 1, 0]); + } + + #[test] + fn equality_works() { + assert_eq!( + BigUint { digits: vec![1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, + true, + ); + assert_eq!( + BigUint { digits: vec![3, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, + false, + ); + assert_eq!( + BigUint { digits: vec![0, 1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, + true, + ); + } + + #[test] + fn ordering_works() { + assert!(BigUint { digits: vec![0] } < BigUint { digits: vec![1] }); + assert!(BigUint { digits: vec![0] } == BigUint { digits: vec![0] }); + assert!(BigUint { digits: vec![] } == BigUint { digits: vec![0] }); + assert!(BigUint { digits: vec![] } == BigUint { digits: vec![] }); + assert!(BigUint { digits: vec![] } < BigUint { digits: vec![1] }); + + assert!(BigUint { digits: vec![1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }); + assert!(BigUint { digits: vec![0, 1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }); + + assert!(BigUint { digits: vec![1, 2, 4] } > BigUint { digits: vec![1, 2, 3] }); + assert!(BigUint { digits: vec![0, 1, 2, 4] } > BigUint { digits: vec![1, 2, 3] }); + assert!(BigUint { digits: vec![1, 2, 1, 0] } > BigUint { digits: vec![1, 2, 3] }); + + assert!(BigUint { digits: vec![0, 1, 2, 1] } < BigUint { digits: vec![1, 2, 3] }); + } + + #[test] + fn can_try_build_numbers_from_types() { + use rstd::convert::TryFrom; + assert_eq!(u64::try_from(with_limbs(1)).unwrap(), 1); + assert_eq!(u64::try_from(with_limbs(2)).unwrap(), u32::max_value() as u64 + 2); + assert_eq!( + u64::try_from(with_limbs(3)).unwrap_err(), + "cannot fit a number into u64", + ); + assert_eq!( + u128::try_from(with_limbs(3)).unwrap(), + u32::max_value() as u128 + u64::max_value() as u128 + 3 + ); + } + + #[test] + fn zero_works() { + assert_eq!(BigUint::zero(), BigUint { digits: vec![0] }); + assert_eq!(BigUint { digits: vec![0, 1, 0] }.is_zero(), false); + assert_eq!(BigUint { digits: vec![0, 0, 0] }.is_zero(), true); + + let a = BigUint::zero(); + let b = BigUint::zero(); + let c = a * b; + assert_eq!(c.digits, vec![0, 0]); + } + + #[test] + fn sub_negative_works() { + assert_eq!( + BigUint::from(10 as Single).sub(&BigUint::from(5 as Single)).unwrap(), + BigUint::from(5 as Single) + ); + assert_eq!( + BigUint::from(10 as Single).sub(&BigUint::from(10 as Single)).unwrap(), + BigUint::from(0 as Single) + ); + assert_eq!( + BigUint::from(10 as Single).sub(&BigUint::from(13 as Single)).unwrap_err(), + BigUint::from((B - 3) as Single), + ); + } + + #[test] + fn mul_always_appends_one_digit() { + let a = BigUint::from(10 as Single); + let b = BigUint::from(4 as Single); + assert_eq!(a.len(), 1); + assert_eq!(b.len(), 1); + + let n = a.mul(&b); + + assert_eq!(n.len(), 2); + assert_eq!(n.digits, vec![0, 40]); + } + + #[test] + fn div_conditions_work() { + let a = BigUint { digits: vec![2] }; + let b = BigUint { digits: vec![1, 2] }; + let c = BigUint { digits: vec![1, 1, 2] }; + let d = BigUint { digits: vec![0, 2] }; + let e = BigUint { digits: vec![0, 1, 1, 2] }; + + assert!(a.clone().div(&b, true).is_none()); + assert!(c.clone().div(&a, true).is_none()); + assert!(c.clone().div(&d, true).is_none()); + assert!(e.clone().div(&a, true).is_none()); + + assert!(c.clone().div(&b, true).is_some()); + } + + #[test] + fn div_unit_works() { + let a = BigUint { digits: vec![100] }; + let b = BigUint { digits: vec![1, 100] }; + + assert_eq!(a.clone().div_unit(1), a); + assert_eq!(a.clone().div_unit(0), a); + assert_eq!(a.clone().div_unit(2), BigUint::from(50 as Single)); + assert_eq!(a.clone().div_unit(7), BigUint::from(14 as Single)); + + assert_eq!(b.clone().div_unit(1), b); + assert_eq!(b.clone().div_unit(0), b); + assert_eq!(b.clone().div_unit(2), BigUint::from(((B + 100) / 2) as Single)); + assert_eq!(b.clone().div_unit(7), BigUint::from(((B + 100) / 7) as Single)); + + } + + #[cfg(feature = "bench")] + fn random_big_uint(size: usize) -> BigUint { + use rand::Rng; + let mut rng = rand::thread_rng(); + let digits = (0..size).map(|_| rng.gen_range(0, Single::max_value())).collect(); + BigUint { digits } + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_addition_2_digit(bencher: &mut Bencher) { + let a = random_big_uint(2); + let b = random_big_uint(2); + bencher.iter(|| { + let _ = a.clone().add(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_addition_4_digit(bencher: &mut Bencher) { + let a = random_big_uint(4); + let b = random_big_uint(4); + bencher.iter(|| { + let _ = a.clone().add(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_subtraction_2_digit(bencher: &mut Bencher) { + let a = random_big_uint(2); + let b = random_big_uint(2); + bencher.iter(|| { + let _ = a.clone().sub(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_subtraction_4_digit(bencher: &mut Bencher) { + let a = random_big_uint(4); + let b = random_big_uint(4); + bencher.iter(|| { + let _ = a.clone().sub(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_multiplication_2_digit(bencher: &mut Bencher) { + let a = random_big_uint(2); + let b = random_big_uint(2); + bencher.iter(|| { + let _ = a.clone().mul(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_multiplication_4_digit(bencher: &mut Bencher) { + let a = random_big_uint(4); + let b = random_big_uint(4); + bencher.iter(|| { + let _ = a.clone().mul(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_division_4_digit(bencher: &mut Bencher) { + let a = random_big_uint(4); + let b = random_big_uint(2); + bencher.iter(|| { + let _ = a.clone().div(&b, true); + }); + } +} diff --git a/core/sr-arithmetic/src/fixed64.rs b/core/sr-arithmetic/src/fixed64.rs new file mode 100644 index 0000000000000000000000000000000000000000..bd58e36940ae6c1887302fd0ded53ba56232e244 --- /dev/null +++ b/core/sr-arithmetic/src/fixed64.rs @@ -0,0 +1,244 @@ +// 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::{ + ops, prelude::*, + convert::{TryFrom, TryInto}, +}; +use codec::{Encode, Decode}; +use crate::{ + Perbill, + traits::{ + SaturatedConversion, CheckedSub, CheckedAdd, Bounded, UniqueSaturatedInto, Saturating + } +}; + +/// 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. +#[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 + } + + /// Consume self and return the inner value. + /// + /// This should only be used for testing. + #[cfg(any(feature = "std", test))] + pub fn into_inner(self) -> i64 { self.0 } + + /// 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( + (i128::from(n).saturating_mul(i128::from(DIV)) / i128::from(d).max(1)) + .try_into() + .unwrap_or_else(|_| 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 { + self.0.checked_sub(rhs.0).map(Self) + } +} + +impl CheckedAdd for Fixed64 { + fn checked_add(&self, rhs: &Self) -> Option { + self.0.checked_add(rhs.0).map(Self) + } +} + +impl rstd::fmt::Debug for Fixed64 { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + write!(f, "Fixed64({},{})", self.0 / DIV, (self.0 % DIV) / 1000) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } +} + +#[cfg(test)] +mod tests { + 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)); + } + + #[test] + fn fixed_64_growth_decrease_curve() { + let test_set = vec![0u32, 1, 10, 1000, 1_000_000_000]; + + // negative (1/2) + let mut fm = Fixed64::from_rational(-1, 2); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i) as i32, i as i32 - i as i32 / 2); + }); + + // unit (1) multiplier + fm = Fixed64::from_parts(0); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i), i); + }); + + // i.5 multiplier + fm = Fixed64::from_rational(1, 2); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i), i * 3 / 2); + }); + + // dual multiplier + fm = Fixed64::from_rational(1, 1); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i), i * 2); + }); + } + + 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-arithmetic/src/helpers_128bit.rs b/core/sr-arithmetic/src/helpers_128bit.rs new file mode 100644 index 0000000000000000000000000000000000000000..10cc94ae777e66d2f802a464947f7bce4385301e --- /dev/null +++ b/core/sr-arithmetic/src/helpers_128bit.rs @@ -0,0 +1,112 @@ +// 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 . + +//! 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. + +use crate::biguint; +use num_traits::Zero; +use rstd::{cmp::{min, max}, convert::TryInto, mem}; + +/// 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!(), + } +} + +/// split a u128 into two u64 limbs +pub fn split(a: u128) -> (u64, u64) { + let al = a as u64; + let ah = (a >> 64) as u64; + (ah, al) +} + +/// Convert a u128 to a u32 based biguint. +pub fn to_big_uint(x: u128) -> biguint::BigUint { + let (xh, xl) = split(x); + let (xhh, xhl) = biguint::split(xh); + let (xlh, xll) = biguint::split(xl); + let mut n = biguint::BigUint::from_limbs(&[xhh, xhl, xlh, xll]); + n.lstrip(); + n +} + +/// Safely and accurately compute `a * b / c`. The approach is: +/// - Simply try `a * b / c`. +/// - Else, convert them both into big numbers and re-try. `Err` is returned if the result +/// cannot be safely casted back to u128. +/// +/// Invariant: c must be greater than or equal to 1. +pub fn multiply_by_rational(mut a: u128, mut b: u128, mut c: u128) -> Result { + if a.is_zero() || b.is_zero() { return Ok(Zero::zero()); } + 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. + if b > a { + mem::swap(&mut a, &mut b); + } + + // Attempt to perform the division first + if a % c == 0 { + a /= c; + c = 1; + } else if b % c == 0 { + b /= c; + c = 1; + } + + if let Some(x) = a.checked_mul(b) { + // This is the safest way to go. Try it. + Ok(x / c) + } else { + let a_num = to_big_uint(a); + let b_num = to_big_uint(b); + let c_num = to_big_uint(c); + + let mut ab = a_num * b_num; + ab.lstrip(); + let mut q = if c_num.len() == 1 { + // PROOF: if `c_num.len() == 1` then `c` fits in one limb. + ab.div_unit(c as biguint::Single) + } else { + // PROOF: both `ab` and `c` cannot have leading zero limbs; if length of `c` is 1, + // the previous branch would handle. Also, if ab for sure has a bigger size than + // c, because `a.checked_mul(b)` has failed, hence ab must be at least one limb + // bigger than c. In this case, returning zero is defensive-only and div should + // always return Some. + let (mut q, r) = ab.div(&c_num, true).unwrap_or((Zero::zero(), Zero::zero())); + let r: u128 = r.try_into() + .expect("reminder of div by c is always less than c; qed"); + if r > (c / 2) { q = q.add(&to_big_uint(1)); } + q + }; + q.lstrip(); + q.try_into().map_err(|_| "result cannot fit in u128") + } +} diff --git a/core/sr-arithmetic/src/lib.rs b/core/sr-arithmetic/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..847ca9e797cb05c695d4cfc6948cbd14444fba6c --- /dev/null +++ b/core/sr-arithmetic/src/lib.rs @@ -0,0 +1,48 @@ +// 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_attr(not(feature = "std"), no_std)] + +// to allow benchmarking +#![cfg_attr(feature = "bench", feature(test))] +#[cfg(feature = "bench")] extern crate test; + +/// Copied from `sr-primitives` and documented there. +#[cfg(test)] +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, + ); + }; +} + +pub mod biguint; +pub mod helpers_128bit; +pub mod traits; +mod per_things; +mod fixed64; +mod rational128; + +pub use fixed64::Fixed64; +pub use per_things::{Percent, Permill, Perbill, Perquintill}; +pub use rational128::Rational128; diff --git a/core/sr-arithmetic/src/per_things.rs b/core/sr-arithmetic/src/per_things.rs new file mode 100644 index 0000000000000000000000000000000000000000..2dd1e62d0b4db7aa45cd39b5ed3088fb84167013 --- /dev/null +++ b/core/sr-arithmetic/src/per_things.rs @@ -0,0 +1,520 @@ +// 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(feature = "std")] +use serde::{Serialize, Deserialize}; + +use rstd::{ops, prelude::*, convert::TryInto}; +use codec::{Encode, Decode, CompactAs}; +use crate::traits::{SaturatedConversion, UniqueSaturatedInto, Saturating}; +use substrate_debug_derive::RuntimeDebug; + +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, Ord, PartialOrd))] + #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, RuntimeDebug, CompactAs)] + 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 = <$upper_type>::from($max) * <$upper_type>::from($max); + 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 + * <$upper_type>::from($max) + / 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 = <$upper_type>::from($max); + 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 + } + } + + #[cfg(test)] + mod $test_mod { + use codec::{Encode, Decode}; + use super::{$name, Saturating, RuntimeDebug}; + use crate::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!(<$upper_type>::from($max) < <$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!(<$upper_type>::from($max).checked_mul($max.into()).is_some()); + } + + #[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug)] + 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: 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 = <$upper_type>::from($max); + // 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 * <$upper_type>::from($max) / 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_", +); diff --git a/core/sr-arithmetic/src/rational128.rs b/core/sr-arithmetic/src/rational128.rs new file mode 100644 index 0000000000000000000000000000000000000000..3247321199d6142e05fd8a11befcaad3e3e16186 --- /dev/null +++ b/core/sr-arithmetic/src/rational128.rs @@ -0,0 +1,384 @@ +// 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::{cmp::Ordering, prelude::*}; +use crate::helpers_128bit; +use num_traits::Zero; +use substrate_debug_derive::RuntimeDebug; + +/// A wrapper for any rational number with a 128 bit numerator and denominator. +#[derive(Clone, Copy, Default, Eq, RuntimeDebug)] +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 { + helpers_128bit::multiply_by_rational(self.0, den, self.1).map(|n| Self(n, 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).map_err(|_| "failed to scale to denominator")?; + let self_scaled = self.to_den(lcm).map_err(|_| "failed to scale to denominator")?; + let other_scaled = other.to_den(lcm).map_err(|_| "failed to scale to denominator")?; + 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).map_err(|_| "failed to scale to denominator")?; + let self_scaled = self.to_den(lcm).map_err(|_| "failed to scale to denominator")?; + let other_scaled = other.to_den(lcm).map_err(|_| "failed to scale to denominator")?; + + 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)) + } +} + +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 { + // Don't even compute gcd. + let self_n = helpers_128bit::to_big_uint(self.0) * helpers_128bit::to_big_uint(other.1); + let other_n = helpers_128bit::to_big_uint(other.0) * helpers_128bit::to_big_uint(self.1); + self_n.cmp(&other_n) + } + } +} + +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 { + let self_n = helpers_128bit::to_big_uint(self.0) * helpers_128bit::to_big_uint(other.1); + let other_n = helpers_128bit::to_big_uint(other.0) * helpers_128bit::to_big_uint(self.1); + self_n.eq(&other_n) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use super::helpers_128bit::*; + + 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(10, 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("result cannot fit in u128"), + ); + 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("failed to scale to denominator"), + ); + 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("failed to scale to denominator"), + ); + 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); + + 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, + ); + + assert_eq!( + multiply_by_rational(2u128.pow(66) - 1, 2u128.pow(65) - 1, 2u128.pow(65)).unwrap(), + 73786976294838206461, + ); + assert_eq!( + multiply_by_rational(1_000_000_000, MAX128 / 8, MAX128 / 2).unwrap(), + 250000000, + ); + } + + #[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] + #[ignore] + fn multiply_by_rational_fuzzed_equation() { + assert_eq!( + multiply_by_rational(154742576605164960401588224, 9223376310179529214, 549756068598), + Ok(2596149632101417846585204209223679) + ); + } +} diff --git a/core/sr-arithmetic/src/traits.rs b/core/sr-arithmetic/src/traits.rs new file mode 100644 index 0000000000000000000000000000000000000000..d02425066ff9d7f8e34efe6e73b94262ba197b64 --- /dev/null +++ b/core/sr-arithmetic/src/traits.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 . + +//! Primitives for the runtime modules. + +use rstd::{self, convert::{TryFrom, TryInto}}; +use codec::HasCompact; +pub use integer_sqrt::IntegerSquareRoot; +pub use num_traits::{ + Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, + CheckedShl, CheckedShr +}; +use rstd::ops::{ + Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, + RemAssign, Shl, Shr +}; + +/// A meta trait for arithmetic. +/// +/// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to +/// be able to represent at least `u32` values without loss, hence the trait implies `From` +/// and smaller ints. All other conversions are fallible. +pub trait SimpleArithmetic: + Zero + One + IntegerSquareRoot + + From + From + From + TryInto + TryInto + TryInto + + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + + UniqueSaturatedInto + UniqueSaturatedInto + UniqueSaturatedInto + + UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + + Add + AddAssign + + Sub + SubAssign + + Mul + MulAssign + + Div + DivAssign + + Rem + RemAssign + + Shl + Shr + + CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + + Saturating + PartialOrd + Ord + Bounded + + HasCompact + Sized +{} +impl + From + From + TryInto + TryInto + TryInto + + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + + UniqueSaturatedInto + UniqueSaturatedInto + UniqueSaturatedInto + + UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + + Add + AddAssign + + Sub + SubAssign + + Mul + MulAssign + + Div + DivAssign + + Rem + RemAssign + + Shl + Shr + + CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + + Saturating + PartialOrd + Ord + Bounded + + HasCompact + Sized +> SimpleArithmetic for T {} + +/// Just like `From` except that if the source value is too big to fit into the destination type +/// then it'll saturate the destination. +pub trait UniqueSaturatedFrom: Sized { + /// Convert from a value of `T` into an equivalent instance of `Self`. + fn unique_saturated_from(t: T) -> Self; +} + +/// Just like `Into` except that if the source value is too big to fit into the destination type +/// then it'll saturate the destination. +pub trait UniqueSaturatedInto: Sized { + /// Consume self to return an equivalent value of `T`. + fn unique_saturated_into(self) -> T; +} + +impl + Bounded + Sized> UniqueSaturatedFrom for S { + fn unique_saturated_from(t: T) -> Self { + S::try_from(t).unwrap_or_else(|_| Bounded::max_value()) + } +} + +impl + Sized> UniqueSaturatedInto for S { + fn unique_saturated_into(self) -> T { + self.try_into().unwrap_or_else(|_| Bounded::max_value()) + } +} + +/// Simple trait to use checked mul and max value to give a saturated mul operation over +/// supported types. +pub trait Saturating { + /// Saturated addition - if the product can't fit in the type then just use max-value. + fn saturating_add(self, o: Self) -> Self; + + /// Saturated subtraction - if the product can't fit in the type then just use max-value. + fn saturating_sub(self, o: Self) -> Self; + + /// Saturated multiply - if the product can't fit in the type then just use max-value. + fn saturating_mul(self, o: Self) -> Self; +} + +impl Saturating for T { + fn saturating_add(self, o: Self) -> Self { + ::saturating_add(self, o) + } + fn saturating_sub(self, o: Self) -> Self { + ::saturating_sub(self, o) + } + fn saturating_mul(self, o: Self) -> Self { + self.checked_mul(&o).unwrap_or_else(Bounded::max_value) + } +} + +/// Convenience type to work around the highly unergonomic syntax needed +/// to invoke the functions of overloaded generic traits, in this case +/// `SaturatedFrom` and `SaturatedInto`. +pub trait SaturatedConversion { + /// Convert from a value of `T` into an equivalent instance of `Self`. + /// + /// This just uses `UniqueSaturatedFrom` internally but with this + /// variant you can provide the destination type using turbofish syntax + /// in case Rust happens not to assume the correct type. + fn saturated_from(t: T) -> Self where Self: UniqueSaturatedFrom { + >::unique_saturated_from(t) + } + + /// Consume self to return an equivalent value of `T`. + /// + /// This just uses `UniqueSaturatedInto` internally but with this + /// variant you can provide the destination type using turbofish syntax + /// in case Rust happens not to assume the correct type. + fn saturated_into(self) -> T where Self: UniqueSaturatedInto { + >::unique_saturated_into(self) + } +} +impl SaturatedConversion for T {} diff --git a/core/sr-io/Cargo.toml b/core/sr-io/Cargo.toml index f3122f0e3029fd65dc4eebc76a6b637595e0e7fe..4d140d289dafe3d1033243f59f7fcc09bd8e5fe2 100644 --- a/core/sr-io/Cargo.toml +++ b/core/sr-io/Cargo.toml @@ -6,21 +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.2", 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 } +primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } +rstd = { package = "sr-std", path = "../sr-std", default-features = false } +libsecp256k1 = { version = "0.3.0", optional = true } +tiny-keccak = { version = "1.5.0", optional = true } substrate-state-machine = { path = "../state-machine", optional = true } trie = { package = "substrate-trie", path = "../trie", optional = true } - -[dev-dependencies] -substrate-offchain = { path = "../offchain" } +externalities = { package = "substrate-externalities", path = "../externalities", optional = true } +log = { version = "0.4.8", optional = true } [features] default = ["std"] @@ -30,13 +28,18 @@ std = [ "rstd/std", "hash-db/std", "trie", - "environmental", "substrate-state-machine", "libsecp256k1", - "tiny-keccak" + "tiny-keccak", + "externalities", + "log", ] 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 b79c13fb12934d20456d95d882ab96af8975cd96..fe5e50b3eda3e8defce026001755e199dcea1b53 100644 --- a/core/sr-io/src/lib.rs +++ b/core/sr-io/src/lib.rs @@ -26,18 +26,14 @@ #![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, }, + LogLevel, }; /// Error verifying ECDSA signature @@ -50,14 +46,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 +55,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 +65,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 +141,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 +153,26 @@ 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]); + + /// Request to print a log message (stderr) on the host. + /// + /// Note that this will be only displayed if the host + /// is enabed to display log messages with given + /// level and target. + /// + /// Instead of using directly, prefer setting up `RuntimeLogger` + /// and using `log` macros. + fn log( + level: LogLevel, + target: &[u8], + message: &[u8] + ); } } @@ -203,10 +188,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 +208,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. /// @@ -235,15 +220,20 @@ export_api! { /// Verify and recover a SECP256k1 ECDSA signature. /// - `sig` is passed in RSV format. V should be either 0/1 or 27/28. - /// - returns `Err` if the signature is bad, otherwise the 64-byte pubkey (doesn't include the 0x04 prefix). + /// - returns `Err` if the signature is bad, otherwise the 64-byte raw pubkey (doesn't include the 0x04 prefix). fn secp256k1_ecdsa_recover(sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 64], EcdsaVerifyError>; + + /// Verify and recover a SECP256k1 ECDSA signature. + /// - `sig` is passed in RSV format. V should be either 0/1 or 27/28. + /// - returns `Err` if the signature is bad, otherwise the 33-byte compressed pubkey. + fn secp256k1_ecdsa_recover_compressed(sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 33], EcdsaVerifyError>; } } export_api! { pub(crate) trait HashingApi { /// Conduct a 256-bit Keccak hash. - fn keccak_256(data: &[u8]) -> [u8; 32] ; + fn keccak_256(data: &[u8]) -> [u8; 32]; /// Conduct a 128-bit Blake2 hash. fn blake2_128(data: &[u8]) -> [u8; 16]; @@ -273,7 +263,7 @@ export_api! { /// 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; @@ -309,7 +299,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. @@ -326,14 +316,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. @@ -345,7 +335,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. @@ -357,16 +347,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. /// @@ -379,7 +367,7 @@ export_api! { fn http_response_read_body( request_id: HttpRequestId, buffer: &mut [u8], - deadline: Option + deadline: Option, ) -> Result; } } @@ -400,13 +388,10 @@ mod imp { } #[cfg(feature = "std")] -pub use self::imp::{ - StorageOverlay, ChildrenStorageOverlay, with_storage, - with_externalities -}; +pub use self::imp::{StorageOverlay, ChildrenStorageOverlay, with_storage}; #[cfg(not(feature = "std"))] pub use self::imp::ext::*; /// Type alias for Externalities implementation used in tests. #[cfg(feature = "std")] -pub type TestExternalities = self::imp::TestExternalities; +pub type TestExternalities = self::imp::TestExternalities; diff --git a/core/sr-io/with_std.rs b/core/sr-io/with_std.rs index 8e6a160cf203a041c134e099520bf33133b09d20..fdd32124c129c8bd172d410c1a2ce7ad4876ad68 100644 --- a/core/sr-io/with_std.rs +++ b/core/sr-io/with_std.rs @@ -15,21 +15,19 @@ // 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::KeystoreExt, storage::ChildStorageKey, hexdisplay::HexDisplay, Hasher, + offchain::{self, OffchainExt}, }; // 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}; -environmental!(ext: trait Externalities); +use externalities::{with_externalities, set_and_run_with_externalities, ExternalitiesExt}; /// Additional bounds for `Hasher` trait for with_std. pub trait HasherBounds {} @@ -40,7 +38,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"), @@ -49,21 +47,21 @@ fn child_storage_key_or_panic(storage_key: &[u8]) -> ChildStorageKey Option> { - ext::with(|ext| ext.storage(key).map(|s| s.to_vec())) + with_externalities(|ext| ext.storage(key).map(|s| s.to_vec())) .expect("storage cannot be called outside of an Externalities-provided environment.") } 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]); + with_externalities(|ext| ext.storage(key).map(|value| { + 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.") } fn child_storage(storage_key: &[u8], key: &[u8]) -> Option> { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.child_storage(storage_key, key).map(|s| s.to_vec()) }) @@ -71,7 +69,7 @@ impl StorageApi for () { } fn set_storage(key: &[u8], value: &[u8]) { - ext::with(|ext| + with_externalities(|ext| ext.set_storage(key.to_vec(), value.to_vec()) ); } @@ -82,13 +80,13 @@ impl StorageApi for () { value_out: &mut [u8], value_offset: usize, ) -> Option { - ext::with(|ext| { + with_externalities(|ext| { 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() }) }) @@ -96,115 +94,126 @@ impl StorageApi for () { } fn set_child_storage(storage_key: &[u8], key: &[u8], value: &[u8]) { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.set_child_storage(storage_key, key.to_vec(), value.to_vec()) }); } fn clear_storage(key: &[u8]) { - ext::with(|ext| + with_externalities(|ext| ext.clear_storage(key) ); } fn clear_child_storage(storage_key: &[u8], key: &[u8]) { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.clear_child_storage(storage_key, key) }); } fn kill_child_storage(storage_key: &[u8]) { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.kill_child_storage(storage_key) }); } fn exists_storage(key: &[u8]) -> bool { - ext::with(|ext| + with_externalities(|ext| ext.exists_storage(key) ).unwrap_or(false) } fn exists_child_storage(storage_key: &[u8], key: &[u8]) -> bool { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.exists_child_storage(storage_key, key) }).unwrap_or(false) } fn clear_prefix(prefix: &[u8]) { - ext::with(|ext| - ext.clear_prefix(prefix) - ); + with_externalities(|ext| ext.clear_prefix(prefix)); } fn clear_child_prefix(storage_key: &[u8], prefix: &[u8]) { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.clear_child_prefix(storage_key, prefix) }); } fn storage_root() -> [u8; 32] { - ext::with(|ext| + with_externalities(|ext| ext.storage_root() ).unwrap_or(H256::zero()).into() } fn child_storage_root(storage_key: &[u8]) -> Vec { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.child_storage_root(storage_key) }).expect("child_storage_root cannot be called outside of an Externalities-provided environment.") } fn storage_changes_root(parent_hash: [u8; 32]) -> Option<[u8; 32]> { - ext::with(|ext| + with_externalities(|ext| ext.storage_changes_root(parent_hash.into()).map(|h| h.map(|h| h.into())) ).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) } } impl OtherApi for () { fn chain_id() -> u64 { - ext::with(|ext| + with_externalities(|ext| ext.chain_id() ).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)); + } + + fn log( + level: LogLevel, + target: &[u8], + message: &[u8], + ) { + let target = std::str::from_utf8(target).unwrap_or("invalid utf8"); + let msg = std::str::from_utf8(message).unwrap_or("invalid utf8"); + + log::log!( + target: target, + log::Level::from(level), + "{}", + msg, + ) } } impl CryptoApi for () { fn ed25519_public_keys(id: KeyTypeId) -> Vec { - ext::with(|ext| { - ext.keystore() + with_externalities(|ext| { + ext.extension::() .expect("No `keystore` associated for the current context!") .read() .ed25519_public_keys(id) @@ -212,8 +221,8 @@ impl CryptoApi for () { } fn ed25519_generate(id: KeyTypeId, seed: Option<&str>) -> ed25519::Public { - ext::with(|ext| { - ext.keystore() + with_externalities(|ext| { + ext.extension::() .expect("No `keystore` associated for the current context!") .write() .ed25519_generate_new(id, seed) @@ -221,19 +230,19 @@ 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()?; - ext::with(|ext| { - ext.keystore() + with_externalities(|ext| { + ext.extension::() .expect("No `keystore` associated for the current context!") .read() .ed25519_key_pair(id, &pub_key) - .map(|k| k.sign(msg.as_ref())) + .map(|k| k.sign(msg)) }).expect("`ed25519_sign` cannot be called outside of an Externalities-provided environment.") } @@ -242,8 +251,8 @@ impl CryptoApi for () { } fn sr25519_public_keys(id: KeyTypeId) -> Vec { - ext::with(|ext| { - ext.keystore() + with_externalities(|ext| { + ext.extension::() .expect("No `keystore` associated for the current context!") .read() .sr25519_public_keys(id) @@ -251,8 +260,8 @@ impl CryptoApi for () { } fn sr25519_generate(id: KeyTypeId, seed: Option<&str>) -> sr25519::Public { - ext::with(|ext| { - ext.keystore() + with_externalities(|ext| { + ext.extension::() .expect("No `keystore` associated for the current context!") .write() .sr25519_generate_new(id, seed) @@ -260,19 +269,19 @@ 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()?; - ext::with(|ext| { - ext.keystore() + with_externalities(|ext| { + ext.extension::() .expect("No `keystore` associated for the current context!") .read() .sr25519_key_pair(id, &pub_key) - .map(|k| k.sign(msg.as_ref())) + .map(|k| k.sign(msg)) }).expect("`sr25519_sign` cannot be called outside of an Externalities-provided environment.") } @@ -291,6 +300,16 @@ impl CryptoApi for () { res.copy_from_slice(&pubkey.serialize()[1..65]); Ok(res) } + + fn secp256k1_ecdsa_recover_compressed(sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 33], EcdsaVerifyError> { + let rs = secp256k1::Signature::parse_slice(&sig[0..64]) + .map_err(|_| EcdsaVerifyError::BadRS)?; + let v = secp256k1::RecoveryId::parse(if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8) + .map_err(|_| EcdsaVerifyError::BadV)?; + let pubkey = secp256k1::recover(&secp256k1::Message::parse(msg), &rs, &v) + .map_err(|_| EcdsaVerifyError::BadSignature)?; + Ok(pubkey.serialize_compressed()) + } } impl HashingApi for () { @@ -320,9 +339,9 @@ impl HashingApi for () { } fn with_offchain(f: impl FnOnce(&mut dyn offchain::Externalities) -> R, msg: &'static str) -> R { - ext::with(|ext| ext - .offchain() - .map(|ext| f(ext)) + with_externalities(|ext| ext + .extension::() + .map(|ext| f(&mut **ext)) .expect(msg) ).expect("offchain-worker functions cannot be called outside of an Externalities-provided environment.") } @@ -334,9 +353,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 +409,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 +419,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 +429,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 +438,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 +446,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 +456,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) @@ -447,13 +466,6 @@ impl OffchainApi for () { impl Api for () {} -/// Execute the given closure with global function available whose functionality routes into the -/// externalities `ext`. Forwards the value that the closure returns. -// NOTE: need a concrete hasher here due to limitations of the `environmental!` macro, otherwise a type param would have been fine I think. -pub fn with_externalities R>(ext: &mut dyn Externalities, f: F) -> R { - ext::using(ext, f) -} - /// A set of key value pairs for storage. pub type StorageOverlay = HashMap, Vec>; @@ -471,31 +483,13 @@ pub fn with_storage R>( rstd::mem::swap(&mut alt_storage, storage); let mut ext = BasicExternalities::new(alt_storage.0, alt_storage.1); - let r = ext::using(&mut ext, f); + let r = set_and_run_with_externalities(&mut ext, f); *storage = ext.into_storages(); 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::*; @@ -504,7 +498,7 @@ mod std_tests { #[test] fn storage_works() { let mut t = BasicExternalities::default(); - assert!(with_externalities(&mut t, || { + assert!(set_and_run_with_externalities(&mut t, || { assert_eq!(storage(b"hello"), None); set_storage(b"hello", b"world"); assert_eq!(storage(b"hello"), Some(b"world".to_vec())); @@ -515,7 +509,7 @@ mod std_tests { t = BasicExternalities::new(map![b"foo".to_vec() => b"bar".to_vec()], map![]); - assert!(!with_externalities(&mut t, || { + assert!(!set_and_run_with_externalities(&mut t, || { assert_eq!(storage(b"hello"), None); assert_eq!(storage(b"foo"), Some(b"bar".to_vec())); false @@ -528,7 +522,7 @@ mod std_tests { b":test".to_vec() => b"\x0b\0\0\0Hello world".to_vec() ], map![]); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { let mut v = [0u8; 4]; assert!(read_storage(b":test", &mut v[..], 0).unwrap() >= 4); assert_eq!(v, [11u8, 0, 0, 0]); @@ -547,7 +541,7 @@ mod std_tests { b":abdd".to_vec() => b"\x0b\0\0\0Hello world".to_vec() ], map![]); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { clear_prefix(b":abc"); assert!(storage(b":a").is_some()); diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index 954eccc9cfafd6ccb7f46f2e0c454c4277f56c1f..c3f7d62031b931dba928f240015f1a9475e8fdc3 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 { ( @@ -209,6 +160,14 @@ pub mod ext { fn ext_print_hex(data: *const u8, len: u32); /// Print a number fn ext_print_num(value: u64); + /// Print a log line if logging for given level and target is enabled. + fn ext_log( + level: u32, + target_data: *const u8, + target_len: u32, + message_data: *const u8, + message_len: u32, + ); /// Set value for key in storage. fn ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32); @@ -228,7 +187,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 +214,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 +225,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 +241,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 +252,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 +263,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 +281,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 +295,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. /// @@ -432,12 +394,23 @@ pub mod ext { ) -> u32; /// Note: ext_secp256k1_ecdsa_recover returns 0 if the signature is correct, nonzero otherwise. + /// + /// pubkey_data must point to 64 bytes. fn ext_secp256k1_ecdsa_recover( msg_data: *const u8, sig_data: *const u8, pubkey_data: *mut u8, ) -> u32; + /// Note: ext_secp256k1_ecdsa_recover_compressed returns 0 if the signature is correct, nonzero otherwise. + /// + /// pubkey_data must point to 33 bytes. + fn ext_secp256k1_ecdsa_recover_compressed( + msg_data: *const u8, + sig_data: *const u8, + pubkey_data: *mut u8, + ) -> u32; + //================================ // Offchain-worker Context //================================ @@ -498,7 +471,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 +499,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 +513,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 +529,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 +543,7 @@ pub mod ext { ids: *const u32, ids_len: u32, statuses: *mut u32, - deadline: u64 + deadline: u64, ); /// Read all response headers. @@ -583,7 +556,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 +578,7 @@ pub mod ext { id: u32, buffer: *mut u8, buffer_len: u32, - deadline: u64 + deadline: u64, ) -> u32; } } @@ -777,21 +750,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 +782,39 @@ 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); + } + } + + fn log( + level: LogLevel, + target: &[u8], + message: &[u8] + ) { + unsafe { + ext_log.get()( + level as u32, + target.as_ptr(), + target.len() as u32, + message.as_ptr(), + message.len() as u32, + ) + } + } } impl HashingApi for () { @@ -876,18 +885,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 +936,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 }; @@ -973,6 +982,19 @@ impl CryptoApi for () { _ => unreachable!("`ext_secp256k1_ecdsa_recover` only returns 0, 1, 2 or 3; qed"), } } + + fn secp256k1_ecdsa_recover_compressed(sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 33], EcdsaVerifyError> { + let mut pubkey = [0u8; 33]; + match unsafe { + ext_secp256k1_ecdsa_recover_compressed.get()(msg.as_ptr(), sig.as_ptr(), pubkey.as_mut_ptr()) + } { + 0 => Ok(pubkey), + 1 => Err(EcdsaVerifyError::BadRS), + 2 => Err(EcdsaVerifyError::BadV), + 3 => Err(EcdsaVerifyError::BadSignature), + _ => unreachable!("`ext_secp256k1_ecdsa_recover_compressed` only returns 0, 1, 2 or 3; qed"), + } + } } impl OffchainApi for () { @@ -980,10 +1002,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 +1184,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 +1239,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..d3303014260f4fae1aaea6efcd52af190da1dd10 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -5,32 +5,34 @@ 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"] } +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 } +arithmetic = { package = "sr-arithmetic", path = "../sr-arithmetic", 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.41" +rand = "0.7.2" +substrate-offchain = { path = "../offchain" } [features] +bench = [] default = ["std"] std = [ - "num-traits/std", - "serde", - "log", - "rstd/std", - "runtime_io/std", + "app-crypto/std", + "arithmetic/std", "codec/std", + "log", "primitives/std", - "app-crypto/std", "rand", + "rstd/std", + "runtime_io/std", + "serde", ] diff --git a/core/sr-primitives/src/curve.rs b/core/sr-primitives/src/curve.rs new file mode 100644 index 0000000000000000000000000000000000000000..6f25af3e10b6e3e96073cd07f19359b40a4a9a08 --- /dev/null +++ b/core/sr-primitives/src/curve.rs @@ -0,0 +1,163 @@ +// 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]. +#[derive(PartialEq, Eq, primitives::RuntimeDebug)] +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/block.rs b/core/sr-primitives/src/generic/block.rs index 736ad0cbbb6368199ce4fa046c253bdddf66f0a3..3383e257605aa7498f35b39384c59bf86a3c50a1 100644 --- a/core/sr-primitives/src/generic/block.rs +++ b/core/sr-primitives/src/generic/block.rs @@ -23,13 +23,14 @@ use std::fmt; use serde::{Deserialize, Serialize}; use rstd::prelude::*; +use primitives::RuntimeDebug; use crate::codec::{Codec, Encode, Decode}; use crate::traits::{self, Member, Block as BlockT, Header as HeaderT, MaybeSerialize}; use crate::Justification; /// Something to identify a block. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug, Serialize))] +#[derive(PartialEq, Eq, Clone, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] pub enum BlockId { @@ -61,8 +62,8 @@ impl fmt::Display for BlockId { } /// Abstraction over a substrate block. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] pub struct Block { @@ -93,11 +94,14 @@ where fn new(header: Self::Header, extrinsics: Vec) -> Self { Block { header, extrinsics } } + fn encode_from(header: &Self::Header, extrinsics: &[Self::Extrinsic]) -> Vec { + (header, extrinsics).encode() + } } /// Abstraction over a substrate block and justification. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] pub struct SignedBlock { diff --git a/core/sr-primitives/src/generic/checked_extrinsic.rs b/core/sr-primitives/src/generic/checked_extrinsic.rs index 08d7b10386721764ca2bad5cf627961b723a6b6a..1e030ea1d87694096e3ff9396d8476b61c51f513 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; @@ -28,8 +26,7 @@ use crate::transaction_validity::TransactionValidity; /// Definition of something that the external world might want to say; its /// existence implies that it has been checked and is good, particularly with /// regards to the signature. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, primitives::RuntimeDebug)] pub struct CheckedExtrinsic { /// Who this purports to be from and the number of extrinsics have come before /// from the same signer, if anyone (note this is not a signature). @@ -55,28 +52,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 +79,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/digest.rs b/core/sr-primitives/src/generic/digest.rs index d2974444e231b48a270c6c3d715408fe7b213639..83f2c6f1745dedd5092b28c2f013fd3caa0fa9a9 100644 --- a/core/sr-primitives/src/generic/digest.rs +++ b/core/sr-primitives/src/generic/digest.rs @@ -23,10 +23,11 @@ use rstd::prelude::*; use crate::ConsensusEngineId; use crate::codec::{Decode, Encode, Input, Error}; +use primitives::RuntimeDebug; /// Generic header digest. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct Digest { /// A list of logs in the digest. pub logs: Vec>, @@ -72,8 +73,7 @@ impl Digest { /// Digest item that is able to encode/decode 'system' digest items and /// provide opaque access to other items. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, RuntimeDebug)] pub enum DigestItem { /// System digest item that contains the root of changes trie at given /// block. It is created for every block iff runtime supports changes @@ -123,8 +123,7 @@ impl<'a, Hash: Decode> serde::Deserialize<'a> for DigestItem { /// A 'referencing view' for digest item. Does not own its contents. Used by /// final runtime implementations for encoding/decoding its log items. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, RuntimeDebug)] pub enum DigestItemRef<'a, Hash: 'a> { /// Reference to `DigestItem::ChangesTrieRoot`. ChangesTrieRoot(&'a Hash), diff --git a/core/sr-primitives/src/generic/era.rs b/core/sr-primitives/src/generic/era.rs index 7308a8adc5cd5d97a43adfc10869008be7c8285b..305951b1ee3914e3ae2fc93839dd155090d12db3 100644 --- a/core/sr-primitives/src/generic/era.rs +++ b/core/sr-primitives/src/generic/era.rs @@ -28,8 +28,8 @@ pub type Period = u64; pub type Phase = u64; /// An era to describe the longevity of a transaction. -#[derive(PartialEq, Eq, Clone, Copy)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] +#[derive(PartialEq, Eq, Clone, Copy, primitives::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum Era { /// The transaction is valid forever. The genesis hash must be present in the signed content. Immortal, diff --git a/core/sr-primitives/src/generic/header.rs b/core/sr-primitives/src/generic/header.rs index e9a8405fe21b0a45d62f9bcc341b14ee1712982b..75994749c572e3a5c144ce738608902dde91e2a0 100644 --- a/core/sr-primitives/src/generic/header.rs +++ b/core/sr-primitives/src/generic/header.rs @@ -18,20 +18,21 @@ #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; -#[cfg(feature = "std")] -use log::debug; use crate::codec::{Decode, Encode, Codec, Input, Output, HasCompact, EncodeAsRef, Error}; use crate::traits::{ - self, Member, SimpleArithmetic, SimpleBitOps, MaybeDisplay, Hash as HashT, MaybeSerializeDebug, - MaybeSerializeDebugButNotDeserialize + self, Member, SimpleArithmetic, SimpleBitOps, Hash as HashT, + MaybeSerializeDeserialize, MaybeSerialize, MaybeDisplay, }; use crate::generic::Digest; use primitives::U256; -use core::convert::TryFrom; +use rstd::{ + convert::TryFrom, + fmt::Debug, +}; /// Abstraction over a block header for a substrate chain. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(PartialEq, Eq, Clone, primitives::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] pub struct Header + TryFrom, Hash: HashT> { @@ -103,11 +104,11 @@ impl codec::EncodeLike for Header where {} impl traits::Header for Header where - Number: Member + MaybeSerializeDebug + rstd::hash::Hash + MaybeDisplay + + Number: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + MaybeDisplay + SimpleArithmetic + Codec + Copy + Into + TryFrom, Hash: HashT, Hash::Output: Default + rstd::hash::Hash + Copy + Member + - MaybeSerializeDebugButNotDeserialize + MaybeDisplay + SimpleBitOps + Codec, + MaybeSerialize + Debug + MaybeDisplay + SimpleBitOps + Codec, { type Number = Number; type Hash = ::Output; @@ -127,15 +128,12 @@ impl traits::Header for Header where fn digest(&self) -> &Digest { &self.digest } - #[cfg(feature = "std")] fn digest_mut(&mut self) -> &mut Digest { - debug!(target: "header", "Retrieving mutable reference to digest"); + #[cfg(feature = "std")] + log::debug!(target: "header", "Retrieving mutable reference to digest"); &mut self.digest } - #[cfg(not(feature = "std"))] - fn digest_mut(&mut self) -> &mut Digest { &mut self.digest } - fn new( number: Self::Number, extrinsics_root: Self::Hash, 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..c7bff1f4c8b36f12039a2e2fab26dd3bf9ec16fa 100644 --- a/core/sr-primitives/src/generic/unchecked_extrinsic.rs +++ b/core/sr-primitives/src/generic/unchecked_extrinsic.rs @@ -16,16 +16,16 @@ //! Generic implementation of an unchecked (pre-verification) extrinsic. -#[cfg(feature = "std")] -use std::fmt; - use rstd::prelude::*; +use rstd::fmt; 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, IdentifyAccount}, + generic::CheckedExtrinsic, transaction_validity::{TransactionValidityError, InvalidTransaction}, +}; -const TRANSACTION_VERSION: u8 = 3; +const TRANSACTION_VERSION: u8 = 4; /// A extrinsic right from the external world. This is unchecked and so /// can contain a signature. @@ -72,12 +72,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) + }) } } @@ -88,31 +98,29 @@ for where Address: Member + MaybeDisplay, Call: Encode + Member, - Signature: Member + traits::Verify, + Signature: Member + traits::Verify, + ::Signer: IdentifyAccount, 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 +131,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 +245,15 @@ where } } +impl EncodeLike + for UncheckedExtrinsic +where + Address: Encode, + Signature: Encode, + Call: Encode, + Extra: SignedExtension, +{} + #[cfg(feature = "std")] impl serde::Serialize for UncheckedExtrinsic @@ -187,7 +263,6 @@ impl s } } -#[cfg(feature = "std")] impl fmt::Debug for UncheckedExtrinsic where @@ -196,7 +271,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,22 +285,26 @@ mod tests { use super::*; use runtime_io::blake2_256; use crate::codec::{Encode, Decode}; - use crate::traits::{SignedExtension, Lookup}; + use crate::traits::{SignedExtension, IdentifyAccount, 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, Copy, Debug, Serialize, Deserialize, Encode, Decode)] + pub struct TestSigner(pub u64); + impl From for TestSigner { fn from(x: u64) -> Self { Self(x) } } + impl From for u64 { fn from(x: TestSigner) -> Self { x.0 } } + impl IdentifyAccount for TestSigner { + type AccountId = u64; + fn into_account(self) -> u64 { self.into() } } #[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize, Encode, Decode)] struct TestSig(u64, Vec); impl traits::Verify for TestSig { - type Signer = u64; - fn verify>(&self, mut msg: L, signer: &Self::Signer) -> bool { - *signer == self.0 && msg.get() == &self.1[..] + type Signer = TestSigner; + fn verify>(&self, mut msg: L, signer: &u64) -> bool { + signer == &self.0 && msg.get() == &self.1[..] } } @@ -238,7 +322,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 +364,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 +373,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 +388,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 a6a66b80d4c1ee89e96323eb05b81fa56eefafc6..4341e3543add582382b675dfc5e63280912edcb4 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -17,9 +17,12 @@ //! Runtime Modules shared primitive types. #![warn(missing_docs)] - #![cfg_attr(not(feature = "std"), no_std)] +// to allow benchmarking +#![cfg_attr(feature = "bench", feature(test))] +#[cfg(feature = "bench")] extern crate test; + #[doc(hidden)] pub use codec; #[cfg(feature = "std")] @@ -37,41 +40,48 @@ pub use app_crypto; #[cfg(feature = "std")] pub use runtime_io::{StorageOverlay, ChildrenStorageOverlay}; -use rstd::{prelude::*, ops, convert::{TryInto, TryFrom}}; -use primitives::{crypto, ed25519, sr25519, hash::{H256, H512}}; -use codec::{Encode, Decode, CompactAs}; +use rstd::prelude::*; +use rstd::convert::TryFrom; +use primitives::{crypto, ed25519, sr25519, ecdsa, hash::{H256, H512}}; +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 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, AccountId32}}; +pub use app_crypto::RuntimeAppPublic; + +/// Re-export `RuntimeDebug`, to avoid dependency clutter. +pub use primitives::RuntimeDebug; + +/// Re-export top-level arithmetic stuff. +pub use arithmetic::{ + Perquintill, Perbill, Permill, Percent, + Rational128, Fixed64 +}; +/// Re-export 128 bit helpers. +pub use arithmetic::helpers_128bit; +/// Re-export big_uint stuff. +pub use arithmetic::biguint; + +/// 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 +90,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"; } @@ -107,19 +117,20 @@ macro_rules! create_runtime_str { #[cfg(feature = "std")] pub use serde::{Serialize, Deserialize, de::DeserializeOwned}; +use crate::traits::IdentifyAccount; /// Complex storage builder stuff. #[cfg(feature = "std")] pub trait BuildStorage: Sized { /// Build the storage out of this builder. - fn build_storage(self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { + fn build_storage(&self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { let mut storage = (Default::default(), Default::default()); self.assimilate_storage(&mut storage)?; Ok(storage) } /// Assimilate the storage for this module into pre-existing overlays. fn assimilate_storage( - self, + &self, storage: &mut (StorageOverlay, ChildrenStorageOverlay), ) -> Result<(), String>; } @@ -129,26 +140,24 @@ pub trait BuildStorage: Sized { pub trait BuildModuleGenesisStorage: Sized { /// Create the module genesis storage into the given `storage` and `child_storage`. fn build_module_genesis_storage( - self, + &self, storage: &mut (StorageOverlay, ChildrenStorageOverlay), ) -> Result<(), String>; } #[cfg(feature = "std")] impl BuildStorage for (StorageOverlay, ChildrenStorageOverlay) { - fn build_storage(self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { - Ok(self) - } fn assimilate_storage( - self, + &self, storage: &mut (StorageOverlay, ChildrenStorageOverlay), )-> Result<(), String> { - storage.0.extend(self.0); - for (k, other_map) in self.1.into_iter() { + storage.0.extend(self.0.iter().map(|(k, v)| (k.clone(), v.clone()))); + for (k, other_map) in self.1.iter() { + let k = k.clone(); if let Some(map) = storage.1.get_mut(&k) { - map.extend(other_map); + map.extend(other_map.iter().map(|(k, v)| (k.clone(), v.clone()))); } else { - storage.1.insert(k, other_map); + storage.1.insert(k, other_map.clone()); } } Ok(()) @@ -158,368 +167,15 @@ 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) - } - - /// Return the product of multiplication of this value by itself. - pub fn square(self) -> Self { - let p: u64 = self.0 as u64 * self.0 as u64; - let q: u64 = 1_000_000_000 * 1_000_000_000; - Self::from_rational_approximation(p, q) - } - - /// Take out the raw parts-per-billions. - pub fn into_parts(self) -> u32 { - self.0 - } -} - -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))] +#[derive(Eq, PartialEq, Clone, Encode, Decode, RuntimeDebug)] pub enum MultiSignature { /// An Ed25519 signature. Ed25519(ed25519::Signature), /// An Sr25519 signature. Sr25519(sr25519::Signature), + /// An ECDSA/SECP256k1 signature. + Ecdsa(ecdsa::Signature), } impl From for MultiSignature { @@ -534,6 +190,12 @@ impl From for MultiSignature { } } +impl From for MultiSignature { + fn from(x: ecdsa::Signature) -> Self { + MultiSignature::Ecdsa(x) + } +} + impl Default for MultiSignature { fn default() -> Self { MultiSignature::Ed25519(Default::default()) @@ -541,13 +203,15 @@ impl Default for MultiSignature { } /// Public key for any known crypto algorithm. -#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum MultiSigner { /// An Ed25519 identity. Ed25519(ed25519::Public), /// An Sr25519 identity. Sr25519(sr25519::Public), + /// An SECP256k1/ECDSA identity (actually, the Blake2 hash of the pub key). + Ecdsa(ecdsa::Public), } impl Default for MultiSigner { @@ -569,6 +233,18 @@ impl AsRef<[u8]> for MultiSigner { match *self { MultiSigner::Ed25519(ref who) => who.as_ref(), MultiSigner::Sr25519(ref who) => who.as_ref(), + MultiSigner::Ecdsa(ref who) => who.as_ref(), + } + } +} + +impl traits::IdentifyAccount for MultiSigner { + type AccountId = AccountId32; + fn into_account(self) -> AccountId32 { + match self { + MultiSigner::Ed25519(who) => <[u8; 32]>::from(who).into(), + MultiSigner::Sr25519(who) => <[u8; 32]>::from(who).into(), + MultiSigner::Ecdsa(who) => runtime_io::blake2_256(who.as_ref()).into(), } } } @@ -579,47 +255,83 @@ impl From for MultiSigner { } } +impl TryFrom for ed25519::Public { + type Error = (); + fn try_from(m: MultiSigner) -> Result { + if let MultiSigner::Ed25519(x) = m { Ok(x) } else { Err(()) } + } +} + impl From for MultiSigner { fn from(x: sr25519::Public) -> Self { MultiSigner::Sr25519(x) } } - #[cfg(feature = "std")] +impl TryFrom for sr25519::Public { + type Error = (); + fn try_from(m: MultiSigner) -> Result { + if let MultiSigner::Sr25519(x) = m { Ok(x) } else { Err(()) } + } +} + +impl From for MultiSigner { + fn from(x: ecdsa::Public) -> Self { + MultiSigner::Ecdsa(x) + } +} + +impl TryFrom for ecdsa::Public { + type Error = (); + fn try_from(m: MultiSigner) -> Result { + if let MultiSigner::Ecdsa(x) = m { Ok(x) } else { Err(()) } + } +} + +#[cfg(feature = "std")] impl std::fmt::Display for MultiSigner { fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { match *self { MultiSigner::Ed25519(ref who) => write!(fmt, "ed25519: {}", who), MultiSigner::Sr25519(ref who) => write!(fmt, "sr25519: {}", who), + MultiSigner::Ecdsa(ref who) => write!(fmt, "ecdsa: {}", who), } } } impl Verify for MultiSignature { type Signer = MultiSigner; - fn verify>(&self, msg: L, signer: &Self::Signer) -> bool { + fn verify>(&self, mut msg: L, signer: &AccountId32) -> bool { + use primitives::crypto::Public; match (self, signer) { - (MultiSignature::Ed25519(ref sig), &MultiSigner::Ed25519(ref who)) => sig.verify(msg, who), - (MultiSignature::Sr25519(ref sig), &MultiSigner::Sr25519(ref who)) => sig.verify(msg, who), - _ => false, + (MultiSignature::Ed25519(ref sig), who) => sig.verify(msg, &ed25519::Public::from_slice(who.as_ref())), + (MultiSignature::Sr25519(ref sig), who) => sig.verify(msg, &sr25519::Public::from_slice(who.as_ref())), + (MultiSignature::Ecdsa(ref sig), who) => { + let m = runtime_io::blake2_256(msg.get()); + match runtime_io::secp256k1_ecdsa_recover_compressed(sig.as_ref(), &m) { + Ok(pubkey) => &runtime_io::blake2_256(pubkey.as_ref()) == >::as_ref(who), + _ => false, + } + } } } } /// Signature verify that can work with any known signature types.. -#[derive(Eq, PartialEq, Clone, Default, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(Eq, PartialEq, Clone, Default, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct AnySignature(H512); impl Verify for AnySignature { type Signer = sr25519::Public; fn verify>(&self, mut msg: L, signer: &sr25519::Public) -> bool { + use primitives::crypto::Public; + let msg = msg.get(); sr25519::Signature::try_from(self.0.as_fixed_bytes().as_ref()) - .map(|s| runtime_io::sr25519_verify(&s, msg.get(), &signer)) + .map(|s| s.verify(msg, signer)) .unwrap_or(false) || ed25519::Signature::try_from(self.0.as_fixed_bytes().as_ref()) - .and_then(|s| ed25519::Public::try_from(signer.0.as_ref()).map(|p| (s, p))) - .map(|(s, p)| runtime_io::ed25519_verify(&s, msg.get(), &p)) + .map(|s| s.verify(msg, &ed25519::Public::from_slice(signer.as_ref()))) .unwrap_or(false) } } @@ -636,56 +348,114 @@ impl From for AnySignature { } } -#[derive(Eq, PartialEq, Clone, Copy, Decode)] -#[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, +#[derive(Eq, PartialEq, Clone, Copy, Decode, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize))] +/// 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, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(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 { +pub fn verify_encoded_lazy(sig: &V, item: &T, signer: &::AccountId) -> bool { // The `Lazy` trait expresses something like `X: FnMut &'a T>`. // unfortunately this is a lifetime relationship that can't // be expressed without generic associated types, better unification of HRTBs in type position, @@ -771,11 +541,11 @@ macro_rules! impl_outer_config { #[cfg(any(feature = "std", test))] impl $crate::BuildStorage for $main { fn assimilate_storage( - self, + &self, storage: &mut ($crate::StorageOverlay, $crate::ChildrenStorageOverlay), ) -> std::result::Result<(), String> { $( - if let Some(extra) = self.[< $snake $(_ $instance )? >] { + if let Some(ref extra) = self.[< $snake $(_ $instance )? >] { $crate::impl_outer_config! { @CALL_FN $concrete; @@ -817,18 +587,55 @@ 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)] pub struct OpaqueExtrinsic(pub Vec); -#[cfg(feature = "std")] -impl std::fmt::Debug for OpaqueExtrinsic { - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { +impl rstd::fmt::Debug for OpaqueExtrinsic { + #[cfg(feature = "std")] + fn fmt(&self, fmt: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { write!(fmt, "{}", primitives::hexdisplay::HexDisplay::from(&self.0)) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _fmt: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } + #[cfg(feature = "std")] impl ::serde::Serialize for OpaqueExtrinsic { fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { @@ -847,50 +654,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() { @@ -899,95 +674,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, + }, ); } - - #[test] - fn per_bill_square() { - const FIXTURES: &[(u32, u32)] = &[ - (0, 0), - (1250000, 1562), // (0.00125, 0.000001562) - (255300000, 65178090), // (0.2553, 0.06517809) - (500000000, 250000000), // (0.5, 0.25) - (999995000, 999990000), // (0.999995, 0.999990000, but ideally 0.99999000002) - (1000000000, 1000000000), - ]; - - for &(x, r) in FIXTURES { - assert_eq!( - Perbill::from_parts(x).square(), - Perbill::from_parts(r), - ); - } - } } diff --git a/core/sr-io/src/offchain/http.rs b/core/sr-primitives/src/offchain/http.rs similarity index 84% rename from core/sr-io/src/offchain/http.rs rename to core/sr-primitives/src/offchain/http.rs index 6685dd023f469e607b59cfcf7509b629c58bde94..77e514d65342bb605f030cf7b8f86e95a9d34d40 100644 --- a/core/sr-io/src/offchain/http.rs +++ b/core/sr-primitives/src/offchain/http.rs @@ -14,12 +14,44 @@ // 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; #[cfg(not(feature = "std"))] use rstd::prelude::vec; +use primitives::RuntimeDebug; use primitives::offchain::{ Timestamp, HttpRequestId as RequestId, @@ -28,8 +60,7 @@ use primitives::offchain::{ }; /// Request method (HTTP verb) -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, RuntimeDebug)] pub enum Method { /// GET request Get, @@ -62,8 +93,7 @@ mod header { use super::*; /// A header type. - #[derive(Clone, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive(Clone, PartialEq, Eq, RuntimeDebug)] pub struct Header { name: Vec, value: Vec, @@ -97,8 +127,7 @@ mod header { } /// An HTTP request builder. -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, RuntimeDebug)] pub struct Request<'a, T = Vec<&'static [u8]>> { /// Request method pub method: Method, @@ -192,11 +221,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 +234,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, @@ -218,20 +247,18 @@ impl<'a, I: AsRef<[u8]>, T: IntoIterator> Request<'a, T> { } /// A request error -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, RuntimeDebug)] pub enum Error { /// Deadline has been reached. DeadlineReached, /// Request had timed out. - Timeout, + IoError, /// Unknown error has been ecountered. Unknown, } /// A struct representing an uncompleted http request. -#[derive(PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, RuntimeDebug)] pub struct PendingRequest { /// Request ID pub id: RequestId, @@ -276,15 +303,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() @@ -292,7 +319,7 @@ impl PendingRequest { } /// A HTTP response. -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(RuntimeDebug)] pub struct Response { /// Request id pub id: RequestId, @@ -314,7 +341,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 +420,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); @@ -421,8 +448,7 @@ impl Iterator for ResponseBody { } /// A collection of Headers in the response. -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, RuntimeDebug)] pub struct Headers { /// Raw headers pub raw: Vec<(Vec, Vec)>, @@ -452,8 +478,7 @@ impl Headers { } /// A custom iterator traversing all the headers. -#[derive(Clone)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, RuntimeDebug)] pub struct HeadersIterator<'a> { collection: &'a [(Vec, Vec)], index: Option, @@ -481,16 +506,17 @@ impl<'a> HeadersIterator<'a> { #[cfg(test)] mod tests { use super::*; - use crate::{TestExternalities, with_externalities}; + use runtime_io::TestExternalities; use substrate_offchain::testing; + use primitives::offchain::OffchainExt; #[test] fn should_send_a_basic_request_and_get_response() { let (offchain, state) = testing::TestOffchainExt::new(); let mut t = TestExternalities::default(); - t.set_offchain_externalities(offchain); + t.register_extension(OffchainExt::new(offchain)); - with_externalities(&mut t, || { + t.execute_with(|| { let request: Request = Request::get("http://localhost:1234"); let pending = request .add_header("X-Auth", "hunter2") @@ -529,9 +555,9 @@ mod tests { fn should_send_a_post_request() { let (offchain, state) = testing::TestOffchainExt::new(); let mut t = TestExternalities::default(); - t.set_offchain_externalities(offchain); + t.register_extension(OffchainExt::new(offchain)); - with_externalities(&mut t, || { + t.execute_with(|| { let pending = Request::default() .method(Method::Post) .url("http://localhost:1234") 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/testing.rs b/core/sr-primitives/src/testing.rs index c91c8366c1123587a98e1f4a5a7542963489dd89..b7903471188151c8912ee6d387f651194b9a0e34 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 @@ -239,6 +259,9 @@ impl) -> Self { Block { header, extrinsics } } + fn encode_from(header: &Self::Header, extrinsics: &[Self::Extrinsic]) -> Vec { + (header, extrinsics).encode() + } } impl<'a, Xt> Deserialize<'a> for Block where Block: Decode { @@ -270,24 +293,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 +319,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 +341,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 3dc1649e495d42ea23c435d6e11dfa66628aa5ea..4586a84511f73d7b40355cf8aa77505909881351 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -17,25 +17,26 @@ //! Primitives for the runtime modules. use rstd::prelude::*; -use rstd::{self, result, marker::PhantomData, convert::{TryFrom, TryInto}}; +use rstd::{self, result, marker::PhantomData, convert::{TryFrom, TryInto}, fmt::Debug}; 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}; -use crate::codec::{Codec, Encode, Decode, HasCompact}; -use crate::transaction_validity::{ValidTransaction, TransactionValidity}; +#[cfg(feature = "std")] +use std::fmt::Display; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize, de::DeserializeOwned}; +use primitives::{self, Hasher, Blake2Hasher, TypeId}; +use crate::codec::{Codec, Encode, Decode}; +use crate::transaction_validity::{ + ValidTransaction, TransactionValidity, TransactionValidityError, UnknownTransaction, +}; use crate::generic::{Digest, DigestItem}; use crate::weights::DispatchInfo; -pub use integer_sqrt::IntegerSquareRoot; -pub use num_traits::{ +pub use arithmetic::traits::{ + SimpleArithmetic, UniqueSaturatedInto, UniqueSaturatedFrom, Saturating, SaturatedConversion, Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, - CheckedShl, CheckedShr + CheckedShl, CheckedShr, IntegerSquareRoot }; -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 { @@ -49,62 +50,126 @@ impl<'a> Lazy<[u8]> for &'a [u8] { fn get(&mut self) -> &[u8] { &**self } } +/// Some type that is able to be collapsed into an account ID. It is not possible to recreate the original value from +/// the account ID. +pub trait IdentifyAccount { + /// The account ID that this can be transformed into. + type AccountId; + /// Transform into an account. + fn into_account(self) -> Self::AccountId; +} + +impl IdentifyAccount for primitives::ed25519::Public { + type AccountId = Self; + fn into_account(self) -> Self { self } +} + +impl IdentifyAccount for primitives::sr25519::Public { + type AccountId = Self; + fn into_account(self) -> Self { self } +} + +impl IdentifyAccount for primitives::ecdsa::Public { + type AccountId = Self; + fn into_account(self) -> Self { self } +} + /// Means of signature verification. pub trait Verify { /// Type of the signer. - type Signer; + type Signer: IdentifyAccount; /// Verify a signature. Return `true` if signature is valid for the value. - fn verify>(&self, msg: L, signer: &Self::Signer) -> bool; + fn verify>(&self, msg: L, signer: &::AccountId) -> bool; } impl Verify for primitives::ed25519::Signature { type Signer = primitives::ed25519::Public; - fn verify>(&self, mut msg: L, signer: &Self::Signer) -> bool { + fn verify>(&self, mut msg: L, signer: &primitives::ed25519::Public) -> bool { runtime_io::ed25519_verify(self, msg.get(), signer) } } impl Verify for primitives::sr25519::Signature { type Signer = primitives::sr25519::Public; - fn verify>(&self, mut msg: L, signer: &Self::Signer) -> bool { + fn verify>(&self, mut msg: L, signer: &primitives::sr25519::Public) -> bool { runtime_io::sr25519_verify(self, msg.get(), signer) } } +impl Verify for primitives::ecdsa::Signature { + type Signer = primitives::ecdsa::Public; + fn verify>(&self, mut msg: L, signer: &primitives::ecdsa::Public) -> bool { + match runtime_io::secp256k1_ecdsa_recover_compressed(self.as_ref(), &runtime_io::blake2_256(msg.get())) { + Ok(pubkey) => >::as_ref(signer) == &pubkey[..], + _ => false, + } + } +} + /// Means of signature verification of an application key. pub trait AppVerify { /// Type of the signer. - type Signer; + type AccountId; /// Verify a signature. Return `true` if signature is valid for the value. - fn verify>(&self, msg: L, signer: &Self::Signer) -> bool; + fn verify>(&self, msg: L, signer: &Self::AccountId) -> bool; } impl< S: Verify::Public as app_crypto::AppPublic>::Generic> + From, T: app_crypto::Wraps + app_crypto::AppKey + app_crypto::AppSignature + AsRef + AsMut + From, -> AppVerify for T { - type Signer = ::Public; - fn verify>(&self, msg: L, signer: &Self::Signer) -> bool { +> AppVerify for T where + ::Signer: IdentifyAccount::Signer>, + <::Public as app_crypto::AppPublic>::Generic: + IdentifyAccount::Public as app_crypto::AppPublic>::Generic>, +{ + type AccountId = ::Public; + fn verify>(&self, msg: L, signer: &::Public) -> bool { use app_crypto::IsWrappedBy; let inner: &S = self.as_ref(); - let inner_pubkey = ::Generic::from_ref(&signer); + let inner_pubkey = <::Public as app_crypto::AppPublic>::Generic::from_ref(&signer); Verify::verify(inner, msg, inner_pubkey) } } +/// 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 +177,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. @@ -120,11 +185,11 @@ pub trait Lookup { /// context. pub trait StaticLookup { /// Type to lookup from. - type Source: Codec + Clone + PartialEq + MaybeDebug; + type Source: Codec + Clone + PartialEq + Debug; /// 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; } @@ -132,16 +197,17 @@ pub trait StaticLookup { /// A lookup implementation returning the input value. #[derive(Default)] pub struct IdentityLookup(PhantomData); -impl StaticLookup for IdentityLookup { +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. @@ -166,120 +232,6 @@ impl> Convert for ConvertInto { fn convert(a: A) -> B { a.into() } } -/// A meta trait for arithmetic. -/// -/// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to -/// be able to represent at least `u32` values without loss, hence the trait implies `From` -/// and smaller ints. All other conversions are fallible. -pub trait SimpleArithmetic: - Zero + One + IntegerSquareRoot + - From + From + From + TryInto + TryInto + TryInto + - TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + - UniqueSaturatedInto + UniqueSaturatedInto + UniqueSaturatedInto + - UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + - Add + AddAssign + - Sub + SubAssign + - Mul + MulAssign + - Div + DivAssign + - Rem + RemAssign + - Shl + Shr + - CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + - Saturating + PartialOrd + Ord + Bounded + - HasCompact + Sized -{} -impl + From + From + TryInto + TryInto + TryInto + - TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + - UniqueSaturatedInto + UniqueSaturatedInto + UniqueSaturatedInto + - UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + - UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + - Add + AddAssign + - Sub + SubAssign + - Mul + MulAssign + - Div + DivAssign + - Rem + RemAssign + - Shl + Shr + - CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + - Saturating + PartialOrd + Ord + Bounded + - HasCompact + Sized -> SimpleArithmetic for T {} - -/// Just like `From` except that if the source value is too big to fit into the destination type -/// then it'll saturate the destination. -pub trait UniqueSaturatedFrom: Sized { - /// Convert from a value of `T` into an equivalent instance of `Self`. - fn unique_saturated_from(t: T) -> Self; -} - -/// Just like `Into` except that if the source value is too big to fit into the destination type -/// then it'll saturate the destination. -pub trait UniqueSaturatedInto: Sized { - /// Consume self to return an equivalent value of `T`. - fn unique_saturated_into(self) -> T; -} - -impl + Bounded + Sized> UniqueSaturatedFrom for S { - fn unique_saturated_from(t: T) -> Self { - S::try_from(t).unwrap_or_else(|_| Bounded::max_value()) - } -} - -impl + Sized> UniqueSaturatedInto for S { - fn unique_saturated_into(self) -> T { - self.try_into().unwrap_or_else(|_| Bounded::max_value()) - } -} - -/// Simple trait to use checked mul and max value to give a saturated mul operation over -/// supported types. -pub trait Saturating { - /// Saturated addition - if the product can't fit in the type then just use max-value. - fn saturating_add(self, o: Self) -> Self; - - /// Saturated subtraction - if the product can't fit in the type then just use max-value. - fn saturating_sub(self, o: Self) -> Self; - - /// Saturated multiply - if the product can't fit in the type then just use max-value. - fn saturating_mul(self, o: Self) -> Self; -} - -impl Saturating for T { - fn saturating_add(self, o: Self) -> Self { - ::saturating_add(self, o) - } - fn saturating_sub(self, o: Self) -> Self { - ::saturating_sub(self, o) - } - fn saturating_mul(self, o: Self) -> Self { - self.checked_mul(&o).unwrap_or_else(Bounded::max_value) - } -} - -/// Convenience type to work around the highly unergonomic syntax needed -/// to invoke the functions of overloaded generic traits, in this case -/// `SaturatedFrom` and `SaturatedInto`. -pub trait SaturatedConversion { - /// Convert from a value of `T` into an equivalent instance of `Self`. - /// - /// This just uses `UniqueSaturatedFrom` internally but with this - /// variant you can provide the destination type using turbofish syntax - /// in case Rust happens not to assume the correct type. - fn saturated_from(t: T) -> Self where Self: UniqueSaturatedFrom { - >::unique_saturated_from(t) - } - - /// Consume self to return an equivalent value of `T`. - /// - /// This just uses `UniqueSaturatedInto` internally but with this - /// variant you can provide the destination type using turbofish syntax - /// in case Rust happens not to assume the correct type. - fn saturated_into(self) -> T where Self: UniqueSaturatedInto { - >::unique_saturated_into(self) - } -} -impl SaturatedConversion for T {} - /// Convenience type to work around the highly unergonomic syntax needed /// to invoke the functions of overloaded generic traits, in this case /// `TryFrom` and `TryInto`. @@ -375,22 +327,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 +349,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,53 +358,13 @@ 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 + MaybeSerializeDeserialize + Debug + Clone + Eq + PartialEq { /// The hash type produced. - type Output: Member + MaybeSerializeDebug + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + Copy - + Default + Encode + Decode; + type Output: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + + AsRef<[u8]> + AsMut<[u8]> + Copy + Default + Encode + Decode; /// The associated hash_db Hasher type. type Hasher: Hasher; @@ -466,18 +377,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; @@ -487,8 +391,8 @@ pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { // Stup } /// Blake2-256 Hash implementation. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(PartialEq, Eq, Clone, primitives::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct BlakeTwo256; impl Hash for BlakeTwo256 { @@ -497,22 +401,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,21 +430,25 @@ 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(); } } } -impl CheckEqual for super::generic::DigestItem where H: Encode { +impl CheckEqual for super::generic::DigestItem where H: Encode { #[cfg(feature = "std")] fn check_equal(&self, other: &Self) { if self != other { @@ -554,84 +459,44 @@ 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 {} - -/// A type that implements Debug when in std environment. -#[cfg(feature = "std")] -pub trait MaybeDebug: Debug {} -#[cfg(feature = "std")] -impl MaybeDebug for T {} - -/// A type that implements Debug when in std environment. -#[cfg(not(feature = "std"))] -pub trait MaybeDebug {} -#[cfg(not(feature = "std"))] -impl MaybeDebug 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 Display when in std environment. -#[cfg(feature = "std")] -pub trait MaybeDisplay: Display {} -#[cfg(feature = "std")] -impl MaybeDisplay for T {} +impl_maybe_marker!( + /// A type that implements Display when in std environment. + MaybeDisplay: Display; -/// 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 Hash when in std environment. + MaybeHash: rstd::hash::Hash; -/// 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 when in std environment. + MaybeSerialize: 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, DeserializeOwned and Debug when in std environment. + MaybeSerializeDeserialize: DeserializeOwned, Serialize +); /// A type that provides a randomness beacon. pub trait RandomnessBeacon { @@ -650,8 +515,8 @@ pub trait RandomnessBeacon { } /// A type that can be used in runtime structures. -pub trait Member: Send + Sync + Sized + MaybeDebug + Eq + PartialEq + Clone + 'static {} -impl Member for T {} +pub trait Member: Send + Sync + Sized + Debug + Eq + PartialEq + Clone + 'static {} +impl Member for T {} /// Determine if a `MemberId` is a valid member. pub trait IsMember { @@ -660,15 +525,17 @@ pub trait IsMember { } /// Something which fulfills the abstract idea of a Substrate header. It has types for a `Number`, -/// a `Hash` and a `Digest`. It provides access to an `extrinsics_root`, `state_root` and +/// a `Hash` and a `Hashing`. It provides access to an `extrinsics_root`, `state_root` and /// `parent_hash`, as well as a `digest` and a block `number`. /// /// You can also create a `new` one from those fields. -pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDeserialize + 'static { +pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + 'static { /// Header number. - type Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec; + type Number: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + + Copy + MaybeDisplay + SimpleArithmetic + Codec; /// Header hash type - type Hash: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; + type Hash: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; /// Hashing algorithm type Hashing: Hash; @@ -716,13 +583,14 @@ pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDe /// `Extrinsic` piece of information as well as a `Header`. /// /// You can get an iterator over each of the `extrinsics` and retrieve the `header`. -pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDeserialize + 'static { +pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + 'static { /// Type of extrinsics. type Extrinsic: Member + Codec + Extrinsic + MaybeSerialize; /// Header type. type Header: Header; /// Block hash type. - type Hash: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; + type Hash: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; /// Returns a reference to the header. fn header(&self) -> &Self::Header; @@ -736,6 +604,8 @@ pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDes fn hash(&self) -> Self::Hash { <::Hashing as Hash>::hash_of(self.header()) } + /// Create an encoded block from the given `header` and `extrinsics` without requiring to create an instance. + fn encode_from(header: &Self::Header, extrinsics: &[Self::Extrinsic]) -> Vec; } /// Something that acts like an `Extrinsic`. @@ -743,13 +613,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 +651,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 +663,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(PartialEq, 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 +688,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 + Debug + Sync + Send + Clone + Eq + PartialEq { /// The type which encodes the sender identity. type AccountId; @@ -871,7 +712,7 @@ 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. /// @@ -888,8 +729,8 @@ pub trait SignedExtension: _call: &Self::Call, _info: DispatchInfo, _len: usize, - ) -> Result { - Ok(Default::default()) + ) -> TransactionValidity { + Ok(ValidTransaction::default()) } /// Do any pre-flight stuff for a signed transaction. @@ -906,8 +747,10 @@ pub trait SignedExtension: 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. @@ -925,7 +768,9 @@ pub trait SignedExtension: _call: &Self::Call, _info: DispatchInfo, _len: usize, - ) -> Result { Ok(Default::default()) } + ) -> TransactionValidity { + Ok(ValidTransaction::default()) + } /// Do any pre-flight stuff for a unsigned transaction. /// @@ -939,95 +784,83 @@ pub trait SignedExtension: 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")] @@ -1036,7 +869,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 @@ -1056,17 +889,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. @@ -1207,12 +1042,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 { @@ -1236,76 +1065,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 @@ -1334,13 +1093,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, /// } /// } @@ -1355,8 +1115,13 @@ macro_rules! impl_opaque_keys { )* } ) => { - #[derive(Default, Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)] - #[cfg_attr(feature = "std", derive(Debug, $crate::serde::Serialize, $crate::serde::Deserialize))] + #[derive( + Default, Clone, PartialEq, Eq, + $crate::codec::Encode, + $crate::codec::Decode, + $crate::RuntimeDebug + )] + #[cfg_attr(feature = "std", derive($crate::serde::Serialize, $crate::serde::Deserialize))] pub struct $name { $( pub $field: $type, @@ -1397,3 +1162,137 @@ 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) { + (*self as u64).print() + } +} + +impl Printable for u32 { + fn print(&self) { + (*self as u64).print() + } +} + +impl Printable for usize { + fn print(&self) { + (*self as u64).print() + } +} + +impl Printable for u64 { + fn print(&self) { + runtime_io::print_num(*self); + } +} + +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_for_tuples(1, 12)] +impl Printable for Tuple { + fn print(&self) { + for_tuples!( #( Tuple.print(); )* ) + } +} + +#[cfg(test)] +mod tests { + use super::AccountIdConversion; + use crate::codec::{Encode, Decode, Input}; + + mod t { + use primitives::crypto::KeyTypeId; + use app_crypto::{app_crypto, sr25519}; + app_crypto!(sr25519, KeyTypeId(*b"test")); + } + + #[test] + fn app_verify_works() { + use t::*; + use super::AppVerify; + + let s = Signature::default(); + let _ = s.verify(&[0u8; 100][..], &Public::default()); + } + + #[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..3e765215b979a950d9b37a083415b24f56c09766 100644 --- a/core/sr-primitives/src/transaction_validity.rs +++ b/core/sr-primitives/src/transaction_validity.rs @@ -17,8 +17,8 @@ //! Transaction validity interface. use rstd::prelude::*; -use crate::codec::{Encode, Decode, Error}; -use crate::traits::DispatchError; +use crate::codec::{Encode, Decode}; +use crate::RuntimeDebug; /// Priority for a transaction. Additive. Higher is better. pub type TransactionPriority = u64; @@ -30,30 +30,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, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(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, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(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, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(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)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] 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..b245f902474ec209d99fbc0e6fff10071a5a649c 100644 --- a/core/sr-primitives/src/weights.rs +++ b/core/sr-primitives/src/weights.rs @@ -23,19 +23,17 @@ //! Note that the decl_module macro _cannot_ enforce this and will simply fail if an invalid struct //! (something that does not implement `Weighable`) is passed in. -use crate::{Fixed64, traits::Saturating}; -use crate::codec::{Encode, Decode}; +use arithmetic::traits::Bounded; +use crate::RuntimeDebug; pub use crate::transaction_validity::TransactionPriority; -use crate::traits::Bounded; /// Numeric range of a transaction weight. pub type Weight = u32; /// A generalized group of dispatch types. This is only distinguishing normal, user-triggered transactions /// (`Normal`) and anything beyond which serves a higher purpose to the system (`Operational`). -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(PartialEq, Eq, Clone, Copy)] +#[derive(PartialEq, Eq, Clone, Copy, RuntimeDebug)] pub enum DispatchClass { /// A normal dispatch. Normal, @@ -64,8 +62,8 @@ impl From for DispatchClass { } /// A bundle of static information collected from the `#[weight = $x]` attributes. -#[cfg_attr(feature = "std", derive(PartialEq, Eq, Debug))] -#[derive(Clone, Copy, Default)] +#[cfg_attr(feature = "std", derive(PartialEq, Eq))] +#[derive(Clone, Copy, Default, RuntimeDebug)] pub struct DispatchInfo { /// Weight of this transaction. pub weight: Weight, @@ -167,76 +165,3 @@ impl Default for SimpleDispatchInfo { SimpleDispatchInfo::FixedNormal(10_000) } } - -/// Representation of a weight multiplier. This represents how a fee value can be computed from a -/// weighted transaction. -/// -/// This is basically a wrapper for the `Fixed64` type a slightly tailored multiplication to u32 -/// in the form of the `apply_to` method. -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct WeightMultiplier(Fixed64); - -impl WeightMultiplier { - /// Apply the inner Fixed64 as a weight multiplier to a weight value. - /// - /// This will perform a saturated `weight + weight * self.0`. - pub fn apply_to(&self, weight: Weight) -> Weight { - self.0.saturated_multiply_accumulate(weight) - } - - /// build self from raw parts per billion. - #[cfg(feature = "std")] - pub fn from_parts(parts: i64) -> Self { - Self(Fixed64(parts)) - } - - /// build self from a fixed64 value. - pub fn from_fixed(f: Fixed64) -> Self { - Self(f) - } - - /// Approximate the fraction `n/d`. - pub fn from_rational(n: i64, d: u64) -> Self { - Self(Fixed64::from_rational(n, d)) - } -} - -impl Saturating for WeightMultiplier { - 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)) - - } - fn saturating_sub(self, rhs: Self) -> Self { - Self(self.0.saturating_sub(rhs.0)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn multiplier_apply_to_works() { - let test_set = vec![0, 1, 10, 1000, 1_000_000_000]; - - // negative (1/2) - let mut fm = WeightMultiplier::from_rational(-1, 2); - test_set.clone().into_iter().for_each(|i| { assert_eq!(fm.apply_to(i) as i32, i as i32 - i as i32 / 2); }); - - // unit (1) multiplier - fm = WeightMultiplier::from_parts(0); - test_set.clone().into_iter().for_each(|i| { assert_eq!(fm.apply_to(i), i); }); - - // i.5 multiplier - fm = WeightMultiplier::from_rational(1, 2); - test_set.clone().into_iter().for_each(|i| { assert_eq!(fm.apply_to(i), i * 3 / 2); }); - - // dual multiplier - fm = WeightMultiplier::from_rational(1, 1); - test_set.clone().into_iter().for_each(|i| { assert_eq!(fm.apply_to(i), i * 2); }); - } -} 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-sandbox/src/lib.rs b/core/sr-sandbox/src/lib.rs index e814a51acedf692b5df4082db9fce73408d5308e..c9f9135661586d034f1722ad30e822ac2eebc1c0 100755 --- a/core/sr-sandbox/src/lib.rs +++ b/core/sr-sandbox/src/lib.rs @@ -51,7 +51,7 @@ mod imp { } /// Error that can occur while using this crate. -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(primitives::RuntimeDebug)] pub enum Error { /// Module is not valid, couldn't be instantiated. Module, @@ -171,7 +171,7 @@ pub struct Instance { impl Instance { /// Instantiate a module with the given [`EnvironmentDefinitionBuilder`]. It will - /// run the `start` function with the given `state`. + /// run the `start` function (if it is present in the module) with the given `state`. /// /// Returns `Err(Error::Module)` if this module can't be instantiated with the given /// environment. If execution of `start` function generated a trap, then `Err(Error::Execution)` will diff --git a/core/sr-staking-primitives/src/lib.rs b/core/sr-staking-primitives/src/lib.rs index 63a5eb29279d1f93faf142ebf4842b8c9b0d644e..182307cb4712fa1a17668f348b70bf89f4dbfda3 100644 --- a/core/sr-staking-primitives/src/lib.rs +++ b/core/sr-staking-primitives/src/lib.rs @@ -17,16 +17,7 @@ //! A crate which contains primitives that are useful for implementation that uses staking //! approaches in general. Definitions related to sessions, slashing, etc go here. -use rstd::vec::Vec; - pub mod offence; /// Simple index type with which we can count sessions. pub type SessionIndex = u32; - -/// A trait for getting the currently elected validator set without coupling to the module that -/// provides this information. -pub trait CurrentElectedSet { - /// Returns the validator ids for the currently elected validator set. - fn current_elected_set() -> Vec; -} diff --git a/core/sr-staking-primitives/src/offence.rs b/core/sr-staking-primitives/src/offence.rs index c076103c18332841851be65a66faf5b444acaf63..db51f75df1bf3c973c8989446404b0fb8178182e 100644 --- a/core/sr-staking-primitives/src/offence.rs +++ b/core/sr-staking-primitives/src/offence.rs @@ -131,8 +131,7 @@ impl OnOffenceHandler for () { } /// A details about an offending authority for a particular kind of offence. -#[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, Encode, Decode, sr_primitives::RuntimeDebug)] pub struct OffenceDetails { /// The offending authority id pub offender: Offender, diff --git a/core/sr-std/without_std.rs b/core/sr-std/without_std.rs index 327e271049d586f7f35b6292ca52a5352634d703..9762c74367198fba65520e9a5b37ce0c9a192134 100755 --- a/core/sr-std/without_std.rs +++ b/core/sr-std/without_std.rs @@ -14,12 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -#[cfg(feature = "nightly")] #[doc(hidden)] 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 +36,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,12 +48,12 @@ 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; pub use core::convert; pub use core::default; +pub use core::fmt; pub use core::hash; pub use core::intrinsics; pub use core::iter; @@ -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 731c5b63c7137cf9d00c3253c9021d0e4af35e1d..24c54a739a2e0489a17aff64f84281fc280ebf1f 100644 --- a/core/sr-version/src/lib.rs +++ b/core/sr-version/src/lib.rs @@ -62,8 +62,8 @@ 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, Default)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize, Decode))] +#[derive(Clone, PartialEq, Eq, Encode, Default, sr_primitives::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Decode))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] pub struct RuntimeVersion { /// Identifies the different Substrate runtimes. There'll be at least polkadot and node. @@ -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, } @@ -141,7 +147,7 @@ impl RuntimeVersion { } #[cfg(feature = "std")] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Debug)] pub struct NativeVersion { /// Basic runtime version info. pub runtime_version: RuntimeVersion, @@ -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..d271a0e179d6d3eee5994b13ac1de5bd9ed4038c 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.7.0" diff --git a/core/state-db/src/lib.rs b/core/state-db/src/lib.rs index 81772e554bc572849a79d257a1e9a420b4b2644d..e561d9ce9617cb4c4edf92270160805bd151e1b8 100644 --- a/core/state-db/src/lib.rs +++ b/core/state-db/src/lib.rs @@ -41,6 +41,11 @@ use noncanonical::NonCanonicalOverlay; use pruning::RefWindow; use log::trace; +const PRUNING_MODE: &[u8] = b"mode"; +const PRUNING_MODE_ARCHIVE: &[u8] = b"archive"; +const PRUNING_MODE_ARCHIVE_CANON: &[u8] = b"archive_canonical"; +const PRUNING_MODE_CONSTRAINED: &[u8] = b"constrained"; + /// Database value type. pub type DBValue = Vec; @@ -77,6 +82,8 @@ pub enum Error { InvalidBlockNumber, /// Trying to insert block with unknown parent. InvalidParent, + /// Invalid pruning mode specified. Contains expected mode. + InvalidPruningMode(String), } /// Pinning error type. @@ -99,6 +106,7 @@ impl fmt::Debug for Error { Error::InvalidBlock => write!(f, "Trying to canonicalize invalid block"), Error::InvalidBlockNumber => write!(f, "Trying to insert block with invalid number"), Error::InvalidParent => write!(f, "Trying to insert block with unknown parent"), + Error::InvalidPruningMode(e) => write!(f, "Expected pruning mode: {}", e), } } } @@ -159,6 +167,14 @@ impl PruningMode { } } + /// Is this an archive (either ArchiveAll or ArchiveCanonical) pruning mode? + pub fn id(&self) -> &[u8] { + match self { + PruningMode::ArchiveAll => PRUNING_MODE_ARCHIVE, + PruningMode::ArchiveCanonical => PRUNING_MODE_ARCHIVE_CANON, + PruningMode::Constrained(_) => PRUNING_MODE_CONSTRAINED, + } + } } impl Default for PruningMode { @@ -183,6 +199,10 @@ struct StateDbSync { impl StateDbSync { pub fn new(mode: PruningMode, db: &D) -> Result, Error> { trace!(target: "state-db", "StateDb settings: {:?}", mode); + + // Check that settings match + Self::check_meta(&mode, db)?; + let non_canonical: NonCanonicalOverlay = NonCanonicalOverlay::new(db)?; let pruning: Option> = match mode { PruningMode::Constrained(Constraints { @@ -192,6 +212,7 @@ impl StateDbSync { PruningMode::Constrained(_) => Some(RefWindow::new(db)?), PruningMode::ArchiveAll | PruningMode::ArchiveCanonical => None, }; + Ok(StateDbSync { mode, non_canonical, @@ -200,18 +221,41 @@ impl StateDbSync { }) } + fn check_meta(mode: &PruningMode, db: &D) -> Result<(), Error> { + let db_mode = db.get_meta(&to_meta_key(PRUNING_MODE, &())).map_err(Error::Db)?; + trace!(target: "state-db", + "DB pruning mode: {:?}", + db_mode.as_ref().map(|v| std::str::from_utf8(&v)) + ); + match &db_mode { + Some(v) if v.as_slice() == mode.id() => Ok(()), + Some(v) => Err(Error::InvalidPruningMode(String::from_utf8_lossy(v).into())), + None => Ok(()), + } + } + pub fn insert_block(&mut self, hash: &BlockHash, number: u64, parent_hash: &BlockHash, mut changeset: ChangeSet) -> Result, Error> { + let mut meta = ChangeSet::default(); + if number == 0 { + // Save pruning mode when writing first block. + meta.inserted.push((to_meta_key(PRUNING_MODE, &()), self.mode.id().into())); + } + match self.mode { PruningMode::ArchiveAll => { changeset.deleted.clear(); // write changes immediately Ok(CommitSet { data: changeset, - meta: Default::default(), + meta: meta, }) }, PruningMode::Constrained(_) | PruningMode::ArchiveCanonical => { - self.non_canonical.insert(hash, number, parent_hash, changeset) + let commit = self.non_canonical.insert(hash, number, parent_hash, changeset); + commit.map(|mut c| { + c.meta.inserted.extend(meta.inserted); + c + }) } } } @@ -544,4 +588,23 @@ mod tests { assert!(sdb.is_pruned(&H256::from_low_u64_be(22), 2)); assert!(db.data_eq(&make_db(&[1, 21, 3, 921, 922, 93, 94]))); } + + #[test] + fn detects_incompatible_mode() { + let mut db = make_db(&[]); + let state_db = StateDb::new(PruningMode::ArchiveAll, &db).unwrap(); + db.commit( + &state_db + .insert_block::( + &H256::from_low_u64_be(0), + 0, + &H256::from_low_u64_be(0), + make_changeset(&[], &[]), + ) + .unwrap(), + ); + let new_mode = PruningMode::Constrained(Constraints { max_blocks: Some(2), max_mem: None }); + let state_db: Result, _> = StateDb::new(new_mode, &db); + assert!(state_db.is_err()); + } } diff --git a/core/state-machine/Cargo.toml b/core/state-machine/Cargo.toml index 94aff8b0789d34902b7a8be271f4977a1c7b8f49..7cd8601a3b636b281309b2ae0256fb1def3ddfcb 100644 --- a/core/state-machine/Cargo.toml +++ b/core/state-machine/Cargo.toml @@ -6,7 +6,7 @@ description = "Substrate State Machine" edition = "2018" [dependencies] -log = "0.4" +log = "0.4.8" parking_lot = "0.9.0" hash-db = "0.15.2" trie-db = "0.15.2" @@ -15,10 +15,12 @@ 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" +externalities = { package = "substrate-externalities", path = "../externalities" } [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..c2d1a0e3950d035a6de4bea3cc6c71b6985dff09 100644 --- a/core/state-machine/src/basic.rs +++ b/core/state-machine/src/basic.rs @@ -16,15 +16,15 @@ //! Basic implementation for Externalities. -use std::collections::HashMap; -use std::iter::FromIterator; +use std::{collections::HashMap, any::{TypeId, Any}, iter::FromIterator}; 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, ChildStorageKey}, + traits::Externalities, Blake2Hasher, hash::H256, +}; use log::warn; /// Simple HashMap-based Externalities impl. @@ -35,7 +35,6 @@ pub struct BasicExternalities { } impl BasicExternalities { - /// Create a new instance of `BasicExternalities` pub fn new( top: HashMap, Vec>, @@ -88,21 +87,37 @@ impl From, Vec>> for BasicExternalities { } } -impl Externalities for BasicExternalities where H::Out: Ord { +impl Externalities for BasicExternalities { fn storage(&self, key: &[u8]) -> Option> { self.top.get(key).cloned() } + fn storage_hash(&self, key: &[u8]) -> Option { + self.storage(key).map(|v| Blake2Hasher::hash(&v)) + } + fn original_storage(&self, key: &[u8]) -> Option> { - Externalities::::storage(self, key) + self.storage(key) + } + + fn original_storage_hash(&self, key: &[u8]) -> Option { + self.storage_hash(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> { - Externalities::::child_storage(self, storage_key, key) + fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + self.child_storage(storage_key, key).map(|v| Blake2Hasher::hash(&v)) + } + + fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + self.child_storage_hash(storage_key, key) + } + + fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + Externalities::child_storage(self, storage_key, key) } fn place_storage(&mut self, key: Vec, maybe_value: Option>) { @@ -119,9 +134,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 +146,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 +162,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)); } @@ -155,17 +170,17 @@ impl Externalities for BasicExternalities where H::Out: Ord { fn chain_id(&self) -> u64 { 42 } - fn storage_root(&mut self) -> H::Out { + fn storage_root(&mut self) -> H256 { let mut top = self.top.clone(); let keys: Vec<_> = self.children.keys().map(|k| k.to_vec()).collect(); // Single child trie implementation currently allows using the same child // empty root for all child trie. Using null storage key until multiple // type of child trie support. - let empty_hash = default_child_trie_root::>(&[]); + 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") + 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,30 +188,28 @@ impl Externalities for BasicExternalities where H::Out: Ord { top.insert(storage_key, child_root); } } - Layout::::trie_root(self.top.clone()) + + 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))); - InMemory::::default().child_storage_root(storage_key.as_ref(), delta).0 + InMemory::::default().child_storage_root(storage_key.as_ref(), delta).0 } else { - default_child_trie_root::>(storage_key.as_ref()) + default_child_trie_root::>(storage_key.as_ref()) } } - fn storage_changes_root(&mut self, _parent: H::Out) -> Result, ()> { + fn storage_changes_root(&mut self, _parent: H256) -> Result, ()> { Ok(None) } +} - fn offchain(&mut self) -> Option<&mut dyn offchain::Externalities> { - warn!("Call to non-existent offchain externalities set."); - None - } - - fn keystore(&self) -> Option { - warn!("Call to non-existent keystore."); +impl externalities::ExtensionStore for BasicExternalities { + fn extension_by_type_id(&mut self, _: TypeId) -> Option<&mut dyn Any> { + warn!("Extensions are not supported by `BasicExternalities`."); None } } @@ -204,14 +217,13 @@ impl Externalities for BasicExternalities where H::Out: Ord { #[cfg(test)] mod tests { use super::*; - use primitives::{Blake2Hasher, H256, map}; + use primitives::{H256, map}; use primitives::storage::well_known_keys::CODE; use hex_literal::hex; #[test] fn commit_should_work() { let mut ext = BasicExternalities::default(); - let ext = &mut ext as &mut dyn Externalities; ext.set_storage(b"doe".to_vec(), b"reindeer".to_vec()); ext.set_storage(b"dog".to_vec(), b"puppy".to_vec()); ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec()); @@ -223,7 +235,6 @@ mod tests { #[test] fn set_and_retrieve_code() { let mut ext = BasicExternalities::default(); - let ext = &mut ext as &mut dyn Externalities; let code = vec![1, 2, 3]; ext.set_storage(CODE.to_vec(), code.clone()); @@ -244,8 +255,6 @@ mod tests { ] ); - let ext = &mut ext as &mut dyn Externalities; - let child = || ChildStorageKey::from_vec(child_storage.clone()).unwrap(); assert_eq!(ext.child_storage(child(), b"doe"), Some(b"reindeer".to_vec())); 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..0e93302a95a547edf66cd498af701677642b5531 100644 --- a/core/state-machine/src/ext.rs +++ b/core/state-machine/src/ext.rs @@ -16,15 +16,23 @@ //! 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 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 trie::{MemoryDB, default_child_trie_root}; -use trie::trie_types::Layout; +use primitives::{ + storage::{ChildStorageKey, well_known_keys::is_child_storage_key}, + traits::Externalities, hexdisplay::HexDisplay, hash::H256, +}; +use trie::{trie_types::Layout, MemoryDB, default_child_trie_root}; +use externalities::Extensions; + +use std::{error, fmt, any::{Any, TypeId}}; +use log::{warn, trace}; const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime"; @@ -58,11 +66,7 @@ impl error::Error for Error { } /// Wraps a read-only backend, call executor, and current overlayed changes. -pub struct Ext<'a, H, N, B, T, O> -where - H: Hasher, - B: 'a + Backend, -{ +pub struct Ext<'a, H, N, B, T> where H: Hasher, B: 'a + Backend { /// The overlayed changes to write to. overlay: &'a mut OverlayedChanges, /// The storage backend to read from. @@ -78,33 +82,29 @@ 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)>, - /// 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, + changes_trie_transaction: Option<(MemoryDB, H::Out, ChangesTrieCacheAction)>, + /// Pseudo-unique id used for tracing. + pub id: u16, /// Dummy usage of N arg. - _phantom: ::std::marker::PhantomData, + _phantom: std::marker::PhantomData, + /// Extensions registered with this instance. + extensions: Option<&'a mut Extensions>, } -impl<'a, H, N, B, T, O> Ext<'a, H, N, B, T, O> +impl<'a, H, N, B, T> Ext<'a, H, N, B, T> where - H: Hasher, + H: Hasher, B: 'a + Backend, T: 'a + ChangesTrieStorage, - O: 'a + offchain::Externalities, - H::Out: Ord + 'static, N: crate::changes_trie::BlockNumber, { + /// Create a new `Ext` from overlayed changes and read-only backend pub fn new( overlay: &'a mut OverlayedChanges, backend: &'a B, changes_trie_storage: Option<&'a T>, - offchain_externalities: Option<&'a mut O>, - keystore: Option, + extensions: Option<&'a mut Extensions>, ) -> Self { Ext { overlay, @@ -112,21 +112,26 @@ where storage_transaction: None, changes_trie_storage, changes_trie_transaction: None, - offchain_externalities, - keystore, + id: rand::random(), _phantom: Default::default(), + extensions, } } /// 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, H256), + Option>, + ) { let _ = self.storage_root(); let (storage_transaction, changes_trie_transaction) = ( self.storage_transaction + .take() .expect("storage_transaction always set after calling storage root; qed"), self.changes_trie_transaction - .map(|(tx, _)| tx), + .take() + .map(|(tx, _, cache)| (tx, cache)), ); ( @@ -141,16 +146,14 @@ where fn mark_dirty(&mut self) { self.storage_transaction = None; } - } #[cfg(test)] -impl<'a, H, N, B, T, O> Ext<'a, H, N, B, T, O> +impl<'a, H, N, B, T> Ext<'a, H, N, B, T> where - H: Hasher, + H: Hasher, B: 'a + Backend, T: 'a + ChangesTrieStorage, - O: 'a + offchain::Externalities, N: crate::changes_trie::BlockNumber, { pub fn storage_pairs(&self) -> Vec<(Vec, Vec)> { @@ -167,77 +170,172 @@ where } } -impl<'a, B, T, H, N, O> Externalities for Ext<'a, H, N, B, T, O> +impl<'a, H, B, T, N> Externalities for Ext<'a, H, N, B, T> where - H: Hasher, + H: Hasher, B: 'a + Backend, T: 'a + ChangesTrieStorage, - O: 'a + offchain::Externalities, - H::Out: Ord + 'static, N: crate::changes_trie::BlockNumber, { 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 { + 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 { + 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), - } + _ => 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 +346,29 @@ 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 +379,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 +396,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(); @@ -293,9 +415,13 @@ where 42 } - fn storage_root(&mut self) -> H::Out { + fn storage_root(&mut self) -> H256 { 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 +431,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,37 +443,58 @@ 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()))) - .chain(self.overlay.prospective.children.get(storage_key) - .into_iter() - .flat_map(|map| map.1.clone().into_iter())); - - let root = self.backend.child_storage_root(storage_key, delta).0; - - self.overlay.set_storage(storage_key.to_vec(), Some(root.to_vec())); - + let (root, is_empty, _) = { + let delta = self.overlay.committed.children.get(storage_key) + .into_iter() + .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.clone().into_iter().map(|(k, v)| (k, v.value)))); + + self.backend.child_storage_root(storage_key, delta) + }; + + if is_empty { + self.overlay.set_storage(storage_key.into(), None); + } else { + self.overlay.set_storage(storage_key.into(), Some(root.clone())); + } + + trace!(target: "state-trace", "{:04x}: ChildRoot({}) {}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&root.as_ref()), + ); root } } - fn storage_changes_root(&mut self, parent_hash: H::Out) -> Result, ()> { + fn storage_changes_root(&mut self, parent_hash: H256) -> Result, ()> { let _guard = panic_handler::AbortGuard::force_abort(); self.changes_trie_transaction = build_changes_trie::<_, T, H, N>( self.backend, @@ -355,33 +502,44 @@ where self.overlay, parent_hash, )?; - Ok(self.changes_trie_transaction.as_ref().map(|(_, root)| root.clone())) - } - - fn offchain(&mut self) -> Option<&mut dyn offchain::Externalities> { - self.offchain_externalities.as_mut().map(|x| &mut **x as _) + 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 keystore(&self) -> Option { - self.keystore.clone() +impl<'a, H, B, T, N> externalities::ExtensionStore for Ext<'a, H, N, B, T> +where + H: Hasher, + B: 'a + Backend, + T: 'a + ChangesTrieStorage, + N: crate::changes_trie::BlockNumber, +{ + fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any> { + self.extensions.as_mut().and_then(|exts| exts.get_mut(type_id)) } } #[cfg(test)] mod tests { + use super::*; use hex_literal::hex; use codec::Encode; - use primitives::{Blake2Hasher}; - use primitives::storage::well_known_keys::EXTRINSIC_INDEX; - use crate::backend::InMemory; - use crate::changes_trie::{Configuration as ChangesTrieConfiguration, - InMemoryStorage as InMemoryChangesTrieStorage}; - use crate::overlayed_changes::OverlayedValue; - use super::*; + use primitives::{Blake2Hasher, storage::well_known_keys::EXTRINSIC_INDEX}; + use crate::{ + changes_trie::{ + Configuration as ChangesTrieConfiguration, + InMemoryStorage as InMemoryChangesTrieStorage, + }, backend::InMemory, overlayed_changes::OverlayedValue, + }; type TestBackend = InMemory; type TestChangesTrieStorage = InMemoryChangesTrieStorage; - type TestExt<'a> = Ext<'a, Blake2Hasher, u64, TestBackend, TestChangesTrieStorage, crate::NeverOffchainExt>; + type TestExt<'a> = Ext<'a, Blake2Hasher, u64, TestBackend, TestChangesTrieStorage>; fn prepare_overlay_with_changes() -> OverlayedChanges { OverlayedChanges { @@ -407,7 +565,7 @@ mod tests { fn storage_changes_root_is_none_when_storage_is_not_provided() { let mut overlay = prepare_overlay_with_changes(); let backend = TestBackend::default(); - let mut ext = TestExt::new(&mut overlay, &backend, None, None, None); + let mut ext = TestExt::new(&mut overlay, &backend, None, None); assert_eq!(ext.storage_changes_root(Default::default()).unwrap(), None); } @@ -417,7 +575,7 @@ mod tests { overlay.changes_trie_config = None; let storage = TestChangesTrieStorage::with_blocks(vec![(100, Default::default())]); let backend = TestBackend::default(); - let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None, None); + let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None); assert_eq!(ext.storage_changes_root(Default::default()).unwrap(), None); } @@ -426,7 +584,7 @@ mod tests { let mut overlay = prepare_overlay_with_changes(); let storage = TestChangesTrieStorage::with_blocks(vec![(99, Default::default())]); let backend = TestBackend::default(); - let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None, None); + let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None); assert_eq!( ext.storage_changes_root(Default::default()).unwrap(), Some(hex!("bb0c2ef6e1d36d5490f9766cfcc7dfe2a6ca804504c3bb206053890d6dd02376").into()), @@ -439,7 +597,7 @@ mod tests { overlay.prospective.top.get_mut(&vec![1]).unwrap().value = None; let storage = TestChangesTrieStorage::with_blocks(vec![(99, Default::default())]); let backend = TestBackend::default(); - let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None, None); + let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None); assert_eq!( ext.storage_changes_root(Default::default()).unwrap(), Some(hex!("96f5aae4690e7302737b6f9b7f8567d5bbb9eac1c315f80101235a92d9ec27f4").into()), diff --git a/core/state-machine/src/lib.rs b/core/state-machine/src/lib.rs index 8c2046e5917c60a356b6b3af4c1614016e65b908..c3092367f064645f79c7e3a4364460858a601693 100644 --- a/core/state-machine/src/lib.rs +++ b/core/state-machine/src/lib.rs @@ -18,18 +18,20 @@ #![warn(missing_docs)] -use std::{fmt, panic::UnwindSafe, result, marker::PhantomData}; -use std::borrow::Cow; -use log::warn; +use std::{fmt, result, collections::HashMap, panic::UnwindSafe, marker::PhantomData}; +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::OffchainExt, + traits::{KeystoreExt, CodeExecutor}, hexdisplay::HexDisplay, hash::H256, }; +use overlayed_changes::OverlayedChangeSet; +use externalities::Extensions; pub mod backend; mod changes_trie; +mod error; mod ext; mod testing; mod basic; @@ -38,9 +40,7 @@ mod proving_backend; mod trie_backend; mod trie_backend_essence; -use overlayed_changes::OverlayedChangeSet; -pub use trie::{TrieMut, DBValue, MemoryDB}; -pub use trie::trie_types::{Layout, TrieDBMut}; +pub use trie::{trie_types::{Layout, TrieDBMut}, TrieMut, DBValue, MemoryDB}; pub use testing::TestExternalities; pub use basic::BasicExternalities; pub use ext::Ext; @@ -50,9 +50,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 +64,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>); - - /// 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; -} +type DefaultHandler = fn(CallResult, CallResult) -> CallResult; -/// 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 +89,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 +119,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 +128,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,68 +147,73 @@ 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> { +pub struct StateMachine<'a, B, H, N, T, Exec> where H: Hasher, B: Backend { 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, - _hasher: PhantomData<(H, N)>, + overlay: &'a mut OverlayedChanges, + extensions: Extensions, + changes_trie_storage: Option<&'a T>, + _marker: PhantomData<(H, N)>, } -impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where - H: Hasher, - Exec: CodeExecutor, +impl<'a, B, H, N, T, Exec> StateMachine<'a, B, H, N, T, Exec> where + H: Hasher, + Exec: CodeExecutor, B: Backend, T: ChangesTrieStorage, - O: offchain::Externalities, - H::Out: Ord + 'static, N: crate::changes_trie::BlockNumber, { + /// Creates new substrate state machine. + pub fn new( + backend: &'a B, + changes_trie_storage: Option<&'a T>, + offchain_ext: Option, + overlay: &'a mut OverlayedChanges, + exec: &'a Exec, + method: &'a str, + call_data: &'a [u8], + keystore: Option, + ) -> Self { + let mut extensions = Extensions::new(); + + if let Some(keystore) = keystore { + extensions.register(keystore); + } + + if let Some(offchain) = offchain_ext { + extensions.register(offchain); + } + + Self { + backend, + exec, + method, + call_data, + extensions, + overlay, + changes_trie_storage, + _marker: 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. @@ -509,10 +222,10 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where /// /// Note: changes to code will be in place if this call is made again. For running partial /// blocks (e.g. a transaction at a time), ensure a different method is used. - pub fn execute( - &mut self, - strategy: ExecutionStrategy, - ) -> Result<(Vec, (B::Transaction, H::Out), Option>), Box> { + pub fn execute(&mut self, strategy: ExecutionStrategy) -> 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,31 +249,49 @@ 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( + let mut ext = Ext::new( self.overlay, self.backend, - self.changes_trie_storage, - self.offchain_ext.as_mut().map(|x| &mut **x), - self.keystore.clone(), + self.changes_trie_storage.clone(), + Some(&mut self.extensions), ); + + let id = ext.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, + &mut ext, self.method, self.call_data, use_native, native_call, ); + let (storage_delta, changes_delta) = if compute_tx { - let (storage_delta, changes_delta) = externalities.transaction(); + let (storage_delta, changes_delta) = ext.transaction(); (Some(storage_delta), changes_delta) } else { (None, None) }; + + trace!( + target: "state-trace", "{:04x}: Return. Native={:?}, Result={:?}", + id, + was_native, + result, + ); + (result, was_native, storage_delta, changes_delta) } @@ -570,23 +301,36 @@ 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, ) -> 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()) - || result.is_err() && wasm_result.is_err() { + || result.is_err() && wasm_result.is_err() + { (result, storage_delta, changes_delta) } else { (on_consensus_failure(wasm_result, result), wasm_storage_delta, wasm_changes_delta) @@ -601,17 +345,29 @@ 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 +388,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 +402,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 +410,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 _) @@ -694,13 +462,12 @@ pub fn prove_execution( exec: &Exec, method: &str, call_data: &[u8], - keystore: Option, + keystore: Option, ) -> Result<(Vec, Vec>), Box> where B: Backend, - H: Hasher, - Exec: CodeExecutor, - H::Out: Ord + 'static, + H: Hasher, + Exec: CodeExecutor, { let trie_backend = backend.as_trie_backend() .ok_or_else(|| Box::new(ExecutionError::UnableToGenerateProof) as Box)?; @@ -722,32 +489,24 @@ pub fn prove_execution_on_trie_backend( exec: &Exec, method: &str, call_data: &[u8], - keystore: Option, + keystore: Option, ) -> Result<(Vec, Vec>), Box> where S: trie_backend_essence::TrieBackendStorage, - H: Hasher, - Exec: CodeExecutor, - H::Out: Ord + 'static, + H: Hasher, + Exec: CodeExecutor, { 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, None, 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)) } @@ -759,11 +518,11 @@ pub fn execution_proof_check( exec: &Exec, method: &str, call_data: &[u8], - keystore: Option, + keystore: Option, ) -> Result, Box> where - H: Hasher, - Exec: CodeExecutor, + H: Hasher, + Exec: CodeExecutor, H::Out: Ord + 'static, { let trie_backend = create_proof_check_backend::(root.into(), proof)?; @@ -777,126 +536,150 @@ pub fn execution_proof_check_on_trie_backend( exec: &Exec, method: &str, call_data: &[u8], - keystore: Option, + keystore: Option, ) -> Result, Box> where - H: Hasher, - Exec: CodeExecutor, - H::Out: Ord + 'static, + H: Hasher, + Exec: CodeExecutor, { - 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, None, 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: Hasher, + 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 +687,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 +700,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 +731,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 +755,7 @@ mod tests { InMemoryStorage as InMemoryChangesTrieStorage, Configuration as ChangesTrieConfig, }; - use primitives::{Blake2Hasher, map}; + use primitives::{Blake2Hasher, map, traits::Externalities, storage::ChildStorageKey}; struct DummyCodeExecutor { change_changes_trie_config: bool, @@ -983,10 +764,14 @@ mod tests { fallback_succeeds: bool, } - impl CodeExecutor for DummyCodeExecutor { + impl CodeExecutor for DummyCodeExecutor { type Error = u8; - fn call, R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result>( + fn call< + E: Externalities, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> result::Result, + >( &self, ext: &mut E, _method: &str, @@ -1026,15 +811,17 @@ mod tests { } } - impl Error for u8 {} - #[test] fn execute_works() { - assert_eq!(new( - &trie_backend::tests::test_trie(), - Some(&InMemoryChangesTrieStorage::::new()), - NeverOffchainExt::new(), - &mut Default::default(), + 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), + None, + &mut overlayed_changes, &DummyCodeExecutor { change_changes_trie_config: false, native_available: true, @@ -1044,19 +831,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()), - NeverOffchainExt::new(), - &mut Default::default(), + 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), + None, + &mut overlayed_changes, &DummyCodeExecutor { change_changes_trie_config: false, native_available: true, @@ -1066,19 +860,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()), - NeverOffchainExt::new(), - &mut Default::default(), + 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), + None, + &mut overlayed_changes, &DummyCodeExecutor { change_changes_trie_config: false, native_available: true, @@ -1088,14 +886,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); } @@ -1164,7 +966,6 @@ mod tests { &mut overlay, backend, Some(&changes_trie_storage), - NeverOffchainExt::new(), None, ); ext.clear_prefix(b"ab"); @@ -1195,7 +996,6 @@ mod tests { &mut overlay, backend, Some(&changes_trie_storage), - NeverOffchainExt::new(), None, ); @@ -1228,20 +1028,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 +1052,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), + None, + &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), + None, + &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..53a66dc49ee05e9f25025a241728343e43dca62f 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> { @@ -402,7 +420,6 @@ mod tests { &mut overlay, &backend, Some(&changes_trie_storage), - crate::NeverOffchainExt::new(), None, ); const ROOT: [u8; 32] = hex!("39245109cef3758c2eed2ccba8d9b370a917850af3824bc8348d505df2c298fa"); @@ -414,9 +431,12 @@ mod tests { fn changes_trie_configuration_is_saved() { let mut overlay = OverlayedChanges::default(); assert!(overlay.changes_trie_config.is_none()); - assert_eq!(overlay.set_changes_trie_config(ChangesTrieConfig { - digest_interval: 4, digest_levels: 1, - }), true); + assert_eq!( + overlay.set_changes_trie_config( + ChangesTrieConfig { digest_interval: 4, digest_levels: 1, }, + ), + true, + ); assert!(overlay.changes_trie_config.is_some()); } diff --git a/core/state-machine/src/proving_backend.rs b/core/state-machine/src/proving_backend.rs index 5e8f618c826466a0b798e9f3512f4e1c2982e767..c6c4ef1ec8c2697682ad4c0d43a030855389ff92 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, storage::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 00a0208a1f72fccd12e2c18bc6a3e411eb942242..16ff62020b59401f81f282659ef0ed867a11f635 100644 --- a/core/state-machine/src/testing.rs +++ b/core/state-machine/src/testing.rs @@ -16,34 +16,47 @@ //! Test implementation for Externalities. -use std::collections::{HashMap}; +use std::{collections::HashMap, any::{Any, TypeId}}; 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::{ + InMemoryStorage as ChangesTrieInMemoryStorage, + BlockNumber as ChangesTrieBlockNumber, + }, + ext::Ext, }; 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} + }, + hash::H256, Blake2Hasher, }; use codec::Encode; -use super::{ChildStorageKey, Externalities, OverlayedChanges}; - -const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime"; +use externalities::{Extensions, Extension}; type StorageTuple = (HashMap, Vec>, HashMap, HashMap, Vec>>); /// Simple HashMap-based Externalities impl. -pub struct TestExternalities { +pub struct TestExternalities=Blake2Hasher, N: ChangesTrieBlockNumber=u64> { overlay: OverlayedChanges, backend: InMemory, changes_trie_storage: ChangesTrieInMemoryStorage, - offchain: Option>, - keystore: Option, + extensions: Extensions, } -impl TestExternalities { +impl, N: ChangesTrieBlockNumber> TestExternalities { + + /// Get externalities implementation. + pub fn ext(&mut self) -> Ext, ChangesTrieInMemoryStorage> { + Ext::new( + &mut self.overlay, + &self.backend, + Some(&self.changes_trie_storage), + Some(&mut self.extensions), + ) + } + /// Create a new instance of `TestExternalities` with storage. pub fn new(storage: StorageTuple) -> Self { Self::new_with_code(&[], storage) @@ -74,8 +87,7 @@ impl TestExternalities { overlay, changes_trie_storage: ChangesTrieInMemoryStorage::new(), backend: backend.into(), - offchain: None, - keystore: None, + extensions: Default::default(), } } @@ -84,14 +96,9 @@ impl TestExternalities { self.backend = self.backend.update(vec![(None, k, Some(v))]); } - /// Set offchain externaltiies. - pub fn set_offchain_externalities(&mut self, offchain: impl offchain::Externalities + 'static) { - self.offchain = Some(Box::new(offchain)); - } - - /// Set keystore. - pub fn set_keystore(&mut self, keystore: BareCryptoStorePtr) { - self.keystore = Some(keystore); + /// Registers the given extension for this instance. + pub fn register_extension(&mut self, ext: E) { + self.extensions.register(ext); } /// Get mutable reference to changes trie storage. @@ -108,22 +115,30 @@ 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::>() }); self.backend.update(top.chain(children).collect()) } + + /// Execute the given closure while `self` is set as externalities. + /// + /// Returns the result of the given closure. + pub fn execute_with(&mut self, execute: impl FnOnce() -> R) -> R { + let mut ext = self.ext(); + externalities::set_and_run_with_externalities(&mut ext, execute) + } } -impl std::fmt::Debug for TestExternalities { +impl, N: ChangesTrieBlockNumber> std::fmt::Debug for TestExternalities { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, "overlay: {:?}\nbackend: {:?}", self.overlay, self.backend.pairs()) } } -impl PartialEq for TestExternalities { +impl, N: ChangesTrieBlockNumber> PartialEq for TestExternalities { /// This doesn't test if they are in the same state, only if they contains the /// same data at this state fn eq(&self, other: &TestExternalities) -> bool { @@ -131,174 +146,35 @@ impl PartialEq for TestExternalities } } -impl Default for TestExternalities { +impl, N: ChangesTrieBlockNumber> Default for TestExternalities { fn default() -> Self { Self::new(Default::default()) } } -impl From for TestExternalities { +impl, N: ChangesTrieBlockNumber> From for TestExternalities { fn from(storage: StorageTuple) -> Self { Self::new(storage) } } -impl Externalities for TestExternalities - where - H: Hasher, - N: ChangesTrieBlockNumber, - H::Out: Ord + 'static +impl externalities::ExtensionStore for TestExternalities where + H: Hasher, + N: ChangesTrieBlockNumber, { - fn storage(&self, key: &[u8]) -> Option> { - 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)) - } - - fn original_storage(&self, key: &[u8]) -> Option> { - self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL) - } - - 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())) - .unwrap_or_else(|| self.backend - .child_storage(storage_key.as_ref(), key) - .expect(EXT_NOT_ALLOWED_TO_FAIL) - ) - } - - 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())) - .expect(EXT_NOT_ALLOWED_TO_FAIL) - } - - fn place_storage(&mut self, key: Vec, maybe_value: Option>) { - if is_child_storage_key(&key) { - panic!("Refuse to directly set child storage key"); - } - - self.overlay.set_storage(key, maybe_value); - } - - fn place_child_storage( - &mut self, - 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) { - let backend = &self.backend; - let overlay = &mut self.overlay; - - overlay.clear_child_storage(storage_key.as_ref()); - backend.for_keys_in_child_storage(storage_key.as_ref(), |key| { - overlay.set_child_storage(storage_key.as_ref().to_vec(), key.to_vec(), None); - }); - } - - fn clear_prefix(&mut self, prefix: &[u8]) { - if is_child_storage_key(prefix) { - panic!("Refuse to directly clear prefix that is part of child storage key"); - } - - self.overlay.clear_prefix(prefix); - - let backend = &self.backend; - let overlay = &mut self.overlay; - backend.for_keys_with_prefix(prefix, |key| { - overlay.set_storage(key.to_vec(), None); - }); - } - - fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { - - self.overlay.clear_child_prefix(storage_key.as_ref(), prefix); - - let backend = &self.backend; - let overlay = &mut self.overlay; - backend.for_child_keys_with_prefix(storage_key.as_ref(), prefix, |key| { - overlay.set_child_storage(storage_key.as_ref().to_vec(), key.to_vec(), None); - }); - } - - fn chain_id(&self) -> u64 { 42 } - - fn storage_root(&mut self) -> H::Out { - - let child_storage_keys = - self.overlay.prospective.children.keys() - .chain(self.overlay.committed.children.keys()); - - 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()))) - .chain(self.overlay.prospective.children.get(storage_key) - .into_iter() - .flat_map(|map| map.1.iter().map(|(k, v)| (k.clone(), v.clone())))))); - - - // compute and memoize - let delta = self.overlay.committed.top.iter().map(|(k, v)| (k.clone(), v.value.clone())) - .chain(self.overlay.prospective.top.iter().map(|(k, v)| (k.clone(), v.value.clone()))); - self.backend.full_storage_root(delta, child_delta_iter).0 - - } - - 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()))) - .chain(self.overlay.prospective.children.get(storage_key) - .into_iter() - .flat_map(|map| map.1.clone().into_iter())); - - self.backend.child_storage_root(storage_key, delta) - }; - if is_empty { - self.overlay.set_storage(storage_key.into(), None); - } else { - self.overlay.set_storage(storage_key.into(), Some(root.clone())); - } - root - } - - fn storage_changes_root(&mut self, parent: H::Out) -> Result, ()> { - Ok(build_changes_trie::<_, _, H, N>( - &self.backend, - Some(&self.changes_trie_storage), - &self.overlay, - parent, - )?.map(|(_, root)| root)) - } - - fn offchain(&mut self) -> Option<&mut dyn offchain::Externalities> { - self.offchain - .as_mut() - .map(|x| &mut **x as _) - } - - fn keystore(&self) -> Option { - self.keystore.clone() + fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any> { + self.extensions.get_mut(type_id) } } #[cfg(test)] mod tests { use super::*; - use primitives::{Blake2Hasher, H256}; + use primitives::traits::Externalities; use hex_literal::hex; #[test] fn commit_should_work() { let mut ext = TestExternalities::::default(); + let mut ext = ext.ext(); ext.set_storage(b"doe".to_vec(), b"reindeer".to_vec()); ext.set_storage(b"dog".to_vec(), b"puppy".to_vec()); ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec()); @@ -309,6 +185,7 @@ mod tests { #[test] fn set_and_retrieve_code() { let mut ext = TestExternalities::::default(); + let mut ext = ext.ext(); let code = vec![1, 2, 3]; ext.set_storage(CODE.to_vec(), code.clone()); diff --git a/core/state-machine/src/trie_backend.rs b/core/state-machine/src/trie_backend.rs index 53c293b7ad17f3de567fd5cbccc935cb4946fe8b..432ccf3e75f0e47319a30c12daaf3c1a03c7747f 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) } @@ -160,7 +168,7 @@ impl, H: Hasher> Backend for TrieBackend where let mut write_overlay = S::Overlay::default(); let mut root = match self.storage(storage_key) { - Ok(value) => value.unwrap_or(default_child_trie_root::>(storage_key)), + Ok(value) => value.unwrap_or(default_root.clone()), Err(e) => { warn!(target: "trie", "Failed to read child storage root: {}", e); default_root.clone() 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 1afc4fd40c83cfd62fc12e2ce1ff5c7c9a28c1ea..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" +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" -rand = "0.6" -serde = { version = "1.0.81", features = ["derive"] } -slog = { version = "^2", features = ["nested-values"] } +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 58e2857cf3c20e17bb5f79db1ac1c64d89cc44c9..de13b34d69753e3ecd2a6b74907ba892fe38f75f 100644 --- a/core/test-client/Cargo.toml +++ b/core/test-client/Cargo.toml @@ -9,7 +9,7 @@ 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" +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" } 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 79e1027b9547e431d09601fd91c853681d5ecde4..dbe4431456a7494385a3525086586968cf510163 100644 --- a/core/test-client/src/lib.rs +++ b/core/test-client/src/lib.rs @@ -24,7 +24,7 @@ pub use client::{ExecutionStrategies, blockchain, backend, self}; pub use client_db::{Backend, self}; pub use client_ext::ClientExt; pub use consensus; -pub use executor::{NativeExecutor, self}; +pub use executor::{NativeExecutor, WasmExecutionMethod, self}; pub use keyring::{ AccountKeyring, ed25519::Keyring as Ed25519Keyring, @@ -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. @@ -100,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 { @@ -189,6 +187,7 @@ impl TestClientBuilder self.backend.clone(), executor, storage, + Default::default(), self.execution_strategies, ).expect("Creates new client"); @@ -199,7 +198,7 @@ impl TestClientBuilder } impl TestClientBuilder< - client::LocalCallExecutor>, + client::LocalCallExecutor>, Backend, G, > { @@ -210,70 +209,22 @@ impl TestClientBuilder< ) -> ( client::Client< Backend, - client::LocalCallExecutor>, + client::LocalCallExecutor>, Block, RuntimeApi >, client::LongestChain, ) where - I: Into>>, + I: Into>>, E: executor::NativeExecutionDispatch, Backend: client::backend::Backend, Block: BlockT::Out>, { - let executor = executor.into().unwrap_or_else(|| executor::NativeExecutor::new(None)); + let executor = executor.into().unwrap_or_else(|| + NativeExecutor::new(WasmExecutionMethod::Interpreted, None) + ); let executor = LocalCallExecutor::new(self.backend.clone(), executor, self.keystore.take()); 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 56c9915192e0f9f435839df99acf07ba3d26c314..4e7c3f8bca450f035706ad465fef44442b62f7ea 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 } @@ -27,10 +27,11 @@ 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 } +srml-system-rpc-runtime-api = { path = "../../srml/system/rpc/runtime-api", default-features = false } [dev-dependencies] substrate-executor = { path = "../executor" } @@ -38,13 +39,12 @@ substrate-test-runtime-client = { path = "./client" } state_machine = { package = "substrate-state-machine", path = "../state-machine" } [build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2", path = "../utils/wasm-builder-runner" } +wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.4", path = "../utils/wasm-builder-runner" } [features] default = [ "std", ] -no_std = [] std = [ "log", "serde", @@ -69,6 +69,7 @@ std = [ "srml-babe/std", "srml-timestamp/std", "srml-system/std", + "srml-system-rpc-runtime-api/std", "app-crypto/std", "session/std", ] diff --git a/core/test-runtime/build.rs b/core/test-runtime/build.rs index e412123b94d88b77d775892bae428181b3c7a857..200cd6d42c2d7705c01ccd4b6b9e26528535163d 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.8", }, // 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..affbae62c22e77d4b66acb8d8f3efc94aa7bcd01 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; @@ -37,7 +39,7 @@ pub mod prelude { // Client structs pub use super::{ TestClient, TestClientBuilder, Backend, LightBackend, - Executor, LightExecutor, LocalExecutor, NativeExecutor, + Executor, LightExecutor, LocalExecutor, NativeExecutor, WasmExecutionMethod, }; // Keyring pub use super::{AccountKeyring, Sr25519Keyring}; @@ -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 executor = NativeExecutor::new(WasmExecutionMethod::Interpreted, None); 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 55b6ad9b5fe148bf12ee3afadac673ca10a14535..45d86f891c594c2f7dd8807f90ba198e2ebb1490 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -25,7 +25,15 @@ pub mod system; use rstd::{prelude::*, marker::PhantomData}; use codec::{Encode, Decode, Input, Error}; -use primitives::{Blake2Hasher, OpaqueMetadata}; +use primitives::{ + Blake2Hasher, + OpaqueMetadata, + RuntimeDebug, + testing::{ + ED25519, + SR25519, + } +}; use app_crypto::{ed25519, sr25519, RuntimeAppPublic}; pub use app_crypto; use trie_db::{TrieMut, Trie}; @@ -38,14 +46,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}; @@ -84,8 +94,7 @@ pub fn native_version() -> NativeVersion { } /// Calls in transactions. -#[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] pub struct Transfer { pub from: AccountId, pub to: AccountId, @@ -104,8 +113,7 @@ impl Transfer { } /// Extrinsic for test-runtime. -#[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] pub enum Extrinsic { AuthoritiesChange(Vec), Transfer(Transfer, AccountSignature), @@ -123,17 +131,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 +149,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 +159,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 +194,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(); @@ -277,6 +286,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 { @@ -319,6 +330,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(); } } } @@ -339,8 +352,7 @@ impl_outer_origin!{ pub enum Origin for Runtime where system = srml_system {} } -#[derive(Clone, Encode, Decode, Eq, PartialEq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug)] pub struct Event; impl From for Event { @@ -368,7 +380,6 @@ impl srml_system::Trait for Runtime { type Lookup = IdentityLookup; type Header = Header; type Event = Event; - type WeightMultiplierUpdate = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; @@ -391,6 +402,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. @@ -439,9 +454,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, } } @@ -477,7 +492,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], @@ -587,6 +602,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 { @@ -600,25 +620,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: >::secondary_slots().0, + secondary_slots: true, } } } @@ -626,7 +636,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(); } } @@ -635,6 +645,12 @@ cfg_if! { SessionKeys::generate(None) } } + + impl srml_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(_account: AccountId) -> Index { + 0 + } + } } } else { impl_runtime_apis! { @@ -661,7 +677,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], @@ -802,6 +818,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 { @@ -815,25 +836,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: >::secondary_slots().0, + secondary_slots: true, } } } @@ -841,7 +852,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() } } @@ -850,6 +861,12 @@ cfg_if! { SessionKeys::generate(None) } } + + impl srml_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(_account: AccountId) -> Index { + 0 + } + } } } } @@ -884,6 +901,46 @@ 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::{ @@ -978,4 +1035,15 @@ mod tests { 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..fc4de0ce4b91106d145054659c89b7a927d2ab61 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, 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,37 +157,29 @@ 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| { - twox_128(&nonce.to_keyed_vec(&from.encode())).to_vec() - }; + let encode = |from: &AccountId, nonce: u64| (from, nonce).encode(); let requires = if tx.nonce != expected_nonce && tx.nonce > 0 { - let mut deps = Vec::new(); - deps.push(hash(&tx.from, tx.nonce - 1)); - deps + vec![encode(&tx.from, tx.nonce - 1)] } else { - Vec::new() + vec![] }; - let provides = { - let mut p = Vec::new(); - p.push(hash(&tx.from, tx.nonce)); - p - }; + let provides = vec![encode(&tx.from, tx.nonce)]; - TransactionValidity::Valid(ValidTransaction { + Ok(ValidTransaction { priority: tx.amount, requires, provides, @@ -199,8 +202,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 +234,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 +242,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 +252,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 +264,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 +283,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 +293,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 +301,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()); } } @@ -310,28 +311,46 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) { mod tests { use super::*; - use runtime_io::{with_externalities, TestExternalities}; + use runtime_io::TestExternalities; use substrate_test_runtime_client::{AccountKeyring, Sr25519Keyring}; use crate::{Header, Transfer, WASM_BINARY}; - use primitives::{Blake2Hasher, map}; - use substrate_executor::WasmExecutor; + use primitives::{NeverNativeValue, map, traits::CodeExecutor}; + use substrate_executor::{NativeExecutor, WasmExecutionMethod, native_executor_instance}; + use runtime_io::twox_128; + + // Declare an instance of the native executor dispatch for the test runtime. + native_executor_instance!( + NativeDispatch, + crate::api::dispatch, + crate::native_version + ); + + fn executor() -> NativeExecutor { + NativeExecutor::new(WasmExecutionMethod::Interpreted, None) + } - fn new_test_ext() -> TestExternalities { + fn new_test_ext() -> TestExternalities { let authorities = vec![ Sr25519Keyring::Alice.to_raw_public(), Sr25519Keyring::Bob.to_raw_public(), Sr25519Keyring::Charlie.to_raw_public() ]; - TestExternalities::new((map![ - twox_128(b"latest").to_vec() => vec![69u8; 32], - twox_128(b"sys:auth").to_vec() => authorities.encode(), - blake2_256(&AccountKeyring::Alice.to_raw_public().to_keyed_vec(b"balance:")).to_vec() => { - vec![111u8, 0, 0, 0, 0, 0, 0, 0] - } - ], map![])) + TestExternalities::new_with_code( + WASM_BINARY, + ( + map![ + twox_128(b"latest").to_vec() => vec![69u8; 32], + twox_128(b"sys:auth").to_vec() => authorities.encode(), + blake2_256(&AccountKeyring::Alice.to_raw_public().to_keyed_vec(b"balance:")).to_vec() => { + vec![111u8, 0, 0, 0, 0, 0, 0, 0] + } + ], + map![], + ) + ) } - fn block_import_works(block_executor: F) where F: Fn(Block, &mut TestExternalities) { + fn block_import_works(block_executor: F) where F: Fn(Block, &mut TestExternalities) { let h = Header { parent_hash: [69u8; 32].into(), number: 1, @@ -344,28 +363,33 @@ mod tests { extrinsics: vec![], }; - with_externalities(&mut new_test_ext(), || polish_block(&mut b)); + new_test_ext().execute_with(|| polish_block(&mut b)); block_executor(b, &mut new_test_ext()); } #[test] fn block_import_works_native() { - block_import_works(|b, ext| { - with_externalities(ext, || { - execute_block(b); - }); - }); + block_import_works(|b, ext| ext.execute_with(|| execute_block(b))); } #[test] fn block_import_works_wasm() { block_import_works(|b, ext| { - WasmExecutor::new().call(ext, 8, &WASM_BINARY, "Core_execute_block", &b.encode()).unwrap(); + let mut ext = ext.ext(); + executor().call::<_, NeverNativeValue, fn() -> _>( + &mut ext, + "Core_execute_block", + &b.encode(), + false, + None, + ).0.unwrap(); }) } - fn block_import_with_transaction_works(block_executor: F) where F: Fn(Block, &mut TestExternalities) { + fn block_import_with_transaction_works(block_executor: F) + where F: Fn(Block, &mut TestExternalities) + { let mut b1 = Block { header: Header { parent_hash: [69u8; 32].into(), @@ -385,7 +409,7 @@ mod tests { }; let mut dummy_ext = new_test_ext(); - with_externalities(&mut dummy_ext, || polish_block(&mut b1)); + dummy_ext.execute_with(|| polish_block(&mut b1)); let mut b2 = Block { header: Header { @@ -411,26 +435,26 @@ mod tests { ], }; - with_externalities(&mut dummy_ext, || polish_block(&mut b2)); + dummy_ext.execute_with(|| polish_block(&mut b2)); drop(dummy_ext); let mut t = new_test_ext(); - with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(balance_of(AccountKeyring::Alice.into()), 111); assert_eq!(balance_of(AccountKeyring::Bob.into()), 0); }); block_executor(b1, &mut t); - with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(balance_of(AccountKeyring::Alice.into()), 42); assert_eq!(balance_of(AccountKeyring::Bob.into()), 69); }); block_executor(b2, &mut t); - with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(balance_of(AccountKeyring::Alice.into()), 0); assert_eq!(balance_of(AccountKeyring::Bob.into()), 42); assert_eq!(balance_of(AccountKeyring::Charlie.into()), 69); @@ -439,17 +463,20 @@ mod tests { #[test] fn block_import_with_transaction_works_native() { - block_import_with_transaction_works(|b, ext| { - with_externalities(ext, || { - execute_block(b); - }); - }); + block_import_with_transaction_works(|b, ext| ext.execute_with(|| execute_block(b))); } #[test] fn block_import_with_transaction_works_wasm() { block_import_with_transaction_works(|b, ext| { - WasmExecutor::new().call(ext, 8, &WASM_BINARY, "Core_execute_block", &b.encode()).unwrap(); + let mut ext = ext.ext(); + executor().call::<_, NeverNativeValue, fn() -> _>( + &mut ext, + "Core_execute_block", + &b.encode(), + false, + None, + ).0.unwrap(); }) } } diff --git a/core/transaction-pool/Cargo.toml b/core/transaction-pool/Cargo.toml index 5e9973b6dc1908824209850875fe3fde555c71d2..33ec9e9ece176b49ffca017ca9b7d0603c9e32d9 100644 --- a/core/transaction-pool/Cargo.toml +++ b/core/transaction-pool/Cargo.toml @@ -5,8 +5,9 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = "0.14.0" -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 a19f3aaccce592b0322762a091b0414bb7ecdf8a..fa0d6f14b6f324e943f68e83c57dd032c3ca1273 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-preview = "=0.3.0-alpha.17" -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.7.0" 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 ce457c01796b2a0e1882eada3f262eef7026a98c..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,11 @@ 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 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 07542afab002bb271f9c9e55fe1c169cb56a423d..621aeabda8ee9917124bf3784a4863ee05c3f3d0 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::channel::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 + Unpin; /// 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,124 +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) => if validity.provides.is_empty() { - Err(error::Error::NoTagsProvided.into()) - } else { - 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. @@ -225,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. @@ -272,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. @@ -285,197 +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 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; const INVALID_NONCE: u64 = 254; - #[derive(Debug, Default)] + #[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. @@ -488,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: if nonce == INVALID_NONCE { vec![] } else { vec![vec![nonce as u8]] }, longevity: 3, propagate: true, })) - } + }) } /// Returns a block number given the block id. @@ -542,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]); @@ -565,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); @@ -582,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); @@ -618,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] @@ -680,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] @@ -715,12 +655,12 @@ 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); @@ -733,12 +673,12 @@ mod tests { let pool = pool(); // when - let err = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + 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(); + }))).unwrap_err(); // then assert_eq!(pool.status().ready, 0); @@ -753,17 +693,17 @@ 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); @@ -778,17 +718,17 @@ 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); @@ -803,22 +743,22 @@ 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 @@ -837,11 +777,11 @@ 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 @@ -861,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 @@ -895,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 @@ -905,7 +845,7 @@ 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 @@ -921,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 @@ -935,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(); }); @@ -949,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/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 16849d9715004b4216500095b12dc825883ca02d..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" @@ -21,11 +21,11 @@ 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.2" } -trie-standardmap = { version = "0.15.2" } -keccak-hasher = { version = "0.15.2" } -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/trie/src/node_header.rs b/core/trie/src/node_header.rs index 50d3d87250de6002c5df232bb44cc7db6c250a96..616273e574d6007106a495965d384bb0238c20fd 100644 --- a/core/trie/src/node_header.rs +++ b/core/trie/src/node_header.rs @@ -22,7 +22,7 @@ use rstd::iter::once; /// A node header #[derive(Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(primitives::RuntimeDebug)] pub(crate) enum NodeHeader { Null, Branch(bool, usize), diff --git a/core/utils/fork-tree/src/lib.rs b/core/utils/fork-tree/src/lib.rs index 42646b652164e3a1ce9df9a3357828d8a0cac1eb..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)); } } @@ -510,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, @@ -560,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 @@ -573,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) => {}, } } @@ -597,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>, @@ -1181,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(); // @@ -1215,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, @@ -1227,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..ab8a539054820445d744711a99192b3adf6f524f 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.4" 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..1739c5eff211e7b5aaa92237a31f80b1a8b32b16 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"); } @@ -198,6 +227,11 @@ fn run_project(project_folder: &Path) { cmd.arg("--release"); } + // Unset the `CARGO_TARGET_DIR` to prevent a cargo deadlock (cargo locks a target dir exclusive). + // The runner project is created in `CARGO_TARGET_DIR` and executing it will create a sub target + // directory inside of `CARGO_TARGET_DIR`. + cmd.env_remove("CARGO_TARGET_DIR"); + if !cmd.status().map(|s| s.success()).unwrap_or(false) { // Don't spam the output with backtraces when a build failed! process::exit(1); @@ -226,7 +260,7 @@ fn check_provide_dummy_wasm_binary() -> bool { fn provide_dummy_wasm_binary(file_path: &Path) { fs::write( file_path, - "pub const WASM_BINARY: &[u8] = &[]; pub const WASM_BINARY_BLOATY: &[u8] = &[];" + "pub const WASM_BINARY: &[u8] = &[]; pub const WASM_BINARY_BLOATY: &[u8] = &[];", ).expect("Writing dummy WASM binary should not fail"); } diff --git a/core/utils/wasm-builder/Cargo.toml b/core/utils/wasm-builder/Cargo.toml index 44288dbcd268f97844230cc9b9f5a701cfcaac9f..e9d38f2bd23f6168d9aacb86808e4f5d8243c3ab 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.8" authors = ["Parity Technologies "] description = "Utility for building WASM binaries" edition = "2018" @@ -10,8 +10,9 @@ 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" +wasm-gc-api = "0.1.11" diff --git a/core/utils/wasm-builder/README.md b/core/utils/wasm-builder/README.md index 8a8c67d6a8c1d164e10d1d4f68a714d83086f5d9..b15d2ebfab2a0dbe124593ceb97f9c9bf8a574ca 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 @@ -60,7 +57,6 @@ be `NODE_RUNTIME`. WASM builder requires the following prerequisities for building the WASM binary: - rust nightly + `wasm32-unknown-unknown` toolchain -- wasm-gc License: GPL-3.0 diff --git a/core/utils/wasm-builder/src/lib.rs b/core/utils/wasm-builder/src/lib.rs index 5bb0342c665dec533f79c0603b903ef4b4dcbd63..93e1700792ab4619262b49da384cb4db0e1e9785 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 @@ -76,7 +75,6 @@ //! WASM builder requires the following prerequisities for building the WASM binary: //! //! - rust nightly + `wasm32-unknown-unknown` toolchain -//! - wasm-gc //! use std::{env, fs, path::PathBuf, process::{Command, Stdio, self}}; @@ -96,6 +94,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 +107,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 +142,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 +165,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 @@ -183,9 +205,7 @@ impl CargoCommand { } fn args(&mut self, args: &[&str]) -> &mut Self { - for arg in args { - self.arg(arg); - } + args.into_iter().for_each(|a| { self.arg(a); }); self } @@ -205,12 +225,17 @@ impl CargoCommand { /// Check if the supplied cargo command is a nightly version fn is_nightly(&self) -> bool { - self.command() - .arg("--version") - .output() - .map_err(|_| ()) - .and_then(|o| String::from_utf8(o.stdout).map_err(|_| ())) - .unwrap_or_default() - .contains("-nightly") + // `RUSTC_BOOTSTRAP` tells a stable compiler to behave like a nightly. So, when this env + // variable is set, we can assume that whatever rust compiler we have, it is a nightly compiler. + // For "more" information, see: + // https://github.com/rust-lang/rust/blob/fa0f7d0080d8e7e9eb20aa9cbf8013f96c81287f/src/libsyntax/feature_gate/check.rs#L891 + env::var("RUSTC_BOOTSTRAP").is_ok() || + self.command() + .arg("--version") + .output() + .map_err(|_| ()) + .and_then(|o| String::from_utf8(o.stdout).map_err(|_| ())) + .unwrap_or_default() + .contains("-nightly") } } diff --git a/core/utils/wasm-builder/src/prerequisites.rs b/core/utils/wasm-builder/src/prerequisites.rs index 52ff40887cfd829074458134f37794453ee481a1..3a7f8387dc8b8c09de41b0d8cbdc2ab449765c6d 100644 --- a/core/utils/wasm-builder/src/prerequisites.rs +++ b/core/utils/wasm-builder/src/prerequisites.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::{process::{Command, Stdio}, fs}; +use std::fs; use tempfile::tempdir; @@ -23,32 +23,18 @@ use tempfile::tempdir; /// # Returns /// Returns `None` if everything was found and `Some(ERR_MSG)` if something could not be found. pub fn check() -> Option<&'static str> { - if !check_nightly_installed() { + if !check_nightly_installed(){ return Some("Rust nightly not installed, please install it!") } - if Command::new("wasm-gc") - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status() - .map(|s| !s.success()).unwrap_or(true) - { - 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 { - let command = crate::get_nightly_cargo(); - command.is_nightly() + crate::get_nightly_cargo().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 +58,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..1651642ee0a7b53a5c7cdd624e448357b0b123d7 100644 --- a/core/utils/wasm-builder/src/wasm_project.rs +++ b/core/utils/wasm-builder/src/wasm_project.rs @@ -14,7 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::{fs, path::{Path, PathBuf}, borrow::ToOwned, process::{Command, self}, env}; +use crate::write_file_if_changed; + +use std::{fs, path::{Path, PathBuf}, borrow::ToOwned, process, 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(), ); @@ -298,15 +352,8 @@ fn compact_wasm_file( .join(format!("{}.wasm", wasm_binary)); let wasm_compact_file = project.join(format!("{}.compact.wasm", wasm_binary)); - let res = Command::new("wasm-gc") - .arg(&wasm_file) - .arg(&wasm_compact_file) - .status() - .map(|s| s.success()); - - if !res.unwrap_or(false) { - panic!("Failed to compact generated WASM binary."); - } + wasm_gc::garbage_collect_file(&wasm_file, &wasm_compact_file) + .expect("Failed to compact generated WASM binary."); (WasmBinary(wasm_compact_file), WasmBinaryBloaty(wasm_file)) } @@ -349,4 +396,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 93b1abe79a2e353a9d5de606e62915dca8d24d2e..bb61c2c2ca7d86c93478782efd538d4694b8e547 100644 --- a/node-template/Cargo.toml +++ b/node-template/Cargo.toml @@ -10,12 +10,12 @@ 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.2" @@ -27,13 +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" } -babe = { package = "substrate-consensus-babe", path = "../core/consensus/babe" } -babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../core/consensus/babe/primitives" } +aura = { package = "substrate-consensus-aura", path = "../core/consensus/aura" } +aura-primitives = { package = "substrate-consensus-aura-primitives", path = "../core/consensus/aura/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" } +runtime = { package = "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 5a59652c1b352c1f2dbf64cbe360d64b1ee8c714..c411dbeef5bcccf9e05d64ddee2405cb5237c678 100644 --- a/node-template/README.md +++ b/node-template/README.md @@ -10,7 +10,7 @@ Install Rust: curl https://sh.rustup.rs -sSf | sh ``` -Install required tools: +Initialize your Wasm Build environment: ```bash ./scripts/init.sh @@ -19,17 +19,23 @@ Install required tools: Build Wasm and native code: ```bash -cargo build +cargo build --release ``` ## Run ### Single node development chain -You can start a development chain with: +Purge any existing developer chain state: ```bash -cargo run -- --dev +./target/release/node-template purge-chain --dev +``` + +Start a development chain with: + +```bash +./target/release/node-template --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`. diff --git a/node-template/runtime/Cargo.toml b/node-template/runtime/Cargo.toml index 986feeb38c9efb7f2f5061490a304976abf8e5b2..ff2e3eb2b1676ad3642c854360c929245a1a999c 100644 --- a/node-template/runtime/Cargo.toml +++ b/node-template/runtime/Cargo.toml @@ -5,8 +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 } @@ -15,20 +15,22 @@ 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 } -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 } +aura = { package = "srml-aura", path = "../../srml/aura", default_features = false } +aura-primitives = { package = "substrate-consensus-aura-primitives", path = "../../core/consensus/aura/primitives", default_features = false } +grandpa = { package = "srml-grandpa", path = "../../srml/grandpa", 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 } +randomness-collective-flip = { package = "srml-randomness-collective-flip", path = "../../srml/randomness-collective-flip", 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 } +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment", default_features = false } sr-primitives = { path = "../../core/sr-primitives", default_features = false } client = { package = "substrate-client", path = "../../core/client", default_features = false } offchain-primitives = { package = "substrate-offchain-primitives", path = "../../core/offchain/primitives", default-features = false } [build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2" } +wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.4" } [features] default = ["std"] @@ -39,20 +41,21 @@ std = [ "runtime-io/std", "support/std", "balances/std", - "babe/std", - "babe-primitives/std", + "aura/std", + "aura-primitives/std", + "grandpa/std", "executive/std", "indices/std", - "grandpa/std", "primitives/std", "sr-primitives/std", + "randomness-collective-flip/std", "system/std", "timestamp/std", "sudo/std", + "transaction-payment/std", "version/std", "serde", "safe-mix/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..c5e798c6efa90a4fdb10e8ffc005afad7066d897 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.8"), // 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 6a73a47d366e915d87f9266765973257b2cab5b6..acc5143ffe5d2bdccbf5960c09416931f9890d37 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -14,15 +14,15 @@ use sr_primitives::{ ApplyResult, transaction_validity::TransactionValidity, generic, create_runtime_str, impl_opaque_keys, AnySignature }; -use sr_primitives::traits::{NumberFor, BlakeTwo256, Block as BlockT, DigestFor, StaticLookup, Verify, ConvertInto}; +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::{self, ScheduledChange}; use client::{ block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api}, runtime_api as client_api, impl_runtime_apis }; +use aura_primitives::sr25519::AuthorityId as AuraId; +use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight}; +use grandpa::fg_primitives; use version::RuntimeVersion; #[cfg(feature = "std")] use version::NativeVersion; @@ -33,7 +33,7 @@ pub use sr_primitives::BuildStorage; pub use timestamp::Call as TimestampCall; pub use balances::Call as BalancesCall; pub use sr_primitives::{Permill, Perbill}; -pub use support::{StorageValue, construct_runtime, parameter_types}; +pub use support::{StorageValue, construct_runtime, parameter_types, traits::Randomness}; /// An index to a block. pub type BlockNumber = u32; @@ -80,14 +80,12 @@ 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, } } } @@ -102,20 +100,6 @@ 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; @@ -166,29 +150,22 @@ impl system::Trait for Runtime { type Header = generic::Header; /// The ubiquitous event type. type Event = Event; - /// Update weight (to fee) multiplier per-block. - type WeightMultiplierUpdate = (); /// The ubiquitous origin type. type Origin = Origin; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount = BlockHashCount; - /// Maximum weight of each block. With a default weight system of 1byte == 1weight, 4mb is ok. + /// Maximum weight of each block. type MaximumBlockWeight = MaximumBlockWeight; /// Maximum size of all encoded transactions (in bytes) that are allowed in one block. type MaximumBlockLength = MaximumBlockLength; /// Portion of the block weight that is available to all normal transactions. type AvailableBlockRatio = AvailableBlockRatio; + /// Version of the runtime. type Version = Version; } -parameter_types! { - pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64; - pub const ExpectedBlockTime: u64 = MILLISECS_PER_BLOCK; -} - -impl babe::Trait for Runtime { - type EpochDuration = EpochDuration; - type ExpectedBlockTime = ExpectedBlockTime; +impl aura::Trait for Runtime { + type AuthorityId = AuraId; } impl grandpa::Trait for Runtime { @@ -208,13 +185,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 = Babe; + type OnTimestampSet = Aura; type MinimumPeriod = MinimumPeriod; } @@ -222,8 +199,6 @@ parameter_types! { pub const ExistentialDeposit: u128 = 500; pub const TransferFee: u128 = 0; pub const CreationFee: u128 = 0; - pub const TransactionBaseFee: u128 = 0; - pub const TransactionByteFee: u128 = 1; } impl balances::Trait for Runtime { @@ -235,16 +210,25 @@ impl balances::Trait for Runtime { type OnNewAccount = Indices; /// The ubiquitous event type. type Event = Event; - - type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; +} + +parameter_types! { + pub const TransactionBaseFee: Balance = 0; + pub const TransactionByteFee: Balance = 1; +} + +impl transaction_payment::Trait for Runtime { + type Currency = balances::Module; + type OnTransactionPayment = (); type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; type WeightToFee = ConvertInto; + type FeeMultiplierUpdate = (); } impl sudo::Trait for Runtime { @@ -265,13 +249,15 @@ construct_runtime!( { System: system::{Module, Call, Storage, Config, Event}, Timestamp: timestamp::{Module, Call, Storage, Inherent}, - Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, + Aura: aura::{Module, Config, Inherent(Timestamp)}, Grandpa: grandpa::{Module, Call, Storage, Config, Event}, Indices: indices::{default, Config}, - Balances: balances, + Balances: balances::{default, Error}, + TransactionPayment: transaction_payment::{Module, Storage}, Sudo: sudo, // Used for the module template in `./template.rs` TemplateModule: template::{Module, Call, Storage, Event}, + RandomnessCollectiveFlip: randomness_collective_flip::{Module, Call, Storage}, } ); @@ -292,7 +278,7 @@ pub type SignedExtra = ( system::CheckEra, system::CheckNonce, system::CheckWeight, - balances::TakeFees + transaction_payment::ChargeTransactionPayment ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; @@ -340,7 +326,7 @@ impl_runtime_apis! { } fn random_seed() -> ::Hash { - System::random_seed() + RandomnessCollectiveFlip::random_seed() } } @@ -356,47 +342,13 @@ impl_runtime_apis! { } } - impl fg_primitives::GrandpaApi for Runtime { - fn grandpa_pending_change(digest: &DigestFor) - -> Option>> - { - Grandpa::pending_change(digest) + impl aura_primitives::AuraApi for Runtime { + fn slot_duration() -> u64 { + Aura::slot_duration() } - - 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 { - // 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: PRIMARY_PROBABILITY, - } - } - - 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(), - secondary_slots: Babe::secondary_slots().0, - } + + fn authorities() -> Vec { + Aura::authorities() } } @@ -406,4 +358,10 @@ impl_runtime_apis! { opaque::SessionKeys::generate(seed) } } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> Vec<(GrandpaId, GrandpaWeight)> { + Grandpa::grandpa_authorities() + } + } } diff --git a/node-template/runtime/src/template.rs b/node-template/runtime/src/template.rs index 7f9d03fbb7c53099e1b817ab78df0a819af93bc5..db7bd24b0e419268610612ae03275164cec7a9ff 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. @@ -24,8 +24,8 @@ decl_storage! { trait Store for Module as TemplateModule { // Just a dummy storage item. // Here we are declaring a StorageValue, `Something` as a Option - // `get(something)` is the default getter which returns either the stored `u32` or `None` if nothing stored - Something get(something): Option; + // `get(fn something)` is the default getter which returns either the stored `u32` or `None` if nothing stored + Something get(fn something): Option; } } @@ -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 @@ -69,12 +69,11 @@ decl_event!( mod tests { use super::*; - use runtime_io::with_externalities; - use primitives::{H256, Blake2Hasher}; + use primitives::H256; use support::{impl_outer_origin, assert_ok, parameter_types}; - use sr_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; - use sr_primitives::weights::Weight; - use sr_primitives::Perbill; + use sr_primitives::{ + traits::{BlakeTwo256, IdentityLookup}, testing::Header, weights::Weight, Perbill, + }; impl_outer_origin! { pub enum Origin for Test {} @@ -101,7 +100,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -116,13 +114,13 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { system::GenesisConfig::default().build_storage::().unwrap().into() } #[test] fn it_works_for_default_value() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // Just a dummy test for the dummy funtion `do_something` // calling the `do_something` function with a value 42 assert_ok!(TemplateModule::do_something(Origin::signed(1), 42)); diff --git a/node-template/scripts/init.sh b/node-template/scripts/init.sh index cf5ecf97926fea7a5e8fd2a91df96853f90e8ee7..1405a41ef333e6af863080d83f854d3edb5fb4fa 100755 --- a/node-template/scripts/init.sh +++ b/node-template/scripts/init.sh @@ -10,7 +10,3 @@ if [ -z $CI_PROJECT_NAME ] ; then fi rustup target add wasm32-unknown-unknown --toolchain nightly - -# Install wasm-gc. It's useful for stripping slimming down wasm binaries. -command -v wasm-gc || \ - cargo +nightly install --git https://github.com/alexcrichton/wasm-gc --force diff --git a/node-template/src/chain_spec.rs b/node-template/src/chain_spec.rs index 9fdc6ee2ca6b3510eabc2ba89a7e4a8b2a7cfa18..b8f7fef35e86af2676f77fb9961031aff8435bbc 100644 --- a/node-template/src/chain_spec.rs +++ b/node-template/src/chain_spec.rs @@ -1,9 +1,9 @@ use primitives::{Pair, Public}; -use node_template_runtime::{ - AccountId, BabeConfig, BalancesConfig, GenesisConfig, GrandpaConfig, +use runtime::{ + AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, SudoConfig, IndicesConfig, SystemConfig, WASM_BINARY, }; -use babe_primitives::{AuthorityId as BabeId}; +use aura_primitives::sr25519::{AuthorityId as AuraId}; use grandpa_primitives::{AuthorityId as GrandpaId}; use substrate_service; @@ -31,13 +31,11 @@ pub fn get_from_seed(seed: &str) -> ::Pu .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) { +/// Helper function to generate an authority key for Aura +pub fn get_authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) { ( - get_from_seed::(&format!("{}//stash", seed)), - get_from_seed::(seed), - get_from_seed::(seed), - get_from_seed::(seed), + get_from_seed::(s), + get_from_seed::(s), ) } @@ -106,7 +104,7 @@ impl Alternative { } } -fn testnet_genesis(initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId)>, +fn testnet_genesis(initial_authorities: Vec<(AuraId, GrandpaId)>, root_key: AccountId, endowed_accounts: Vec, _enable_println: bool) -> GenesisConfig { @@ -125,11 +123,11 @@ fn testnet_genesis(initial_authorities: Vec<(AccountId, AccountId, GrandpaId, Ba sudo: Some(SudoConfig { key: root_key, }), - babe: Some(BabeConfig { - authorities: initial_authorities.iter().map(|x| (x.3.clone(), 1)).collect(), + aura: Some(AuraConfig { + authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(), }), grandpa: Some(GrandpaConfig { - authorities: initial_authorities.iter().map(|x| (x.2.clone(), 1)).collect(), + authorities: initial_authorities.iter().map(|x| (x.1.clone(), 1)).collect(), }), } } diff --git a/node-template/src/cli.rs b/node-template/src/cli.rs index 4d672491c18e658b69fa9114261f2ad4a1b38ec1..15c1a0486fb3f0575b92cc135c58c36616e9f8b5 100644 --- a/node-template/src/cli.rs +++ b/node-template/src/cli.rs @@ -4,9 +4,9 @@ use std::cell::RefCell; use tokio::runtime::Runtime; pub use substrate_cli::{VersionInfo, IntoExit, error}; use substrate_cli::{informant, parse_and_prepare, ParseAndPrepare, NoCustom}; -use substrate_service::{ServiceFactory, Roles as ServiceRoles}; +use substrate_service::{AbstractService, Roles as ServiceRoles, Configuration}; +use aura_primitives::sr25519::{AuthorityPair as AuraPair}; use crate::chain_spec; -use std::ops::Deref; use log::info; /// Parse command line arguments into service configuration. @@ -15,8 +15,10 @@ pub fn run(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 +29,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)?, exit ), _ => run_until_exit( runtime, - service::Factory::new_full(config).map_err(|e| format!("{:?}", e))?, + service::new_full(config)?, 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 +60,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 +103,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..1f286a2237548dfc84a9c9ccce7c9f78a3eb38d4 100644 --- a/node-template/src/main.rs +++ b/node-template/src/main.rs @@ -4,12 +4,13 @@ #![warn(unused_extern_crates)] mod chain_spec; +#[macro_use] mod service; mod cli; pub use substrate_cli::{VersionInfo, IntoExit, error}; -fn main() { +fn main() -> Result<(), cli::error::Error> { let version = VersionInfo { name: "Substrate Node", commit: env!("VERGEN_SHA_SHORT"), @@ -20,8 +21,5 @@ fn main() { support_url: "support.anonymous.an", }; - if let Err(e) = cli::run(::std::env::args(), cli::Exit, version) { - eprintln!("Fatal error: {}\n\n{:?}", e, e); - std::process::exit(1) - } + cli::run(std::env::args(), cli::Exit, version) } diff --git a/node-template/src/service.rs b/node-template/src/service.rs index 2baa0c76313734020cafef3bb91adc1a54d3dce8..203e311df9df9b2ffa30950630cf473ec38c240e 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -1,32 +1,24 @@ -#![warn(unused_extern_crates)] - //! Service and ServiceFactory implementation. Specialized wrapper over substrate service. use std::sync::Arc; use std::time::Duration; -use substrate_client::{self as client, LongestChain}; -use babe::{import_queue, start_babe, BabeImportQueue, Config}; -use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; +use substrate_client::LongestChain; use futures::prelude::*; -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 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::construct_simple_protocol; +use network::{construct_simple_protocol}; use substrate_executor::native_executor_instance; -use substrate_service::{ServiceFactory, construct_service_factory, TelemetryOnConnect}; pub use substrate_executor::NativeExecutor; +use aura_primitives::sr25519::{AuthorityPair as AuraPair}; +use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; // Our native executor instance. native_executor_instance!( pub Executor, - node_template_runtime::api::dispatch, - node_template_runtime::native_version, - WASM_BINARY + runtime::api::dispatch, + runtime::native_version, ); construct_simple_protocol! { @@ -34,235 +26,185 @@ construct_simple_protocol! { pub struct NodeProtocol where Block = Block { } } -type BabeBlockImportForService = babe::BabeBlockImport< - FullBackend, - FullExecutor, - ::Block, - grandpa::BlockImportForService, - ::RuntimeApi, - client::Client< - FullBackend, - FullExecutor, - ::Block, - ::RuntimeApi - >, ->; - -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: 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 = 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 = 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) => {{ + let mut import_setup = None; + let inherent_data_providers = inherents::InherentDataProviders::new(); + + let builder = substrate_service::ServiceBuilder::new_full::< + runtime::opaque::Block, 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::<_, _, _, runtime::RuntimeApi, _, _>( + client.clone(), &*client, select_chain )?; - let justification_import = block_import.clone(); - let (import_queue, babe_link, babe_block_import, pruning_task) = import_queue( - Config::get_or_compute(&*client)?, - block_import, - Some(Box::new(justification_import)), + + let import_queue = aura::import_queue::<_, _, AuraPair, _>( + aura::SlotDuration::get_or_compute(&*client)?, + Box::new(grandpa_block_import.clone()), + Some(Box::new(grandpa_block_import.clone())), None, - client.clone(), client, - config.custom.inherent_data_providers.clone(), - transaction_pool, + inherent_data_providers.clone(), + Some(transaction_pool), )?; - 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((grandpa_block_import, grandpa_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() - )?; + })?; - 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, - )?; +/// Builds a new service for a full client. +pub fn new_full(config: Configuration) + -> Result +{ + let is_authority = config.roles.is_authority(); + let force_authoring = config.force_authoring; + let name = config.name.clone(); + let disable_grandpa = config.disable_grandpa; + + let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config); + + let (block_import, grandpa_link) = + import_setup.take() + .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); + + let service = builder.with_network_protocol(|_| Ok(NodeProtocol::new()))? + .with_finality_proof_provider(|client, backend| + Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _) + )? + .build()?; + + 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 aura = aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _>( + aura::SlotDuration::get_or_compute(&*client)?, + client, + select_chain, + block_import, + proposer, + service.network(), + inherent_data_providers.clone(), + force_authoring, + service.keystore(), + )?; + + // the AURA authoring task is considered essential, i.e. if it + // fails we take down the service with it. + service.spawn_essential_task(aura); + } - Ok((import_queue, finality_proof_request_builder)) - }}, - SelectChain = LongestChain, Self::Block> - { |config: &FactoryFullConfiguration, client: Arc>| { - #[allow(deprecated)] - Ok(LongestChain::new(client.backend().clone())) - } + 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(grandpa::run_grandpa_observer( + grandpa_config, + grandpa_link, + service.network(), + service.on_exit(), + )?); + }, + (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()), + voting_rule: grandpa::VotingRulesBuilder::default().build(), + }; + + // 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(Some(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _)) - }}, - RpcExtensions = (), } + + 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 import_queue = aura::import_queue::<_, _, AuraPair, ()>( + aura::SlotDuration::get_or_compute(&*client)?, + Box::new(grandpa_block_import), + None, + Some(Box::new(finality_proof_import)), + client, + inherent_data_providers.clone(), + None, + )?; + + 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 7b4ebb0c5f32d36dcd1256f07e3f79ff1a93b8ef..5fa92360d62cf21b4e2a8178cc05357cc4db37d8 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -7,11 +7,11 @@ build = "build.rs" edition = "2018" [dependencies] -log = "0.4" -tokio = "0.1.7" -futures = "0.1" -exit-future = "0.1" -jsonrpc-core = "13.0.0" +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" } @@ -21,10 +21,11 @@ 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" } @@ -34,28 +35,33 @@ 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.3.3" 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" } +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment" } support = { package = "srml-support", path = "../../srml/support", default-features = false } im_online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false } -authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", 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.3.3" diff --git a/node/cli/res/flaming-fir.json b/node/cli/res/flaming-fir.json index e135901ac1ae95192f43c99612336f80ca3c6925..5cd11eb97fa008d124b4d51322520610538d6d8c 100644 --- a/node/cli/res/flaming-fir.json +++ b/node/cli/res/flaming-fir.json @@ -23,86 +23,87 @@ "genesis": { "raw": [ { - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797346c8960f8387b17441ee2be48a0896e48d3580e922c6e1cd8f53a621370c1e49": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", - "0x579ab55d37b1220812be3c3df29d4858": "0x00000000", - "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b657973711590f60a214f6f06502eb29dd14f55aa04e72e2fa12c098ba4fa5a00c57fa9": "0x7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973dc4036f96ca26a30da6d8637ca1431896c1069bf172c419e98dc08109e7b23b5": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579730a299be621974fd19374a88f1dddd8442b21db25d2c923907dda6af815b657fe": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0x3a636f6465": "0x0061736d010000000194022460027f7f0060017f0060027f7f017f60037f7f7f0060037f7f7f017f60057f7f7f7f7f0060047f7f7f7f0060017f017e60057f7f7f7f7f017f60067f7f7f7f7f7f0060047f7f7f7f017f6000017f60077f7f7f7f7f7f7f017f60017f017f60067f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60000060077f7f7e7e7f7f7f0060087f7f7f7f7f7e7e7f0060057f7f7f7e7e0060047f7f7e7e0060077f7f7f7e7e7f7f0060037f7e7e0060057f7f7e7e7f0060077f7e7e7f7f7f7f0060067f7f7e7e7f7f0060077f7e7e7e7e7e7e0060047f7e7e7e0060037e7f7f017f60027f7f017e60047f7f7f7f017e60067f7f7f7e7e7f0060037f7e7f0060047f7e7e7f0060057f7e7e7e7e0060067f7e7e7e7e7f00029b082703656e760e6578745f626c616b65325f323536000303656e761f6578745f6765745f616c6c6f63617465645f6368696c645f73746f72616765000803656e76176578745f636c6561725f6368696c645f73746f72616765000603656e760c6578745f74776f785f313238000303656e760f6578745f7365745f73746f72616765000603656e76146578745f6765745f73746f726167655f696e746f000803656e76116578745f636c6561725f73746f72616765000003656e76166578745f6b696c6c5f6368696c645f73746f72616765000003656e76196578745f6765745f616c6c6f63617465645f73746f72616765000403656e760e6578745f7072696e745f75746638000003656e76166578745f6368696c645f73746f726167655f726f6f74000403656e76156578745f7365745f6368696c645f73746f72616765000903656e76126578745f737232353531395f766572696679000a03656e760d6578745f7072696e745f686578000003656e76106578745f69735f76616c696461746f72000b03656e76156578745f6c6f63616c5f73746f726167655f676574000a03656e76216578745f6c6f63616c5f73746f726167655f636f6d706172655f616e645f736574000c03656e76176578745f737232353531395f7075626c69635f6b657973000203656e76116578745f6e6574776f726b5f7374617465000d03656e76106578745f737232353531395f7369676e000803656e76166578745f7375626d69745f7472616e73616374696f6e000203656e76156578745f6c6f63616c5f73746f726167655f736574000503656e76146578745f656432353531395f67656e6572617465000603656e76146578745f737232353531395f67656e6572617465000603656e76106578745f636c6561725f707265666978000003656e76166578745f73616e64626f785f6d656d6f72795f6e6577000203656e761b6578745f73616e64626f785f6d656d6f72795f74656172646f776e000103656e76176578745f73616e64626f785f696e7374616e7469617465000e03656e76126578745f73616e64626f785f696e766f6b65000f03656e761d6578745f73616e64626f785f696e7374616e63655f74656172646f776e000103656e76236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f74000603656e76106578745f73746f726167655f726f6f74000103656e76186578745f73746f726167655f6368616e6765735f726f6f74000403656e76126578745f656432353531395f766572696679000a03656e76166578745f73616e64626f785f6d656d6f72795f676574000a03656e76166578745f73616e64626f785f6d656d6f72795f736574000a03656e760b6578745f74776f785f3634000303656e760a6578745f6d616c6c6f63000d03656e76086578745f66726565000103da04d80400000d040100100101000010000d000000030001000000000000000003000000000000000303110202120309060100131401011506000000050000020600000000020200000214031403010316000100000000170000030010000300030018000101010100160114030019141416010000010003000203020101000100001a1b01010100000000000003000204021c0e0000000000000a030300010100000003010000000001010000010000000000000000030205030000060000000000030003050302030000010000030503030600060000000001000003000000000000010101010101010101010101010100030001000300030106060303030310030101001d1d000100000610011d1d0300001d1d001d001d1d031d03031d1d1d1d1d1d000000001d1d030101010001010001000300100001000003010100100606060606060606060606060606060606060606060606061e0000000d0d00000005010000010104000100000000000101010001010100001000000000010100030001010100000100000000000000000010100600000002000d030001030303010100000100000000000000000000000000000000001a1f010100000101000000000000010000140000010300050001010000000001000000000000000a0003030503200000020000030305000300020400030000020006020302020001000306060303020505030303030602040101020204020202080302030203030000020302020202010202020200010202020100010d01040d040202070a0602020d02020202020601010402020402020202020202040404042121222222230407017001de01de0105030100120619037f01418080c0000b7f0041f099c6000b7f0041f099c6000b07dd0416066d656d6f72790200195f5f696e6469726563745f66756e6374696f6e5f7461626c6501000a5f5f646174615f656e6403010b5f5f686561705f6261736503020c436f72655f76657273696f6e00a80212436f72655f657865637574655f626c6f636b00a90215436f72655f696e697469616c697a655f626c6f636b00b102114d657461646174615f6d6574616461746100b2021c426c6f636b4275696c6465725f6170706c795f65787472696e73696300b6021b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b00b70220426c6f636b4275696c6465725f696e686572656e745f65787472696e7369637300b9021c426c6f636b4275696c6465725f636865636b5f696e686572656e747300bb0218426c6f636b4275696c6465725f72616e646f6d5f7365656400bc022b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e00be02214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b657200c102214772616e6470614170695f6772616e6470615f70656e64696e675f6368616e676500c202204772616e6470614170695f6772616e6470615f666f726365645f6368616e676500c3021e4772616e6470614170695f6772616e6470615f617574686f72697469657300c40214426162654170695f737461727475705f6461746100c5020d426162654170695f65706f636800c60218436f6e73656e7375734170695f617574686f72697469657300cb022153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b65797300cc0209bb03010041010bdd019804e302e402e502e602e702e802e902ea02eb02ec02ed02ee02ef02f002f102f202f302f402f502f602f702f802f902fa02fb02e604da0168696c9e0189049b049d049e049204c204a704af04b404e304bb04bd04d004d104cf04df04e004d002e801e901eb01ea01e701ec0159f201f301f4014ef10155d4028b01f703d601cc03cd03e203a101a203ce01a401a301ad01ac01aa01db02b201b104b401c401c301cf01f403d701d501d401d301d201d101d103e404e504a703a6038602aa03a0019f01a201930392039403e002df028c0387028a01890188028d01e003df038902e703d302d2028a02d502f303f2038b02f803970396038c029803cd01cc018d02d001890388038e02c101c201cf02ce028f02a801a7019002a901c403c3039102c703a103a0039202a502a6029302a702f204d102d602dd02dc02de02f4049503a903a803c603c503d303d203d003cf03ce03cb03ca03c903c803e603e503e403e303e103e803ed03d803eb03ee03f603f503fc03fb03fa03f903b204b604c604b304c404b804c504c704cb04c904ca04cc04cd04ce04d904da04db04dc04e904ea04eb04ec04ed04ee04ef04f104f004f3040afec83ad8049a1002187f017e230041f0006b2202240002400240024020012802042203200128020022046b41e100490d0003402001200441206a3602002001280208220341186a280200210520032802102106200241d0006a41186a22034200370300200241d0006a41106a22074200370300200241d0006a41086a220842003703002002420037035020044120200241d0006a1000200241106a41186a22092003290300370300200241106a41106a220a2007290300370300200241106a41086a220b2008290300370300200220022903503703102002410036025020062005200241106a4120200241d0006a100121060240024020022802502205417f470d002002200c36020c2002200d3602082002200e3602040c010b2001280208220f2802182110200f280210210f2003420037030020074200370300200842003703002002420037035020044120200241d0006a1000200241306a41186a2003290300370300200241306a41106a2007290300370300200241306a41086a200829030037030020022002290350370330200f2010200241306a412010022002200536020c20022005360208200220063602042006210e2005210d2005210c2004450d00200241046a21010c030b20012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037035020044120200241d0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903503703102002410036025020052006200241106a4120200241d0006a100121060240024020022802502205417f470d002002201136020c20022012360208200220133602040c010b2001280208220f2802182110200f280210210f2003420037030020074200370300200842003703002002420037035020044120200241d0006a1000200241306a41186a2003290300370300200241306a41106a2007290300370300200241306a41086a200829030037030020022002290350370330200f2010200241306a412010022002200536020c20022005360208200220063602042006211320052112200521112004450d00200241046a21010c030b20012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037035020044120200241d0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903503703102002410036025020052006200241106a4120200241d0006a100121060240024020022802502205417f470d002002201436020c20022015360208200220163602040c010b2001280208220f2802182110200f280210210f2003420037030020074200370300200842003703002002420037035020044120200241d0006a1000200241306a41186a2003290300370300200241306a41106a2007290300370300200241306a41086a200829030037030020022002290350370330200f2010200241306a412010022002200536020c20022005360208200220063602042006211620052115200521142004450d00200241046a21010c030b20012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037035020044120200241d0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903503703102002410036025020052006200241106a4120200241d0006a1001210a0240024020022802502209417f470d002002201736020c20022018360208200220193602040c010b2001280208220b2802182105200b280210210b2003420037030020074200370300200842003703002002420037035020044120200241d0006a1000200241306a41186a2003290300370300200241306a41106a2007290300370300200241306a41086a200829030037030020022002290350370330200b2005200241306a412010022002200936020c200220093602082002200a360204200a211920092118200921172004450d00200241046a21010c030b20012802042203200128020022046b41e0004b0d000b0b024020042003460d0003402001200441206a3602002001280208220341186a280200210a20032802102103200241d0006a41186a22074200370300200241d0006a41106a22084200370300200241d0006a41086a220942003703002002420037035020044120200241d0006a1000200241106a41186a2007290300370300200241106a41106a2008290300370300200241106a41086a200929030037030020022002290350370310200241003602502003200a200241106a4120200241d0006a1001210a0240024020022802502203417f470d002002200b36020c20022005360208200220063602040c010b2001280208220b2802182105200b280210210b2007420037030020084200370300200942003703002002420037035020044120200241d0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a200929030037030020022002290350370330200b2005200241306a412010022002200336020c200220033602082002200a360204200a2106200321052003210b2004450d00200241046a21010c030b200128020022042001280204470d000b0b200041003602000c010b200241d0006a41086a200141086a280200220336020020022001290200221a370350200020043602002000201a3702042000410c6a20033602000b200241f0006a24000b830202077f017e0240024002400240200041046a2802002202200041086a28020022036b2001410c6a2802002204200141086a28020022056b220641b0016d2207490d00200028020021020c010b200320076a22082003490d0220024101742203200820082003491b2203ad42b0017e2209422088a70d022009a722084100480d020240024020020d002008102921020c010b2000280200200241b0016c2008102a21020b2002450d0120002002360200200041046a2003360200200041086a28020021030b2002200341b0016c6a2005200610f6041a200141086a2004360200200041086a2200200028020020076a3602002001102b0f0b20084108102c000b102d000b0700200010d5040b0b0020002001200210d7040b950201057f230041e0026b22012400024020002802082202200028020c460d00200141b0016a4101722103200141d8016a210403402000200241b0016a36020820022d00002105200141b0016a200241016a41af0110f6041a20054103460d01200141016a200141b0016a41af0110f6041a200120053a00b0012003200141016a41af0110f6041a02400240200541014b0d000240024020050e020001000b024020012802b801450d0020012802b401102e0b20012d00c0014105490d0220012802e801450d0220012802e401102e0c020b2004102f0c010b200128029802450d00200128029402102e0b20002802082202200028020c470d000b0b02402000280204450d002000280200102e0b200141e0026a24000b0e0041f8e6c500412210d30400000b0a0041bce8c5001058000b0700200010d6040b9a0b01057f0240024020002d0000220141114b0d0002400240024002400240024002400240024002400240024020010e12000d0d010d0d020304050607080d090d0a0b000b0240200041086a280200220141054b0d0002400240024020010e06101000100102100b200041106a280200450d0f2000410c6a280200102e0f0b200041106a280200450d0e2000410c6a280200102e0f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141186a2101200241686a22020d000b0b200041106a280200450d0d200028020c102e0f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d002001280200102e0b2001410c6a2101200241746a22020d000b0b200041106a280200450d0c200028020c102e0f0b02402000410c6a2802002201450d00200041046a2802002203200141f0006c6a2104034002402003410c6a2802002202450d0020032802042101200241246c210203400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012002415c6a22020d000b0b200341f0006a21010240200341086a280200450d002003280204102e0b2001210320012004470d000b0b200041086a280200450d0b2000280204102e0f0b0240200041086a2d00002201410d4b0d0020014106470d0b200041106a280200450d0b2000410c6a280200102e0f0b200041106a280200450d0a2000410c6a280200102e0f0b200041086a280200450d09200041046a280200102e0f0b200041086a2d0000417f6a220141074b0d08024002400240024020010e08000c0c0c0c010203000b2000410c6a2201280200102f2001280200102e0f0b2000410c6a2201280200102f2001280200102e0f0b2000410c6a2201280200102f2001280200102e0f0b2000410c6a2201280200102f2001280200102e0f0b200041046a2d0000417f6a220141024b0d0702400240024020010e03000102000b2000410c6a280200450d09200041086a280200102e0f0b200041086a2201280200102f2001280200102e0f0b2000410c6a2201280200102f2001280200102e0f0b200041046a2d0000417f6a220141024b0d0602400240024020010e03000102000b2000410c6a280200450d08200041086a280200102e0f0b200041086a2201280200102f2001280200102e0f0b2000410c6a2201280200102f2001280200102e0f0b200041086a280200417f6a220141014b0d050240024020010e020001000b200041106a280200450d062000410c6a280200102e0f0b200041106a280200450d052000410c6a280200102e0f0b200041046a2d00004104490d042000410c6a280200450d04200041086a280200102e0f0b200041086a280200450d03200041046a280200102e0f0b200041086a2d0000417e6a220141024b0d0202400240024020010e03000102000b200041106a280200450d042000410c6a280200102e0c040b200041346a280200450d03200041306a280200102e0f0b200041306a280200450d022000412c6a280200102e0f0b200041046a2802004101470d01200041086a2201280200102f2001280200102e0f0b02402000410c6a280200450d00200041086a280200102e0b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d002001280200102e0b2001410c6a2101200241746a22020d000b0b200041186a280200450d002000280214102e0f0b0baf04010a7f230041d0006b220224002002200110310240024002400240024020022802000d00200128020422034160712204417f4c0d022002280204210502400240200341057622060d00410121070c010b200410292207450d040b02402005450d00410021080340200241003a00482008220941016a21082001280204417f6a21034100210402400240024003402003417f460d01200241286a20046a2001280200220a2d00003a0000200120033602042001200a41016a3602002002200441016a220a3a00482003417f6a2103200a2104200a4120470d000b200241086a41186a2204200241286a41186a290300370300200241086a41106a220a200241286a41106a290300370300200241086a41086a220b200241286a41086a2903003703002002200229032837030820062009470d02024020094101742203200820082003491b220641ffffff3f712006470d002006410574220341004e0d020b102d000b0240200441ff0171450d00200241003a00480b200041003602002006450d052007102e0c050b0240024020090d002003102921070c010b200720094105742003102a21070b2007450d070b200720094105746a22032002290308370000200341186a2004290300370000200341106a200a290300370000200341086a200b29030037000020082005470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241d0006a24000f0b1032000b20044101102c000b20034101102c000bcf0201067f0240024020012802042202450d00200128020022032d0000210420012002417f6a2205360204410121062001200341016a3602000240200441037122074103460d0002400240024020070e03000102000b20044102762107410021060c040b41012106024020050d000c040b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d03200141fcff03714102762107410021060c030b20054103490d01200341036a2d0000210620032f0001210720012002417c6a3602042001200341046a3602002007200641107472410874200472220141027621072001418080044921060c020b0240200441034d0d000c020b20054104490d012003280001210720012002417b6a3602042001200341056a36020020074180808080044921060c010b410121060b20002007360204200020063602000b0500102d000b960301097f230041106b2202240002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002006450d0020042d0001210720012003417e6a22063602042001200441026a3602002006450d0020042d0002210820012003417d6a22063602042001200441036a3602002006450d0020042d0003210620012003417c6a3602042001200441046a360200200241086a2001103120022802080d022001280204200228020c2204490d022004417f4c0d0302400240024020040d004101210341010d010c050b200410342203450d0120012802042004490d0320032001280200200410f60421092001280204220a2004490d062001200a20046b3602042001200128020020046a3602002009450d040b20002004360208200020033602042000410c6a2004360200200020074108742005722008411074722006411874723602000c060b20044101102c000b200041003602040c040b2003102e0b200041003602040c020b1032000b2004200a1035000b200241106a24000b0700200010d8040b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420237020c200241b4efc500360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41c4efc500106a000b970201057f0240024002400240200041086a28020022022001490d0020012002200220014b1b21030c010b02400240200041046a280200220320026b200120026b2204490d0020002802002105200221030c010b200220046a22052002490d0320034101742206200520052006491b22064100480d030240024020030d002006102921050c010b200028020020032006102a21050b2005450d0220002005360200200041046a2006360200200041086a28020021030b200520036a21060240024020044102490d00200641002002417f73220220016a10f5041a2005200320016a20026a22036a21060c010b2004450d010b200641003a0000200341016a21030b200041086a20033602000f0b20064101102c000b102d000b9203010a7f200041086a220228020021034100210420024100360200024002402003450d004100210541002106410021044100210702400340024002402004450d00200741057421080340200720034f0d062001200028020022096b2008460d02200920086a220a2001412010f804450d020240200620076a220b20034f0d00200920056a20086a2209200a290000370000200941186a200a41186a290000370000200941106a200a41106a290000370000200941086a200a41086a290000370000200841206a2108200741016a22072003490d010c050b0b419481c000200b20031038000b200028020020074105746a21080340200720034f0d0520012008460d0120082001412010f804450d01200841206a2108200741016a22072003490d000b410021040c030b200541606a21052006417f6a2106200441016a2104200741016a22072003490d000b0b2004450d00200320074d0d00200028020020074105746a220820044105746b2008200320076b41057410f7041a0b2002200320046b3602000f0b41b880c000200720031038000b6c01017f230041306b2203240020032002360204200320013602002003411c6a41023602002003412c6a41013602002003420237020c200341b8ecc500360208200341013602242003200341206a360218200320033602282003200341046a360220200341086a2000106a000ba30a03027f017e1b7f230041f0006b22022400024020012802082203ad42f0007e2204422088a70d002004a72205417f4c0d002001280200210602400240024020050d00410421070c010b200510292207450d010b02400240024020030d00410021080c010b2006200341f0006c6a2109410021082007210a0340200241c0006a41086a220b200641186a290000370300200241c0006a41106a220c200641206a290000370300200241c0006a41186a220d200641286a290000370300200241206a41086a220e200641386a29000037030020062900102104200241206a41106a220f200641c0006a290000370300200241206a41186a2210200641c8006a290000370300200241186a2211200641e8006a290000370300200241106a2212200641e0006a290000370300200241086a2213200641d8006a290000370300200220043703402002200629003037032020022006290050370300200628020c2214ad42247e2204422088a70d042004a72201417f4c0d0420062802002115200628020421160240024020010d00410421170c010b200110292217450d030b0240024020140d00410021180c010b201441246c2119410021054100211803400240024002400240024002400240201620056a22012d00000e050001020304000b2002200141146a2900003703602002200141196a290000370065200141056a2f0000200141076a2d000041107472211a200141106a280000211b2001410c6a280000211c200141086a280000211d200141016a280000211e4100211f0c050b200141106a280200221c417f4c0d0b200141016a280000211e4101211f201c450d03200141086a28020021010240201c1029221d450d00201d2001201c10f6041a201c211b0c050b201c4101102c000b200141106a280200221c417f4c0d0a200141016a280000211e4102211f201c450d02200141086a28020021010240201c1029221d450d00201d2001201c10f6041a201c211b0c040b201c4101102c000b200141106a280200221c417f4c0d09200141016a280000211e4103211f201c450d01200141086a28020021010240201c1029221d450d00201d2001201c10f6041a201c211b0c030b201c4101102c000b2001410c6a280200221d417f4c0d08024002400240201d0d00410121010c010b200141046a280200211c201d10292201450d012001201c201d10f6041a0b2001410876211a2001411874211e4104211f201d211c0c020b201d4101102c000b4100211c4101211d4100211b0b201720056a2201201f3a0000200141076a201a4110763a0000200141056a201a3b0000200141106a201b3600002001410c6a201c360000200141086a201d360000200141016a201e360000200141146a20022903603702002001411c6a200241e0006a41086a290300370200201841016a21182019200541246a2205470d000b0b200a2017360204200a410c6a2018360200200a41086a2014360200200a2002290340370210200a41186a200b290300370200200a2015360200200a2002290320370230200a41206a200c290300370200200a41286a200d290300370200200a41386a200e290300370200200a41c0006a200f290300370200200a41c8006a2010290300370200200a41e8006a2011290300370200200a41e0006a2012290300370200200a41d8006a2013290300370200200a2002290300370250200841016a2108200a41f0006a210a200641f0006a22062009470d000b0b200020083602082000200336020420002007360200200241f0006a24000f0b20014104102c000b20054104102c000b1032000b900201077f024020002802082201200028020c460d0003402000200141306a36020820012d00284102460d01200141246a2802002102200141206a2802002103200141146a2802002104200128021c2105200128021021060240200141186a2802002201450d002001410c6c21072006210103400240200141046a280200450d002001280200102e0b2001410c6a2101200741746a22070d000b0b02402004450d002006102e0b02402002450d002002410c6c21072005210103400240200141046a280200450d002001280200102e0b2001410c6a2101200741746a22070d000b0b02402003450d002005102e0b20002802082201200028020c470d000b0b02402000280204450d002000280200102e0b0be60403087f017e017f230041f0016b22022400200241086a2001103102400240024002400240024020022802080d00200128020441f0006e220341f0006c2204417f4c0d02200228020c21050240024020040d00410421060c010b200410292206450d040b024002402005450d00410021074100210841002109034020024180016a2001103c200228028401450d02200941016a2104200241106a20024180016a41f00010f6041a024020092003470d002007200420042007491b2203ad42f0007e220a422088a70d09200aa7220b4100480d090240024020090d00200b102921060c010b20062008200b102a21060b2006450d080b200620086a200241106a41f00010f6041a200741026a2107200841f0006a21082004210920052004470d000b0b2000200336020420002006360200200041086a20053602000c020b2000410036020002402009450d00200620086a210120062107034002402007410c6a2802002209450d0020072802042104200941246c210903400240024020042d0000220841034b0d0002400240024020080e0404000102040b2004410c6a280200450d03200441086a280200102e0c030b2004410c6a280200450d02200441086a280200102e0c020b2004410c6a280200450d01200441086a280200102e0c010b200441086a280200450d00200441046a280200102e0b200441246a21042009415c6a22090d000b0b200741f0006a21040240200741086a280200450d002007280204102e0b2004210720012004470d000b0b2003450d012006102e0c010b200041003602000b200241f0016a24000f0b1032000b20044104102c000b200b4104102c000b102d000b9f0a03077f037e057f230041d0026b2202240041002103200241003a00c8022001280204417f6a210402400240024003402004417f460d01200241a8026a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c8022004417f6a21042005210320054120470d000b200241e8006a41086a200241a8026a41086a290300370300200241e8006a41106a200241a8026a41106a290300370300200241e8006a41186a200241a8026a41186a290300370300200220022903a8023703682002200110312002280200450d01200041003602040c020b0240200341ff0171450d00200241003a00c8020b200041003602040c010b2002280204210641002104200241003a00c80220012802042107417f21030240034020072004460d01200241a8026a20046a200128020022082d00003a00002001200720036a3602042001200841016a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241a8016a41086a200241a8026a41086a2903002209370300200241a8016a41106a200241a8026a41106a290300220a370300200241a8016a41186a200241a8026a41186a290300220b37030020024188016a41086a200937030020024188016a41106a200a37030020024188016a41186a200b370300200220022903a80222093703a801200220093703880141002104200241003a00c802200720056b210c200720036a210303400240200c2004470d000240200441ff0171450d00200241003a00c8020b200041003602040c030b200241a8026a20046a200820046a220541016a2d00003a0000200120033602042001200541026a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241e8016a41086a200241a8026a41086a2903002209370300200241e8016a41106a200241a8026a41106a290300220a370300200241e8016a41186a200241a8026a41186a290300220b370300200241c8016a41086a22042009370300200241c8016a41106a2203200a370300200241c8016a41186a2205200b370300200220022903a80222093703e801200220093703c801200241a8026a2001103f024020022802a8022201450d00200241c8006a41086a2208200241e8006a41086a290300370300200241c8006a41106a2207200241e8006a41106a290300370300200241c8006a41186a220c200241e8006a41186a290300370300200241286a41086a220d20024188016a41086a290300370300200241286a41106a220e20024188016a41106a290300370300200241286a41186a220f20024188016a41186a29030037030020022002290368370348200220022903880137032820022902ac022109200241086a41186a22102005290300370300200241086a41106a22052003290300370300200241086a41086a22032004290300370300200220022903c801370308200020093702082000200136020420002006360200200041106a2002290348370200200041186a2008290300370200200041206a2007290300370200200041286a200c290300370200200041306a2002290328370200200041386a200d290300370200200041c0006a200e290300370200200041c8006a200f290300370200200041e8006a2010290300370200200041e0006a2005290300370200200041d8006a2003290300370200200041d0006a20022903083702000c020b200041003602040c010b0240200441ff0171450d00200241003a00c8020b200041003602040b200241d0026a24000bfb1002147f037e230041c0026b22022400200241086a200110310240024020022802080d000240200128020441c4006e220341c4006c2204417f4c0d00200228020c210502400240024020040d00410421060c010b200410292206450d010b024002402005450d0020024198026a410772210741002108034002400240024002400240024020012802042209450d002001280200220a2d0000210420012009417f6a220b3602042001200a41016a360200200441014b0d000240024020040e020001000b200b41034d0d01200a280001210c20012009417b6a3602042001200a41056a360200200241d4016a41026a200241d8016a41026a2d00003a0000200241b8016a41086a200241f8016a41086a290200370300200241b8016a41106a200241f8016a41106a290200370300200241b8016a41186a200241f8016a41186a2d00003a000020024198016a41086a20024198026a41086a29010037030020024198016a41106a20024198026a41106a29010037030020024198016a41186a20024198026a41186a290100370300200220022f00d8013b01d401200220022902f8013703b801200220022901980237039801200220022f01f4013b0196014100210d0c030b4100210e200241003a00b8022009417e6a210d03400240200b200e2204470d000240200441ff0171450d00200241003a00b8020b4102210d0c040b20024198026a20046a200a20046a220e41016a2d00003a00002001200d3602042001200e41026a3602002002200441016a220e3a00b802200d417f6a210d200e4120470d000b200241f4016a41026a220f20022d009a023a0000200241d8016a41086a2210200741086a290000370300200241d8016a41106a2211200741106a290000370300200241d8016a41186a2212200741186a2d00003a0000200220022f0198023b01f401200220072900003703d801200b200e460d01200228009b022113200a200e6a220a41016a2d0000210b2001200d3602042001200a41026a360200200b41014b0d014100211402400240200b0e020100010b4100210d200241003a00b802200e20096b41026a210b200920046b417c6a210403400240200b200d6a0d00200d41ff0171450d04200241003a00b8020c040b20024198026a200d6a200a200d6a220e41026a2d00003a0000200120043602042001200e41036a3602002002200d41016a220e3a00b8022004417f6a2104200e210d200e4120470d000b200241f8016a41186a20024198026a41186a290300370300200241f8016a41106a20024198026a41106a290300370300200241f8016a41086a20024198026a41086a29030037030020022002290398023703f801410121140b20024198016a41186a200241f8016a41186a29030037030020024198016a41106a200241f8016a41106a29030037030020024198016a41086a200241f8016a41086a290300370300200241d4016a41026a200f2d00003a0000200241b8016a41086a2010290300370300200241b8016a41106a2011290300370300200241b8016a41186a20122d00003a0000200220022903f80137039801200220022f01f4013b01d401200220022903d8013703b8014101210d201421152013210c0c020b20024192016a41026a200241d4016a41026a2d00003a0000200241f8006a41086a200241b8016a41086a290300370300200241f8006a41106a200241b8016a41106a290300370300200241f8006a41186a200241b8016a41186a2d00003a0000200241d8006a41086a20024198016a41086a290300370300200241d8006a41106a20024198016a41106a290300370300200241d8006a41186a20024198016a41186a290300370300200220022f01d4013b019201200220022903b8013703782002200229039801370358200220022f0196013b01560c020b4102210d0b20024192016a41026a2204200241d4016a41026a2d00003a0000200241f8006a41086a220a200241b8016a41086a290300370300200241f8006a41106a220b200241b8016a41106a290300370300200241f8006a41186a2209200241b8016a41186a2d00003a0000200241d8006a41086a220f20024198016a41086a290300370300200241d8006a41106a221020024198016a41106a290300370300200241d8006a41186a221120024198016a41186a290300370300200220022f01d4013b019201200220022903b8013703782002200229039801370358200220022f0196013b0156200d4102460d00200841016a210e200241d2006a41026a221220042d00003a0000200241386a41086a2213200a290300370300200241386a41106a220a200b290300370300200241386a41186a220b20092d00003a0000200241186a41086a2209200f290300370300200241186a41106a220f2010290300370300200241186a41186a22102011290300370300200220022f0192013b01522002200229037837033820022002290358370318200220022f01563b011620032008470d02024020084101742204200e200e2004491b2203ad42c4007e2216422088a70d002016a7220441004e0d020b102d000b200041003602002003450d082006102e0c080b0240024020080d002004102921060c010b2006200841c4006c2004102a21060b2006450d030b2006200841c4006c6a2204200d3a00002004200c360004200441036a20122d00003a0000200420022f01523b0001200b2d0000210d200a29030021162013290300211720022903382118200420153a002120042018370008200441106a2017370000200441186a2016370000200441206a200d3a00002004413a6a2010290300370000200441326a200f2903003700002004412a6a200929030037000020042002290318370022200420022f01163b0042200e2108200e2005470d000b0b2000200336020420002006360200200041086a20053602000c040b20044104102c000b20044104102c000b1032000b200041003602000b200241c0026a24000bb906020c7f047e230041b0016b2202240020022001103102400240024002400240024020022802000d00200128020441286e220341286c2204417f4c0d02200228020421050240024020040d00410821060c010b200410292206450d040b02402005450d00410021070340200241003a00a8012007220841016a210720012802042109417f210a4100210402400240024002400240034020092004460d0120024188016a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a00a801200a417f6a210a200c2104200c4120470d000b200241e8006a41186a220420024188016a41186a290300370300200241e8006a41106a220a20024188016a41106a290300370300200241e8006a41086a220d20024188016a41086a29030037030020022002290388013703682009200c6b220c41074d0d01200b290001210e2001200b41096a3602002001200c41786a360204200241286a41086a200d290300220f370300200241286a41106a200a2903002210370300200241286a41186a20042903002211370300200241086a41086a220a200f370300200241086a41106a220c2010370300200241086a41186a2209201137030020022002290368220f3703282002200f37030820032008470d0420084101742204200720072004491b2203ad42287e220f422088a70d0c200fa722044100480d0c20080d022004102921060c030b200441ff0171450d00200241003a00a8010b200241286a41186a200241c8006a41186a290300370300200241286a41106a200241c8006a41106a290300370300200241286a41086a200241c8006a41086a29030037030020022002290348370328200041003602002003450d062006102e0c060b2006200841286c2004102a21060b2006450d070b2006200841286c6a22042002290308370300200a290300210f200c2903002110200929030021112004200e370320200441186a2011370300200441106a2010370300200441086a200f37030020072005470d000b0b2000200336020420002006360200200041086a20053602000c010b200041003602000b200241b0016a24000f0b1032000b20044108102c000b20044108102c000b102d000b990a02137f017e230041e0006b22022400200241086a200110310240024020022802080d000240200128020441246e220341246c2204417f4c0d00200228020c210502400240024020040d00410421060c010b200410292206450d010b02400240024020050d00410021040c010b2002412d6a2107200241cb006a220841056a21094100210a4100210b0340024002402001280204220c450d002001280200220d2d000021042001200c417f6a220e3602042001200d41016a360200200441064b0d00024002400240024002400240024020040e0700070107030402000b20022001103120022802000d0620012802042002280204220c490d06200c417f4c0d0c024002400240200c0d004101210441010d010c090b200c10342204450d012001280204200c490d0620042001280200200c10f604210f2001280204220d200c490d072001200d200c6b36020420012001280200200c6a360200200f450d080b200241206a41086a200241386a41086a290200370300200220022902383703202004410876210f4104210d200c210e201041ffffff0771200441187472221021110c080b200c4101102c000b41002104200241003a0058200c417e6a210c03400240200e2004470d00200441ff0171450d07200241003a00580c070b200241386a20046a200d20046a220f41016a2d00003a00002001200c3602042001200f41026a3602002002200441016a220f3a0058200c417f6a210c200f2104200f4120470d000b2002200829000037032020022009290000370025200228004721122002280043210e200228003f210c2002280238211120022f013c210420022d003e210f200741026a200241356a41026a2d00003a0000200720022f00353b00002004200f41107472210f4100210d0c060b200241386a20011033200228023c220c450d04200228024421122002280240210e200228023821114101210d0c050b200241386a20011033200228023c220c450d03200228024421122002280240210e200228023821114102210d0c040b200241386a20011033200228023c220c450d02200228024421122002280240210e200228023821114103210d0c030b2004102e0c010b200c200d1035000b200041003602000240200b450d002006210403400240024020042d0000220141034b0d0002400240024020010e0404000102040b2004410c6a280200450d03200441086a280200102e0c030b2004410c6a280200450d02200441086a280200102e0c020b2004410c6a280200450d01200441086a280200102e0c010b200441086a280200450d00200441046a280200102e0b200441246a2104200a415c6a220a0d000b0b2003450d072006102e0c070b200241106a41086a2213200241206a41086a290300370300200220022903203703100240200b2003470d0002400240200341016a22042003490d0020034101742214200420042014491b2204ad42247e2215422088a70d002015a7221441004e0d010b102d000b0240024020030d002014102921060c010b2006200341246c2014102a21060b2006450d03200421030b2006200b41246c6a220420123600102004200e36000c2004200c3600082004200f3b0005200420113600012004200d3a0000200441076a200f4110763a0000200420022903103700142004411c6a2013290300370000200a41246a210a200b41016a2204210b20042005470d000b0b2000200336020420002006360200200041086a20043602000c040b20144104102c000b20044104102c000b1032000b200041003602000b200241e0006a24000bc902010a7f230041106b22022400200241086a200110310240024020022802080d00024020012802042203417f4c0d00200228020c210402400240024020030d00410121050c010b200310292205450d010b02402004450d004100210641002107034002400240024020012802042208450d00200741016a21092001280200220a2d0000210b20012008417f6a3602042001200a41016a36020020072003460d010c020b200041003602002003450d072005102e0c070b02402006200920092006491b22034100480d000240024020070d002003102921050c010b200520072003102a21050b20050d0120034101102c000b102d000b200520076a200b3a0000200641026a21062009210720042009470d000b0b2000200336020420002005360200200041086a20043602000c030b20034101102c000b1032000b200041003602000b200241106a24000bf602010b7f230041106b22022400200241086a200110310240024002400240024020022802080d0020012802042203417c712204417f4c0d02200228020c210502400240200341027622060d00410421070c010b200410292207450d040b02402005450d0041002108410021094100210403400240024002402001280204220a4104490d00200441016a21032001280200220b280000210c2001200a417c6a3602042001200b41046a36020020042006470d0202402008200320032008491b220641ffffffff03712006470d002006410274220a41004e0d020b102d000b200041003602002006450d052007102e0c050b0240024020040d00200a102921070c010b20072009200a102a21070b2007450d070b200720096a200c360200200841026a2108200941046a21092003210420052003470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241106a24000f0b1032000b20044104102c000b200a4104102c000bd408040c7f017e057f037e23004180016b22022400024002400240200141086a220328020022042001410c6a2802002205460d002001280210220628020021072006280208220841014b210903402003200441206a220a360200200241e0006a41186a200441186a290000370300200241e0006a41106a200441106a290000370300200241e0006a41086a200441086a29000037030020022004290000370360410021040240024020090d0020080e020401040b2008210b0340200b410176220c20046a220d20042007200d4105746a200241e0006a412010f8044101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241e0006a412010f8040d02200a2104200a2005470d000b200521040b2000410036020820004201370200024020042005460d00200141086a200520046b41606a41607120046a41206a3602000b2001280204450d012001280200102e0c010b200241c0006a41086a2204200241e0006a41086a290300370300200241c0006a41106a220b200241e0006a41106a290300370300200241c0006a41186a220c200241e0006a41186a29030037030020022002290360220e3703002002200e370340024041201029220f450d00200f2002290340370000200f41186a200c290300370000200f41106a200b290300370000200f41086a2004290300370000200128020421102001280200211102400240200a2005470d0041012112410121130c010b41012112410121130340200628020821032006280200210702400340200241e0006a41186a2208200a41186a290000370300200241e0006a41106a2209200a41106a290000370300200241e0006a41086a2201200a41086a2900003703002002200a290000370360200a41206a210a4100210402400240200341014b0d0020030e020301030b2003210b0340200b410176220c20046a220d20042007200d4105746a200241e0006a412010f8044101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241e0006a412010f8040d01200a2005470d000c030b0b200241c0006a41086a2001290300220e370300200241c0006a41106a20092903002214370300200241c0006a41186a20082903002215370300200220022903602216370340200241186a220b2015370300200241106a220c2014370300200241086a220d200e37030020022016370300024020132012470d000240201241016a22042012490d0020124101742207200420042007491b221341ffffff3f712013470d00201341057422044100480d000240024020120d0020041029210f0c010b200f20124105742004102a210f0b200f0d0120044101102c000b102d000b200f20124105746a22042002290300370000200441186a200b290300370000200441106a200c290300370000200441086a200d290300370000201241016a2112200a2005470d000b0b02402010450d002011102e0b20002012360208200020133602042000200f3602000c010b41204101102c000b20024180016a24000bed0704067f017e0a7f027e230041f0006b22032400200341206a2001200228020c22041100000240024020032802200d002000410036020820004208370200200120022802001101002002280204450d012001102e0c010b200341c8006a41106a200341206a41106a290300370300200341c8006a41086a200341206a41086a290300370300200341c8006a41186a200341206a41186a290300370300200341c8006a41206a200341206a41206a280200360200200341086a200341d4006a290200370300200341106a200341dc006a290200370300200341186a200341e4006a290200370300200320032903203703482003200329024c370300200341c8006a2001200228021022051100000240024002400240417f2003280248220641016a220720072006491b2208ad42287e2209422088a70d002009a72206417f4c0d000240024020060d004108210a4108210b0c010b20061029220a450d02200a210b0b200a2003290300370300200a41186a200341186a220c290300370300200a41106a200341106a220d290300370300200a41086a200341086a290300370300200b4201370320200341206a200120041100000240024020032802200d004101210e0c010b200341c8006a410472210641c800210f4101210e0340200341c8006a41206a200341206a41206a280200360200200341c8006a41186a2210200341206a41186a290300370300200341c8006a41106a2211200341206a41106a290300370300200341c8006a41086a2212200341206a41086a29030037030020032003290320370348200341086a2207200641086a290200370300200d200641106a290200370300200c200641186a290200370300200320062902003703002010200c2903003703002011200d29030037030020122007290300370300200320032903003703480240200e2008470d00200341206a200120051100002008417f2003280220220741016a221320132007491b6a22072008490d0620084101742213200720072013491b2213ad42287e2209422088a70d062009a722074100480d060240024020080d0020071029210a0c010b200a200841286c2007102a210a0b200a450d05200a210b201321080b200b200f6a221341606a2207200329034837030020122903002109201129030021142010290300211520134201370300200741186a2015370300200741106a2014370300200741086a2009370300200341206a20012004110000200f41286a210f200e41016a210e20032802200d000b0b2001200228020011010002402002280204450d002001102e0b2000200e360208200020083602042000200b3602000c040b1032000b20064108102c000b20074108102c000b102d000b200341f0006a24000bd80705077f037e087f017e017f23004180016b22022400024002400240200141086a220328020022042001410c6a2802002205460d0020012802102106200241f4006a2107034020032004220841206a2204360200200841086a2903002109200841106a290300210a2008290300210b200241e0006a41186a200841186a290300370300200241e0006a41106a200a370300200241e0006a41086a20093703002002200b3703600240200aa720062802004d0d002001280214220c2007460d002007290000200c290000520d030b20052004470d000b200521040b2000410036020820004208370200024020042005460d00200141086a200520046b41606a41607120046a41206a3602000b2001280204450d012001280200102e0c010b200241086a2204200241e0006a41086a290300370300200241106a2203200241e0006a41106a290300370300200241186a2207200241e0006a41186a29030037030020022002290360220a3703202002200a37030002400240024041201029220d450d00200d2002290300370300200d41186a2007290300370300200d41106a2003290300370300200d41086a20042903003703002001280204210e2001280200210f4101211002400240200541606a2008470d00410121110c010b0240200c200241f4006a2207470d00410121110c010b200841206a2112200541606a2113410121104101211103402012210802400340200241e0006a41186a2204200841186a290300370300200241e0006a41106a2203200841106a290300220a370300200241e0006a41086a2201200841086a290300370300200220082903003703600240200aa720062802004d0d002007290000200c290000520d020b2005200841206a2208470d000c030b0b200241206a41086a2001290300220a370300200241206a41106a20032903002209370300200241206a41186a2004290300220b3703002002200229036022143703202004200b370300200320093703002001200a37030020022014370360024020112010470d00201041016a22112010490d0520104101742212201120112012491b221141ffffff3f712011470d05201141057422124100480d050240024020100d0020121029210d0c010b200d20104105742012102a210d0b200d450d040b200841206a2112200d20104105746a22152002290360370300201541186a2004290300370300201541106a2003290300370300201541086a2001290300370300201041016a211020132008470d000b0b0240200e450d00200f102e0b20002010360208200020113602042000200d3602000c030b41204108102c000b20124108102c000b102d000b20024180016a24000ba41601067f230041106b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e050003010204000b2002410036020820024201370300410110292203450d05200242818080801037020420022003360200200341023a0000200141016a200210460c040b2002410036020820024201370300410110292203450d05200242818080801037020420022003360200200341043a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a20034101742205200420042005491b22054100480d1a0240024020030d002005102921040c010b200228020020032005102a21040b2004450d0720022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a20034101742205200420042005491b22054100480d1a0240024020030d002005102921040c010b200228020020032005102a21040b2004450d0820022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a20034101742205200420042005491b22054100480d1a0240024020030d002005102921040c010b200228020020032005102a21040b2004450d0920022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a20034101742205200420042005491b22054100480d1a0240024020030d002005102921040c010b200228020020032005102a21040b2004450d0a20022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210470240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d1a20044101742207200620062007491b22064100480d1a0240024020040d002006102921040c010b200228020020042006102a21040b2004450d0b20022006360204200220043602000b2002200320016a360208200420036a2005200110f6041a0c030b2002410036020820024201370300410110292203450d0a200242818080801037020420022003360200200341053a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1920034101742205200420042005491b22054100480d190240024020030d002005102921040c010b200228020020032005102a21040b2004450d0c20022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1920034101742205200420042005491b22054100480d190240024020030d002005102921040c010b200228020020032005102a21040b2004450d0d20022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1920034101742205200420042005491b22054100480d190240024020030d002005102921040c010b200228020020032005102a21040b2004450d0e20022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1920034101742205200420042005491b22054100480d190240024020030d002005102921040c010b200228020020032005102a21040b2004450d0f20022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210470240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d1920044101742207200620062007491b22064100480d190240024020040d002006102921040c010b200228020020042006102a21040b2004450d1020022006360204200220043602000b2002200320016a360208200420036a2005200110f6041a0c020b2002410036020820024201370300410110292203450d0f200242818080801037020420022003360200200341063a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1820034101742205200420042005491b22054100480d180240024020030d002005102921040c010b200228020020032005102a21040b2004450d1120022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1820034101742205200420042005491b22054100480d180240024020030d002005102921040c010b200228020020032005102a21040b2004450d1220022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1820034101742205200420042005491b22054100480d180240024020030d002005102921040c010b200228020020032005102a21040b2004450d1320022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1820034101742205200420042005491b22054100480d180240024020030d002005102921040c010b200228020020032005102a21040b2004450d1420022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210470240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d1820044101742207200620062007491b22064100480d180240024020040d002006102921040c010b200228020020042006102a21040b2004450d1520022006360204200220043602000b2002200320016a360208200420036a2005200110f6041a0c010b2002410036020820024201370300410110292203450d14200242818080801037020420022003360200200341003a0000200141046a28020021052001410c6a2802002201200210470240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d1720044101742207200620062007491b22064100480d170240024020040d002006102921040c010b200228020020042006102a21040b2004450d1620022006360204200220043602000b2002200320016a360208200420036a2005200110f6041a0b200020022201290200370200200041086a200141086a280200360200200241106a24000f0b41014101102c000b41014101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20064101102c000b41014101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20064101102c000b41014101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20064101102c000b41014101102c000b20064101102c000b102d000bb50501037f02400240024002400240024002400240410110292202450d00200220002d00003a0000200241014102102a2202450d01200220002d00013a0001200241024104102a2202450d02200220002d00023a0002200220002d00033a0003200241044108102a2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102a2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102a2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f02400240200141046a2802002203200141086a28020022006b4120490d00200128020021030c010b200041206a22042000490d0820034101742200200420042000491b22004100480d080240024020030d002000102921030c010b200128020020032000102a21030b2003450d0720012003360200200141046a2000360200200141086a28020021000b200141086a200041206a360200200320006a220041186a200241186a290000370000200041106a200241106a290000370000200041086a200241086a290000370000200020022900003700002002102e0f0b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000b20004101102c000b102d000b920701037f0240024002400240024002402000413f4b0d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0620024101742204200320032004491b22044100480d060240024020020d002004102921030c010b200128020020022004102a21030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20004102743a00000f0b200041808001490d032000418080808004490d020c010b20044101102c000b0240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0520024101742204200320032004491b22044100480d050240024020020d002004102921030c010b200128020020022004102a21030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a000002400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d0520034101742202200420042002491b22024100480d050240024020030d002002102921030c010b200128020020032002102a21030b2003450d0220012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20003600000f0b20044101102c000b20024101102c000b024002400240200141046a2802002203200141086a28020022026b4104490d00200128020021030c010b200241046a22042002490d0320034101742202200420042002491b22024100480d030240024020030d002002102921030c010b200128020020032002102a21030b2003450d0120012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20004102744102723600000f0b20024101102c000b024002400240200141046a2802002203200141086a28020022026b4102490d00200128020021030c010b200241026a22042002490d0220034101742202200420042002491b22024100480d020240024020030d002002102921030c010b200128020020032002102a21030b2003450d0120012003360200200141046a2002360200200141086a28020021020b200141086a200241026a360200200320026a20004102744101723b00000f0b20024101102c000b102d000bf40601067f230041f0006b21020240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a2206360204410121072001200441016a360200200541f001490d0a200541847e6a220541034b0d0420050e0401020803010b200041023a00000f0b20064102490d0320042f0001210520012003417d6a3602042001200441036a360200200541ef014b0d04200041023a00000f0b20064104490d042004280001210520012003417b6a3602042001200441056a36020041012107200541ffff034b0d07200041023a00000f0b41002105200241003a00682003417f6a21062003417e6a210302400340024020062005470d000240200541ff0171450d00200241003a00680b410121010c020b200241c8006a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00682003417f6a21032007210520074120470d000b200241c6006a20022d004a3a0000200241306a200241d7006a290000370300200241386a200241df006a290000370300200241c0006a200241e7006a2d00003a0000200220022f01483b01442002200229004f370328200228004b2105410021010b200241246a41026a2203200241c4006a41026a2d00003a0000200241086a41086a2207200241286a41086a290300370300200241086a41106a2204200241286a41106a290300370300200241086a41186a2206200241286a41186a2d00003a0000200220022f01443b0124200220022903283703082001450d05200041023a00000f0b200041023a00000f0b200041023a00000f0b410121070c030b200041023a00000f0b0240200641044f0d00200041023a00000f0b200041023a000020012003417b6a3602042001200441056a3602000f0b200241286a41026a20032d00003a0000200241c8006a41086a2007290300370300200241c8006a41106a2004290300370300200241c8006a41186a20062d00003a0000200220022f01243b012820022002290308370348410021070b200020073a0000200020022f01283b0001200041046a2005360200200041086a2002290348370200200041036a2002412a6a2d00003a0000200041106a200241c8006a41086a290300370200200041186a200241c8006a41106a290300370200200041206a200241c8006a41186a2802003602000bb20801037f0240024002400240024002400240024020002d00004101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0820024101742204200320032004491b22044100480d080240024020020d002004102921030c010b200128020020022004102a21030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41ff013a0000200041016a2001104a0f0b0240024002400240200041046a280200220241ffff034b0d00200241ef014b0d03200141046a280200200141086a2802002200460d01200128020021030c020b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0a20004101742204200320032004491b22044100480d0a0240024020000d002004102921030c010b200128020020002004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41fd013a000002400240200141046a2802002203200428020022006b4104490d00200128020021030c010b200041046a22042000490d0a20034101742200200420042000491b22004100480d0a0240024020030d002000102921030c010b200128020020032000102a21030b2003450d0620012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20023600000f0b200041016a22032000490d0820004101742204200320032004491b22044100480d080240024020000d002004102921030c010b200128020020002004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a20023a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0720004101742204200320032004491b22044100480d070240024020000d002004102921030c010b200128020020002004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41fc013a000002400240200141046a2802002203200428020022006b4102490d00200128020021030c010b200041026a22042000490d0720034101742200200420042000491b22004100480d070240024020030d002000102921030c010b200128020020032000102a21030b2003450d0620012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a20023b00000f0b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20004101102c000b102d000b952801057f02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2202280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00003a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00013a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00023a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00033a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00043a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00053a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00063a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00073a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00083a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00093a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000e3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1020012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000f3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00103a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00113a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00123a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00133a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00143a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00153a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00163a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00173a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00183a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00193a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001e3a000002400240200228020020032802002202460d00200128020021040c010b200241016a22042002490d2120024101742205200420042005491b22054100480d210240024020020d002005102921040c010b200128020020022005102a21040b2004450d2020012004360200200141046a2005360200200141086a28020021020b2003200241016a360200200420026a20002d001f3a00000f0b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20054101102c000b102d000b9b0502067f027e230041c0006b220324002003200236020820032001280200220236020020032002200128020841246c22016a22043602042003200341086a36020c024002400240200141ed00490d00200341286a410472210103402003200241246a360200200341286a2003410c6a2002104c200341106a41086a2204200141086a2205290200370300200341106a41106a2206200141106a220728020036020020032001290200370310200341106a2108200328022822024105470d0220032003280200220241246a360200200341286a2003410c6a2002104c200420052902003703002006200728020036020020032001290200370310200328022822024105470d0220032003280200220241246a360200200341286a2003410c6a2002104c200420052902003703002006200728020036020020032001290200370310200328022822024105470d0220032003280200220241246a360200200341286a2003410c6a2002104c200420052902003703002006200728020036020020032001290200370310200328022822024105470d0220032802042204200328020022026b41ec004b0d000b0b024020022004460d00200341286a410472210103402003200241246a360200200341286a2003410c6a2002104c200341106a41086a200141086a290200370300200341106a41106a200141106a280200360200200320012902003703100240200328022822024105460d00200341106a21080c030b200328020022022003280204470d000b0b200041053602000c010b200341286a41106a200841106a2802002201360200200341286a41086a200841086a290200220937030020032008290200220a370328200020023602002000200a3702042000410c6a2009370200200041146a20013602000b200341c0006a24000bea0602047f037e230041206b2203240020012802002802002201280204210420012802002101024002400240024002400240024002400240024002400240024020022d00000e050001020304000b200241016a21024100210520010e0406040507060b200241086a210641012105200241016a210220010e0405030406050b200241086a2106200241016a21024102210520010e0404020305040b200241086a2106200241016a21024103210520010e0403010204030b41042105200241046a210220010e0402000103020b20054102470d0520022004470d03200621020c040b20054103470d04024020022004470d00200621020c040b200228000021012006210220012004280000460d030c040b20054101470d03024020022004470d00200621020c030b200228000021012006210220012004280000460d020c030b20054104470d020c010b200228000021012006210220012004280000470d010b2002280200210120032002280208220236020c200320013602082002450d0020012d0000210520032002417f6a220436020c2003200141016a3602082005417f6a220541044b0d000240024002400240024002400240024020050e050001020304000b200341106a200341086a103e20032802102205450d0720032902142107200328020c22024104490d0620032802082201350000210820032002417c6a36020c2003200141046a360208410021060c050b20044104490d062001280001210520032002417b6a36020c2003200141056a360208200341106a200341086a103e20032802102202450d06200328021421010240200328020c220441044f0d002001450d072002102e0c070b200341186a350200210820032802082206350000210920032004417c6a36020c2003200641046a3602082001ad4220862002ad84210720082009422086842108410121060c040b20044108490d05200129000121072003200241776a36020c2003200141096a360208410221060c030b20044104490d042001280001210520032002417b6a36020c2003200141056a360208410321060c010b4104210620044104490d032001280001210520032002417b6a36020c2003200141056a3602080b0b2000200536020420002006360200200041106a2008370300200041086a20073703000c020b2007a7450d002005102e0b200041053602000b200341206a24000b942004027f027e087f037e230041a00d6b22072400024002400240200128022c200128023c22082802b801460d002004420020042903082209200841c0006a2903007d220a200a20095622081b3703082008450d01200041c083c00036020420004101360200200041086a412a3602002000410c6a2006290200370200200041146a200641086a2802003602000c020b200041f682c00036020420004101360200200041086a41243602002000410c6a2006290200370200200041146a200641086a2802003602000c010b200741086a41186a200141e4006a290000370300200741086a41106a200141dc006a290000370300200741086a41086a200141d4006a2900003703002007200129004c3703082006280208210b20062802002108200741a0026a41186a220c4200370300200741a0026a41106a220d4200370300200741a0026a41086a220e4200370300200742003703a0022008200b200741a0026a1000200741c00a6a41186a200c290300370300200741c00a6a41106a200d290300370300200741c00a6a41086a200e290300370300200720072903a0023703c00a024002400240024002400240024002400240412010292208450d0020082005290000370000200841186a200541186a290000370000200841106a200541106a290000370000200841086a200541086a2900003700002008412041c000102a2208450d01200820072903c00a370020200841386a200741c00a6a41186a290300370000200841306a200741c00a6a41106a290300370000200841286a200741c00a6a41086a290300370000200841c000418001102a2208450d0220082007290308370040200841d8006a200741086a41186a290300370000200841d0006a200741086a41106a290300370000200841c8006a200741086a41086a290300370000200741a0026a41186a220c4200370300200741a0026a41106a220d4200370300200741a0026a41086a220e4200370300200742003703a002200841e000200741a0026a1000200741286a41186a220f200c290300370300200741286a41106a220c200d290300370300200741286a41086a220d200e290300370300200720072903a0023703282008102e200629020021092007419c016a200d290300370200200741a4016a200c290300370200200741ac016a200f290300370200200741c8006a41386a4100360200200741c8006a41286a419c83c000360200200741ec006a200141146a2210360200200741e4006a4200370200200741c8006a41186a221141e08dc0003602002007200729032837029401200742083703782007410036025c200741003602502007200128024436028c012007200129023c370284012007200128022c41016a3602742001290300210a20072001280248360290012007200a370348200741b8016a41186a200541186a290000370300200741b8016a41106a200541106a290000370300200741b8016a41086a200541086a2900003703002007410136025c200720052900003703b8012010200741286a104e21062007200728025c417f6a220836025c024020060d0020080d042007417f36025c20074180026a41186a200741286a41186a29030037030020074180026a41106a200741286a41106a29030037030020074180026a41086a200741286a41086a2903003703002007200729032837038002024002402007280260220e41e08dc000460d002007280264210f0c010b4100210f200741c00a6a410041e00210f5041a200741a0026a410041a00810f5041a41880b1029220e450d06200e41003b0106200e4100360200200e41086a200741c00a6a41e00210f6041a200e41e8026a200741a0026a41a00810f6041a200741003602642007200e3602600b024002400340200e41086a2108200e2f0106221241057421064100210c0240024003402006450d0120074180026a2008412010f804220d450d02200641606a2106200c41016a210c200841206a2108200d417f4a0d000b200c417f6a21120b200f450d02200f417f6a210f200e20124102746a41880b6a280200210e0c010b0b200e200c41e0006c6a41e8026a21060c010b200741e0016a41186a20074180026a41186a290300220a370300200741e0016a41106a20074180026a41106a2903002213370300200741e0016a41086a20074180026a41086a2903002214370300200720072903800222153703e001200741dc0a6a2014370200200741e40a6a2013370200200741ec0a6a200a3702002007200741e8006a3602d00a200720123602cc0a200720113602c80a2007200e3602c40a200741003602c00a200720153702d40a200741d4026a4200370200200741003a00dc02200742003703a002200741e08dc0003602d002200742003703b802200741c00a6a200741a0026a104f21060b200641013a003c200641286a427f370300200641206a427f3703002006413d6a20072903b801370000200641d5006a200741d0016a290300370000200641cd006a200741c8016a290300370000200641c5006a200741c0016a290300370000200642013703182007200728025c41016a36025c200720044101200741086a200741286a20022003200741c8006a10502007280200220e0d06200741a0026a2005200728028c012802001051024020072802a0024101470d00200741a8026a280200210520072802a402210e0c090b20074180026a41186a220c200741a0026a410472220641186a2802002208360200200741c00a6a41106a200641086a290200370300200741c00a6a41186a220d200641106a290200370300200741e00a6a2008360200200741063602c40a200741b1a4c5003602c00a200720062902003703c80a20072802880121062007200741c8006a3602b8022007290348210a2007280290012108200741c8026a200741086a41086a220f290300370300200741d0026a200741086a41106a2212290300370300200741d8026a200741086a41186a2211290300370300200720033703a802200720023703a002200720083602bc022007200a3703b002200720072903083703c0022007200b3602e801200720093703e00120074180026a2006200741c00a6a200741a0026a200741e0016a200410522007418c026a290200210920074180026a41086a22062802002105200728028402210e02402007280280024101470d0020074180026a41146a280200210b200d280200450d09200741c00a6a41146a280200102e0c090b2006200f29030037030020074180026a41106a2012290300370300200c2011290300370300200741e0016a41086a200741286a41086a290300370300200741e0016a41106a200741286a41106a290300370300200741e0016a41186a200741286a41186a2903003703002007200729030837038002200720072903283703e00102402007280280012206200728027c460d00200728027821080c0a0b0240200641016a22082006490d002006410174220c20082008200c491b220cad42b0017e2202422088a70d002002a7220d4100480d000240024020060d00200d102921080c010b2007280278200641b0016c200d102a21080b2008450d082007200c36027c2007200836027820072802800121060c0a0b102d000b41c8dac100210e412a21050c070b41204101102c000b41c0004101102c000b4180014101102c000b41aed9c1004110200741a0026a41c0d9c1001053000b41880b4108102c000b200728020421050c010b200d4108102c000b024020072802502206450d00200741d4006a280200450d002006102e0b200728026821012007280260210602400240200728026422080d002006210c0c010b2008210d2006210c0340200c2802880b210c200d417f6a220d0d000b0340200620062f01064102746a41880b6a28020021062008417f6a22080d000b0b200741bc026a20062f010636020041002108200741b8026a4100360200200741b4026a2006360200200720013602c002200741003602b002200742003703a8022007200c3602a402200741003602a002200741a0026a105402402007280280012206450d002007280278210d200641b0016c2101034002400240200d20086a22062d0000220c41014b0d0002400240200c0e020001000b0240200641086a280200450d00200641046a280200102e0b200641106a2d00004105490d02200641386a280200450d02200641346a280200102e0c020b200641286a102f0c010b200641e8006a280200450d00200641e4006a280200102e0b2001200841b0016a2208470d000b0b0240200728027c450d002007280278102e0b2000200e36020420004101360200200041146a200b3602002000410c6a2009370200200041086a20053602000c010b2008200641b0016c6a220641003a0000200620072f00dd013b0001200641013a00102006410036000c200642013700042006200729038002370011200620072903e001370031200641036a200741df016a2d00003a0000200641196a20074180026a41086a290300370000200641216a20074180026a41106a290300370000200641296a20074180026a41186a290300370000200641396a200741e0016a41086a290300370000200641c1006a200741e0016a41106a290300370000200641c9006a200741e0016a41186a290300370000200641e0006a200741c7016a290000370000200641d9006a200741b8016a41086a290000370000200620072900b801370051200641e8006a200741a0026a41c80010f6041a200720072802800141016a2208360280010240200741c00a6a41186a280200450d00200741d40a6a280200102e20072802800121080b200728027c210b20072802782104200728026821122007280264210d2007280260210602402007280250220c450d00200741d4006a280200450d00200c102e0b0240024020094280808080f01f8350450d00200720123602a8022007200d3602a402200720063602a0022010200741a0026a105520072004200841b0016c6a3602ac02200720043602a8022007200b3602a402200720043602a002200141306a200741a0026a10280c010b02402008450d00200841b0016c210f41002108034002400240200420086a220c2d0000220141014b0d000240024020010e020001000b0240200c41086a280200450d00200c41046a280200102e0b200c41106a2d00004105490d02200c41386a280200450d02200c41346a280200102e0c020b200c41286a102f0c010b200c41e8006a280200450d00200c41e4006a280200102e0b200f200841b0016a2208470d000b0b0240200b450d002004102e0b02400240200d0d00200621080c010b200d210c20062108034020082802880b2108200c417f6a220c0d000b0340200620062f01064102746a41880b6a2802002106200d417f6a220d0d000b0b200741bc026a20062f0106360200200741b8026a4100360200200741b4026a2006360200200720123602c002200741003602b002200742003703a802200720083602a402200741003602a002200741a0026a10540b20002007290328370004200041003602002000412c6a2009370200200041286a2005360200200041246a200e3602002000411c6a200741c0006a290300370000200041146a200741386a2903003700002000410c6a200741306a2903003700000b200741a00d6a24000b940201097f230041106b220224000240200028020041016a220341004c0d0020002003360200200041046a2104200041086a28020021050240024003402004280200220641086a210720062f01062208410574210441002109024003402004450d0120012007412010f804220a450d03200441606a2104200941016a2109200741206a2107200a417f4a0d000b2009417f6a21080b02402005450d002005417f6a2105200620084102746a41880b6a21040c010b0b20002802102001200041146a2802002802181102002104200028020021030c010b2006200941e0006c6a41a4036a2d000041014621040b20002003417f6a360200200241106a240020040f0b41e3d7c1004118200241086a41fcd7c1001053000b8f1901187f230041d0116b2202240020002802102203200328020041016a360200200028020c21042000280208210520002802042103200241206a41186a22062000412c6a290000370300200241206a41106a2207200041246a290000370300200241206a41086a22082000411c6a29000037030020022000290014370320200241a0026a200141e00010f6041a024002400240024020032f01062201410b490d00200241b0036a410041e00210f5041a20024198066a410041a00810f5041a0240024041880b10292209450d00200941003b010620094100360200200941086a200241b0036a41e00210f6042101200941e8026a20024198066a41a00810f6042106200220032f00c8013b01ac032002200341ca016a2d00003a00ae03200220032900db01370398032002200341e0016a29000037009d03200341cb016a280000210a200341cf016a280000210b200341d3016a280000210c200341d7016a280000210d20024198066a200341a8076a41e00010f6041a2001200341e8016a20032f010641796a220041057410f6042101200620034188086a200041e0006c10f6042106200341063b0106200920003b0106200220022f01ac033b019403200220022d00ae033a0096032002200229039803370380032002200229009d0337008503200241b0036a20024198066a41e00010f6041a0240024020044107490d00200441057420016a41c07e6a2001200441796a22074105746a2201200041ffff037120076b41057410f7041a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200441e0006c20066a220041c07b6a200041e07a6a220e200941066a22002f010020076b41e0006c10f7041a200e200241a0026a41e00010f6041a0c010b200341086a20044105746a220141206a2001200341066a22002f010020046b41057410f7041a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200341e8026a200441e0006c6a220e41e0006a200e20002f010020046b41e0006c10f7041a200e200241a0026a41e00010f6041a0b20024188026a41026a220420022d0096033a0000200020002f010041016a3b0100200220022f0194033b01880220022002290380033703800120022002290085033700850120024190016a200241b0036a41e00010f6041a2002411c6a41026a220f20042d00003a0000200220022f0188023b011c2002200229038001370308200220022900850137000d200241206a20024190016a41e00010f6041a20032802002206450d0320032f0104211020024198066a410272211103402002419c026a41026a2212200f2d00003a0000200220022f011c3b019c0220022002290308370388022002200229000d37008d02200241a0026a200241206a41e00010f6041a201041ffff0371210702400240024020062f01062203410b490d002011410041b20b10f5041a41b80b10292201450d0520014100360200200141046a20024198066a41b40b10f6041a200220062f00c8013b01ac032002200641ca016a2d00003a00ae03200220062900db01370398032002200641e0016a29000037009d03200641cb016a2800002113200641cf016a2800002114200641d3016a2800002115200641d7016a280000211620024198066a200641a8076a41e00010f6041a200141086a200641e8016a20062f0106220041796a220341057410f6042117200141e8026a20064188086a200341e0006c10f6042118200141880b6a200641a40b6a2000417a6a220841027410f6042119200641063b0106200120033b010602402008450d00410021032019210003402000280200220420033b010420042001360200200041046a21002008200341016a2203470d000b0b200241b0036a20024198066a41e00010f6041a200220022d00ae0322033a009603200220022f01ac0322003b0194032002200229009d033700850320022002290398033703800320024194066a41026a220820033a0000200220003b01940620022002290380033703800120022002290085033700850120024198066a200241b0036a41e00010f6041a201041ffff037122004107490d0120172007417a6a22044105746a2017200741796a22034105746a220020012f010620036b41057410f7041a200041186a200229008d023700002000200d36000f2000200c36000b2000200b3600072000200a360003200041026a20122d00003a0000200020022f019c023b00002000200229038802370013200741e0006c20186a220041c07b6a200041e07a6a220020012f010620036b41e0006c10f7041a2000200241a0026a41e00010f6041a200120012f010641016a22003b01062007410274220a20196a416c6a201920044102746a2210200041ffff0371220720046b41027410f7041a2010200936020020072004490d022001200a6a41f00a6a2100034020002802002204200341016a22033b010420042001360200200041046a210020032007490d000c030b0b200641086a2200200741016a22044105746a200020074105746a2200200320076b220141057410f7041a2000200d36000f2000200c36000b2000200b3600072000200a360003200041026a2002419c026a41026a2d00003a0000200020022f019c023b00002000200229038802370013200041186a200229008d023700002006200741e0006c6a220041c8036a200041e8026a2200200141e0006c10f7041a2000200241a0026a41e00010f6041a2006200341016a22033b01062007410274200641880b6a22006a41086a200020044102746a2200200341ffff037120046b41027410f7041a20002009360200201041ffff037120062f010622034f0d07200920043b010420092006360200200420034f0d072003417f6a210120062004417f6a22034102746a41900b6a2100034020002802002204200341026a3b010420042006360200200041046a21002001200341016a2203470d000c080b0b200641086a2203200741016a22044105746a200320074105746a220320062f0106221020076b221941057410f7041a2003200d36000f2003200c36000b2003200b3600072003200a360003200341026a20122d00003a0000200320022f019c023b00002003200229038802370013200341186a200229008d02370000200641e8026a200741e0006c6a220341e0006a2003201941e0006c10f7041a2003200241a0026a41e00010f6041a2006201041016a22033b010620074102742219200641880b6a22106a41086a201020044102746a2210200341ffff037120046b41027410f7041a20102009360200200020062f010622044f0d00200620196a418c0b6a2103034020032802002200200741016a22073b010420002006360200200341046a210320042007470d000b0b20024184026a41026a220320082d00003a0000200220022f0194063b01840220022002290380013703f00120022002290085013700f50120024190016a20024198066a41e00010f6041a200f20032d00003a0000200220022f0184023b011c200220022903f001370308200220022900f50137000d200241206a20024190016a41e00010f6041a0240200628020022030d002013210a2016210d2015210c2014210b200121090c050b20062f010421102013210a2016210d2015210c2014210b20032106200121090c000b0b41880b4108102c000b41b80b4108102c000b200320044105746a220041286a200041086a2210200120046b41057410f7041a200041206a2006290300370000200041186a2007290300370000200041106a2008290300370000201020022903203700002003200441e0006c6a220041c8036a200041e8026a220e20032f010620046b41e0006c10f7041a200e200241a0026a41e00010f6041a200320032f010641016a3b01060c010b20024198066a410272410041b20b10f5041a41b80b10292203450d0120034100360200200341046a20024198066a41b40b10f6041a2003200528020022003602880b200520033602002005200528020441016a360204200041003b010420002003360200200320032f010622044105746a220041086a20022f011c3b00002000410a6a2002411c6a41026a2d00003a0000200041176a200d360000200041136a200c3600002000410f6a200b3600002000410b6a200a3600002000411b6a2002290308370000200041206a200229000d3700002003200441e0006c6a41e8026a200241206a41e00010f6041a200341880b6a200441016a22004102746a2009360200200320003b0106200920003b0104200920033602000b200241d0116a2400200e0f0b41b80b4108102c000b9f0d020b7f067e230041d0016b22082400024002400240024002400240200728021441016a220941004c0d00200741146a210a200720093602142007411c6a280200210b200741186a220c210d024002400340200d280200220e41086a210f200e2f01062210410574210d41002111024002400340200d450d012004200f412010f8042212450d02200d41606a210d201141016a2111200f41206a210f2012417f4a0d000b2011417f6a21100b200b450d02200b417f6a210b200e20104102746a41880b6a210d0c010b0b200e201141e0006c6a220d41e8026a280200450d00200d41f8026a2903002113200d41f0026a29030021140c010b200841286a200741246a2802002004200741286a28020028021c110300200841306a290300211320072802142109200829032821140b20072009417f6a360214200141186a2903002115200728023c210d20012903102116024002400240024041004101410220142013842217501b20021b0e03010200010b200d41a8016a210d0c020b200d4188016a210d0c010b200d4198016a210d0b20162015844200510d01200841186a200d290300200d41086a2903002016201510fc0420014200200129030822152008290318427f200841186a41086a290300501b7d22162016201556220d1b3703080240200d450d0041ea83c000210d4122210f0c060b200a28020041016a220141004c0d0220072001360214200728021c210b024002400340200c280200220e41086a210f200e2f01062210410574210d41002111024002400340200d450d012003200f412010f8042212450d02200d41606a210d201141016a2111200f41206a210f2012417f4a0d000b2011417f6a21100b200b450d02200b417f6a210b200e20104102746a41880b6a210c0c010b0b200e201141e0006c6a220d41e8026a280200450d00200d41f8026a2903002115200d41f0026a29030021160c010b200841086a200741246a2802002003200741286a28020028021c110300200841106a290300211520072802142101200829030821160b200a2001417f6a3602000240201620057d2218201656201520067d2016200554ad7d221620155620162015511b4101470d004191b5c000210d411d210f0c060b024020174200520d00200728023c220d290378200556200d4180016a290300221520065620152006511b450d0041d6b5c000210d411f210f0c060b20082003410220182016105602402008280200220d450d002008280204210f0c060b0240201420057c2217201454220d201320067c200dad7c221520135420152013511b450d0041e4b4c000210d412d210f0c060b4100210d024020032004470d000c060b024020032004412010f8040d000c060b200a2003201820161057200a2004201720151057200841a8016a41086a200341086a290000370300200841a8016a41106a200341106a290000370300200841a8016a41186a200341186a29000037030020084188016a41086a200441086a29000037030020084188016a41106a200441106a29000037030020084188016a41186a200441186a290000370300200820032900003703a801200820042900003703880102400240200741386a280200220f200741346a280200460d00200728023021110c010b200f41016a220d200f490d05200f4101742211200d200d2011491b220dad42b0017e2215422088a70d052015a722124100480d0502400240200f0d002012102921110c010b2007280230200f41b0016c2012102a21110b2011450d0420072011360230200741346a200d3602002007280238210f0b4100210d2011200f41b0016c6a220f41003a0000200f20082f00cd013b0001200f4200370008200f4101360004200f20082903a801370011200f200829038801370031200f41036a200841cf016a2d00003a0000200f41106a41003a0000200f41196a200841a8016a41086a290300370000200f41216a200841a8016a41106a290300370000200f41296a200841a8016a41186a290300370000200f41c9006a20084188016a41186a290300370000200f41c1006a20084188016a41106a290300370000200f41396a20084188016a41086a290300370000200f2005370358200f41e0006a2006370300200f41d4006a20084181016a41036a280000360000200f200828008101360051200f41e8006a200841386a41c80010f6041a2007200728023841016a3602380c050b41e3d7c1004118200841386a41fcd7c1001053000b41c8a5c3001058000b41e3d7c1004118200841386a41fcd7c1001053000b20124108102c000b102d000b2000200f3602042000200d360200200841d0016a24000bd61001107f230041a0016b2203240002400240024002400240024002400240024002400240411410292204450d00200441106a41002800aca543360000200441086a41002900a4a5433700002004410029009ca54337000020034294808080c00237027c200320043602782001200341f8006a1046200328027c2105200328028001210420032802782106200341f8006a41186a22074200370300200341f8006a41106a22084200370300200341f8006a41086a220942003703002003420037037820062004200341f8006a1000200341d8006a41186a2007290300370300200341d8006a41106a2008290300370300200341d8006a41086a20092903003703002003200329037837035820034100360278200341d8006a4120200341f8006a1008210a2003280278220b417f460d03200a450d032003200b36027c2003200a360278200341286a200341f8006a103120032802280d02200328022c2107200341206a200341f8006a103120032802200d0220032802242109200341186a200341f8006a103120032802180d02200328027c2204450d02200328021c210c20032004417f6a36027c20032003280278220441016a36027820042d0000220441014b0d02410021080240024020040e020100010b410121080b200341106a200341f8006a103120032802100d02200328027c220d20032802142204490d022004417f4c0d050240024020040d004101210e0c010b20041034220e450d02200e2003280278220f200410f6041a2003200d20046b36027c2003200f20046a3602780b200e450d02200341d4006a41026a220d200341386a41026a2d00003a0000200320032f00383b01540240200b450d00200a102e0b200341f8006a41026a200d2d00003a0000200320032f01543b01780c040b41144101102c000b20044101102c000b41eff0c2004133200341386a4184f4c2001053000b410221080b02402005450d002006102e0b0240024020084102470d004101210641f2dac1002107411121090c010b200341d8006a41026a200341f8006a41026a2d00003a0000200320032f01783b0158410021060b200341346a41026a200341d8006a41026a2d00003a0000200320032f01583b013402402006450d002000200736020420004101360200200041086a20093602000c060b200341d4006a41026a220a200341346a41026a2d00003a0000200320032f01343b015402400240200228025820074b0d00200421050c010b411510292208450d02410021072008410d6a4100290094a543370000200841086a410029008fa54337000020084100290087a54337000020034295808080d00237027c200320083602782001200341f8006a1046200328027c2105200328028001210620032802782108200341f8006a41186a22094200370300200341f8006a41106a220b4200370300200341f8006a41086a220c42003703002003420037037820082006200341f8006a1000200341d8006a41186a2009290300370300200341d8006a41106a200b290300370300200341d8006a41086a200c2903003703002003200329037837035820034100360278200341d8006a4120200341f8006a10082109024002402003280278220b417f470d00410021070c010b024020090d000c010b2003200b36027c20032009360278200341086a200341f8006a103102400240024020032802080d00200328027c220c200328020c2206490d002006417f4c0d050240024020060d00410121070c010b200610342207450d0220072003280278220d200610f6041a2003200c20066b36027c2003200d20066a3602780b20070d020b41eff0c2004133200341386a4184f4c2001053000b20064101102c000b200b450d002009102e0b02402005450d002008102e0b024020070d0020004183dbc10036020420004101360200200041086a411a3602000c060b2007410020071b210d200341f8006a20072006200210f701024020032802784101470d002000200329027c370204200041013602002006450d06200d102e0c060b02402004450d00200e102e0b200341d6006a20034197016a2d00003a0000200320032f0095013b015420034190016a2802002204417f4c0d0120034194016a2d000021082003418c016a280200210520034188016a280200210e20034184016a280200210c20034180016a2802002109200328027c21074101210202402004450d00200410292202450d042002200e200410f6041a0b200341386a41146a2004360200200341386a41106a20043602002003200c3602402003200936023c20032007360238200320023602442003200841ff01714101463a005041141029220b450d04200b41106a41002800aca543360000200b41086a41002900a4a543370000200b410029009ca54337000020034294808080c00237027c2003200b3602782001200341f8006a1046200328027c210b200328028001210f20032802782101200341f8006a41186a22104200370300200341f8006a41106a22114200370300200341f8006a41086a22124200370300200342003703782001200f200341f8006a1000200341d8006a41186a2010290300370300200341d8006a41106a2011290300370300200341d8006a41086a2012290300370300200320032903783703582003412036027c2003200341d8006a360278200341386a200341f8006a10f8010240200b450d002001102e0b02402004450d002002102e0b2006450d00200d102e0b20002007360204200020032f01543b001d200041003602002000411c6a20083a0000200041186a2004360200200041146a2005360200200041106a200e3602002000410c6a200c360200200041086a20093602002000411f6a200a2d00003a00000c050b1032000b41154101102c000b20044101102c000b41144101102c000b2004450d00200e102e0b200341a0016a24000beb3002097f017e230041c0006b22062400024002402002410c6a280200200241106a28020010192207417f460d00410c102922080d01410c4104102c000b10e202000b200820073602082008428180808010370200024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002404101450d002008410141016a3602004101417e460d0020084101410272360200410410292209450d01200920083602002008280208210a41031029220b450d02200b41026a41002d008cc5453a0000200b41002f008ac5453b000041061029220c450d03200c41046a41002f008b9a433b0000200c41002800879a43360000412010292207450d042007200a36021c2007410136021820074286808080e0003702102007200c36020c20074283808080303702042007200b36020020082008280200417f6a220b3602000240200b0d002008280208101a20082008280204417f6a220b360204200b0d002008102e0b41031029220b450d05200b41026a41002d008cc5453a0000200b41002f008ac5453b000041031029220c450d06200c41026a41002d008fc5453a0000200c41002f008dc5453b00002007412041c000102a2207450d072007410236023c2007410036023820074283808080303702302007200c36022c20074283808080303702242007200b36022041031029220b450d08200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410f1029220c450d09200c41076a41002900c39c45370000200c41002900bc9c45370000200741c000418001102a2207450d0a2007410336025c200741003602582007428f808080f0013702502007200c36024c20074283808080303702442007200b36024041031029220b450d0b200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410f1029220c450d0c200c41076a41002900d29c45370000200c41002900cb9c453700002007410436027c200741003602782007428f808080f0013702702007200c36026c20074283808080303702642007200b36026041031029220b450d0d200b41026a41002d008cc5453a0000200b41002f008ac5453b000041081029220c450d0e200c42e5f0d1fbb5ac98b6ec003700002007418001418002102a2207450d0f2007410536029c012007410036029801200742888080808001370290012007200c36028c012007428380808030370284012007200b3602800141031029220b450d10200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410a1029220c450d11200c41086a41002f00ea9c453b0000200c41002900e29c45370000200741063602bc01200741003602b8012007428a808080a0013702b0012007200c3602ac0120074283808080303702a4012007200b3602a00141031029220b450d12200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410a1029220c450d13200c41086a41002f00f49c453b0000200c41002900ec9c45370000200741073602dc01200741003602d8012007428a808080a0013702d0012007200c3602cc0120074283808080303702c4012007200b3602c00141031029220b450d14200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410a1029220c450d15200c41086a41002f00fe9c453b0000200c41002900f69c45370000200741083602fc01200741003602f8012007428a808080a0013702f0012007200c3602ec0120074283808080303702e4012007200b3602e00141031029220b450d16200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410b1029220c450d17200c41076a41002800879d45360000200c41002900809d453700002007418002418004102a2207450d182007410936029c0220074100360298022007428b808080b001370290022007200c36028c022007428380808030370284022007200b3602800241031029220b450d19200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410d1029220c450d1a200c41056a41002900909d45370000200c410029008b9d453700002007410a3602bc02200741003602b8022007428d808080d0013702b0022007200c3602ac0220074283808080303702a4022007200b3602a00241031029220b450d1b200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410c1029220c450d1c200c41086a41002800a09d45360000200c41002900989d453700002007410b3602dc02200741003602d8022007428c808080c0013702d0022007200c3602cc0220074283808080303702c4022007200b3602c00241031029220b450d1d200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410b1029220c450d1e200c41076a41002800ab9d45360000200c41002900a49d453700002007410c3602fc02200741003602f8022007428b808080b0013702f0022007200c3602ec0220074283808080303702e4022007200b3602e00241031029220c450d1f200c41026a41002d008cc5453a0000200c41002f008ac5453b000041151029220b450d20200b410d6a41002900bc9d45370000200b41086a41002900b79d45370000200b41002900af9d453700002007410d36029c03200741003602980320074295808080d002370290032007200b36028c032007428380808030370284032007200c3602800341031029220b450d21200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410a1029220c450d22200c41086a41002f00cc9d453b0000200c41002900c49d453700002007410e3602bc03200741003602b8032007428a808080a0013702b0032007200c3602ac0320074283808080303702a4032007200b3602a00341031029220b450d23200b41026a41002d008cc5453a0000200b41002f008ac5453b000041071029220c450d24200c41036a41002800d19d45360000200c41002800ce9d453600002007410f3602dc03200741003602d80320074287808080f0003702d0032007200c3602cc0320074283808080303702c4032007200b3602c00341031029220c450d25200c41026a41002d008cc5453a0000200c41002f008ac5453b000041111029220b450d26200b41106a41002d00e59d453a0000200b41086a41002900dd9d45370000200b41002900d59d45370000200741103602fc03200741003602f8032007429180808090023702f0032007200b3602ec0320074283808080303702e4032007200c3602e00341031029220b450d27200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410e1029220c450d28200c41066a41002900ec9d45370000200c41002900e69d453700002007418004418008102a220a450d29200a411136029c04200a410036029804200a428e808080e00137029004200a200c36028c04200a42838080803037028404200a200b36028004410310292207450d2a200741026a41002d008cc5453a0000200741002f008ac5453b000041101029220b450d2b200b41086a41002900fc9d45370000200b41002900f49d45370000200a41123602bc04200a41003602b804200a429080808080023702b004200a200b3602ac04200a4283808080303702a404200a20073602a004410310292207450d2c200741026a41002d008cc5453a0000200741002f008ac5453b000041101029220b450d2d200b41086a410029008c9e45370000200b41002900849e45370000200a41133602dc04200a41003602d804200a429080808080023702d004200a200b3602cc04200a4283808080303702c404200a20073602c00441031029220b450d2e200b41026a41002d008cc5453a0000200b41002f008ac5453b0000411110292207450d2f200741106a41002d00a49e453a0000200741086a410029009c9e45370000200741002900949e45370000200a41143602fc04200a41003602f804200a429180808090023702f004200a20073602ec04200a4283808080303702e404200a200b3602e00441031029220b450d30200b41026a41002d008cc5453a0000200b41002f008ac5453b0000411110292207450d31200741106a41002d00b59e453a0000200741086a41002900ad9e45370000200741002900a59e45370000200a411536029c05200a410036029805200a4291808080900237029005200a200736028c05200a42838080803037028405200a200b3602800541031029220b450d32200b41026a41002d008cc5453a0000200b41002f008ac5453b0000411610292207450d332007410e6a41002900c49e45370000200741086a41002900be9e45370000200741002900b69e45370000200a41163602bc05200a41003602b805200a4296808080e0023702b005200a20073602ac05200a4283808080303702a405200a200b3602a00541031029220b450d34200b41026a41002d008cc5453a0000200b41002f008ac5453b0000411210292207450d35200741106a41002f00dc9e453b0000200741086a41002900d49e45370000200741002900cc9e45370000200a41173602dc05200a41003602d805200a4292808080a0023702d005200a20073602cc05200a4283808080303702c405200a200b3602c005410310292207450d36200741026a41002d008cc5453a0000200741002f008ac5453b0000410b1029220b450d37200b41076a41002800e59e45360000200b41002900de9e45370000200a41183602fc05200a41003602f805200a428b808080b0013702f005200a200b3602ec05200a4283808080303702e405200a20073602e005410310292207450d38200741026a41002d008cc5453a0000200741002f008ac5453b000041101029220b450d39200b41086a41002900f19e45370000200b41002900e99e45370000200a411936029c06200a410036029806200a4290808080800237029006200a200b36028c06200a42838080803037028406200a2007360280062006410c6a200441086a280200360200200620033602002006410036021c20062005360218200620083602142006200429020037020420062001280200360210200241146a280200210d2002411c6a280200210e20064100360238200642013703304119200641306a1047410021030340200a20036a220b2802002104200b41086a2802002207200641306a1047024002402006280234220c200628023822086b2007490d002006280230210c0c010b200820076a22012008490d41200c4101742205200120012005491b22014100480d4102400240200c0d0020011029210c0c010b2006280230200c2001102a210c0b200c450d3c200620013602342006200c3602300b2006200820076a360238200c20086a2004200710f6041a200b410c6a2802002105200b41146a280200220c200641306a10470240024020062802342208200628023822016b200c490d00200628023021070c010b2001200c6a22072001490d4120084101742204200720072004491b22044100480d410240024020080d002004102921070c010b200628023020082004102a21070b2007450d3d2006200436023420062007360230200421080b20062001200c6a2204360238200720016a2005200c10f6041a02400240200b41186a2802004101460d000240024020082004460d002008210c0c010b200841016a220c2008490d4320084101742201200c200c2001491b220c4100480d430240024020080d00200c102921070c010b20072008200c102a21070b2007450d402006200c360234200620073602300b2006200441016a2208360238200720046a41013a00002006200b411c6a280200220b360228200641286a21040c010b0240024020082004460d002008210c0c010b200841016a220c2008490d4220084101742201200c200c2001491b220c4100480d420240024020080d00200c102921070c010b20072008200c102a21070b2007450d402006200c360234200620073602300b2006200441016a2208360238200720046a41023a00002006200b411c6a280200220b360228200641286a21040b0240200c20086b41034b0d00200841046a220b2008490d41200c4101742201200b200b2001491b220b4100480d4102400240200c0d00200b102921070c010b2007200c200b102a21070b2007450d402006200b360234200620073602302004280200210b0b2006200841046a360238200720086a200b360000200341206a220341a006470d000b200628023421070240411a200d200e2006280230220420062802382006101b220b41036a220841024b0d004100210c0240024020080e03000201000b4102210c0b41012101024020070d000c450b2004102e0c440b410410292208450d402009280200220c28020041016a220141014d0d00200c20013602002008200c36020002402007450d002004102e0b200228020421042002280200210120064100360238200642013703304100200641306a104720062802382103200628023421022006280230210c410a10342207450d410240024002400240200b20012004200c20032007410a2006101c41036a220441034b0d004101210120040e0402000001020b4198a4c2001058000b2006410936022c410121012006200741016a36022820072d0000220441014b0d01410421030240024020040e020100010b200641306a200641286a10fc02200628023022034104460d02200628023421050b410021010b2007102e2002450d43200c102e0c430b2007102e024020020d000c430b200c102e0c420b00000b41044104102c000b41034101102c000b41064101102c000b41204104102c000b41034101102c000b41034101102c000b41c0004104102c000b41034101102c000b410f4101102c000b4180014104102c000b41034101102c000b410f4101102c000b41034101102c000b41084101102c000b4180024104102c000b41034101102c000b410a4101102c000b41034101102c000b410a4101102c000b41034101102c000b410a4101102c000b41034101102c000b410b4101102c000b4180044104102c000b41034101102c000b410d4101102c000b41034101102c000b410c4101102c000b41034101102c000b410b4101102c000b41034101102c000b41154101102c000b41034101102c000b410a4101102c000b41034101102c000b41074101102c000b41034101102c000b41114101102c000b41034101102c000b410e4101102c000b4180084104102c000b41034101102c000b41104101102c000b41034101102c000b41104101102c000b41034101102c000b41114101102c000b41034101102c000b41114101102c000b41034101102c000b41164101102c000b41034101102c000b41124101102c000b41034101102c000b410b4101102c000b41034101102c000b41104101102c000b20014101102c000b20044101102c000b200c4101102c000b200c4101102c000b200b4101102c000b102d000b41044104102c000b410a4101102c000b200b101d200828020022072007280200417f6a3602000240200828020022072802000d002007280208101a200828020022072007280204417f6a360204200828020022072802040d002007102e0b2008102e4102210c0b200641086a2802002108200628021421072006280204210b024002400240024002400240024002400240200628021c22040d002006410c6a290200210f20010d04200341044b0d0320030e050203030301020b2000200436020420004100360200200041106a41003a0000200041086a200641206a29030037020002402008450d00200b102e0b20072007280200417f6a220836020020080d072007280208101a20072007280204417f6a22083602042008450d060c070b2000200b3602044100210b200041106a41003a00002000410c6a4100360200200041086a20083602000c040b2000200b360204200041106a20053a00002000410c6a200f3e0200200041086a20083602004100210b0c030b200041badfc300360204200041146a200f3e0200200041106a20083602002000410c6a200b360200200041086a41113602000c010b0240200c450d00200041dbdfc300360204200041146a200f3e0200200041106a20083602002000410c6a200b360200200041086a41103602000c010b200041cbdfc300360204200041146a200f3e0200200041106a20083602002000410c6a200b360200200041086a41103602000b4101210b0b2000200b36020020072007280200417f6a220836020020080d012007280208101a20072007280204417f6a220836020420080d010b2007102e0b4100210803400240200a20086a220741046a280200450d002007280200102e0b0240200741106a280200450d002007410c6a280200102e0b200841206a220841a006470d000b200a102e200928020022072007280200417f6a3602000240200928020022072802000d002007280208101a200928020022072007280204417f6a360204200928020022072802040d002007102e0b2009102e200641c0006a24000b810101017f230041c0006b220424002004200136020c2004200036020820042003360214200420023602102004412c6a41023602002004413c6a411b3602002004420237021c2004418098c6003602182004411c3602342004200441306a3602282004200441106a3602382004200441086a360230200441186a419498c600106a000bca0201067f230041b0016b22012400200141086a200010ed01024020012903284202510d000340200128026021022001280258210302400240200128025c22040d00200321050c010b2004210620032105034020052802ec0321052006417f6a22060d000b0340200320032f01064102746a41ec036a28020021032004417f6a22040d000b0b200120023602a801200141003602a001200141003602980120014200370390012001200536028c0120014100360288012001200336029c01200120032f01063602a40120014188016a10ee01200141086a200010ed0120012903284202520d000b0b02402000280204220341e08dc000460d00200328020021042003102e2004450d00200428020021052004102e2005450d00024020052802002203450d0003402005102e2003210520032802002204210320040d000b0b2005102e0b200141b0016a24000b911208057f017e107f047e017f017e0a7f047e230041800d6b22022400024020002802000d002000417f360200200128020821032001280200210402400240200128020422050d00200421010c010b2005210620042101034020012802880b21012006417f6a22060d000b0340200420042f01064102746a41880b6a28020021042005417f6a22050d000b0b200241246a20042f0106360200200241086a41186a4100360200200241086a41146a20043602002002200336022820024100360218200242003703102002200136020c2002410036020820024180026a200241086a10ed01024020022903a00222074202510d00200041046a21082000410c6a2109200241dd026a210a200241bd026a210b200241a00a6a41146a210c200241a00a6a41206a210d20024180026a4104722101200241fd026a210e200241c8026a210f200241b0026a211020024180026a41286a21110340200241d0006a41086a220420024180026a41086a2212290300370300200241d0006a41106a220520024180026a41106a2213290300370300200241d0006a41186a220320024180026a41186a2214290300370300200241306a41086a2215200a41086a290000370300200241306a41106a2216200a41106a290000370300200241306a41186a2217200a41186a29000037030020022002290380023703502002200a290000370330200f29030021182010290300211920022903c002211a20022903a802211b20022d00dc02211c20022903b802211d20022802d002210620022802d402211e20022802d802211f2002412c6a41026a200e41026a2d000022203a00002002200e2f000022213b012c200241f8006a41086a22222015290300370300200241f8006a41106a22232016290300370300200241f8006a41186a22242017290300370300200241f4006a41026a222520203a000020022002290330370378200220213b017420024198016a41186a2221200329030037030020024198016a41106a2226200529030037030020024198016a41086a222720042903003703002002200229035037039801024002400240024002402008280200221541e08dc000460d00200028020821170c010b200241a00a6a410041e00210f5041a20024180026a410041a00810f5041a41880b10292215450d0141002117201541003b010620154100360200201541086a200241a00a6a41e00210f6041a201541e8026a20024180026a41a00810f6041a20004100360208200020153602040b034020152f01062220410574211641002104410021050240034020162004460d0120024198016a201520046a41086a412010f8042203450d04200441206a2104200541016a21052003417f4a0d000b2005417f6a21200b02402017450d002017417f6a2117201520204102746a41880b6a28020021150c010b0b200241d0016a41186a20212903002228370300200241d0016a41106a20262903002229370300200241d0016a41086a2027290300222a3703002002200229039801222b3703d001200c202b370200200c41086a202a370200200c41106a2029370200200c41186a2028370200200220093602b00a200220203602ac0a200220083602a80a200220153602a40a200241003602a00a20112018370300201320193703002002201a3703a0022002201b370388022002201c3a00bc022002201f3602b8022002201e3602b402200220063602b0022002201d370398022002200737038002200b2002290378370000200b41086a2022290300370000200b41106a2023290300370000200b41186a2024290300370000200a20022f01743b0000200a41026a20252d00003a0000200241a00a6a20024180026a104f1a0c020b41880b4108102c000b2015200541e0006c6a221741f0026a22042004290300201b20075022041b370300201741f8026a22052005290300201920041b370300201741e8026a22052005290300200720041b370300200241a00a6a41186a22032024290300370300200241a00a6a41106a22152023290300370300200241a00a6a41086a22162022290300370300200220022903783703a00a201741a4036a22052d000021202014201741bd036a22222900003703002013201741b5036a22232900003703002012201741ad036a22132900003703002002201741a5036a2224290000370380022027200241a00a6a20024180026a201c41ff0171410146221c1b220441086a2900003703002026200441106a2900003703002021200441186a2900003703002002200429000037039801200541012020201c1b3a0000202420022903980137000020132027290300370000202320262903003700002022202129030037000020174188036a2204201a2004290300201da722041b37030020174190036a22052018200529030020041b37030020174180036a2205201d200529030020041b37030002400240201e0d00200621040c010b201e210520062104034020042802ec0321042005417f6a22050d000b0340200620062f01064102746a41ec036a2802002106201e417f6a221e0d000b0b20062f010621052002201f3602b801200220053602b401200241003602b001200220063602ac01200241003602a801200242003703a0012002200436029c01200241003602980120024180026a20024198016a10ef0102402002280280024101470d0020174198036a211e0340200241a00a6a41286a200141286a280200360200200d200141206a2902003703002003200141186a22042902003703002015200141106a22052902003703002016200141086a2206290200370300200220012902003703a00a200241d0016a41186a2004290000370300200241d0016a41106a2005290000370300200241d0016a41086a2006290000370300200220012900003703d001200241f0016a41086a200d41086a2802003602002002200d2902003703f001200241c0016a201e200241d0016a200241f0016a10f501024020022802c001450d0020022802c4012204450d0020022802c801450d002004102e0b20024180026a20024198016a10ef012002280280024101460d000b0b20024198016a10ee010b20024180026a200241086a10ed0120022903a00222074202520d000b0b200241086a10542000200028020041016a360200200241800d6a24000f0b41aed9c100411020024180026a41c0d9c1001053000b8a0303027f017e037f230041c0006b22052400024002400240200241ff0171417e6a220641024b0d000240024020060e03000201000b200541106a2001107b2005290310200358200541186a290300220720045820072004511b0d010c020b200541206a2001107b2005290320200356200541286a290300220720045620072004511b0d010b200541306a2001107c0240200528023822010d0002402005280234450d002005280230102e0b410021010c020b200541086a41b0f3c200410d107d200528020c410020052802081b210820014105742106200528023421092005280230220a2101024002400240034002402008200141106a2802004f0d002001290300200358200141086a290300220720045820072004511b0d002001411c6a2d000020027141ff0171200241ff0171460d020b200141206a2101200641606a22060d000b4100210120090d010c020b41b88bc00021012009450d010b200a102e0b413121060c010b41928bc0002101412621060b2000200636020420002001360200200541c0006a24000b890602087f047e230041d00b6b220424000240024020002802000d002000417f360200200441286a41186a200141186a290000370300200441286a41106a200141106a290000370300200441286a41086a200141086a29000037030020042001290000370328024002402000280204220541e08dc000460d00200041086a28020021060c010b41002106200441f0086a410041e00210f5041a200441d0006a410041a00810f5041a41880b10292205450d02200541003b010620054100360200200541086a200441f0086a41e00210f6041a200541e8026a200441d0006a41a00810f6041a200041086a4100360200200020053602040b200041046a210702400240034020052f010622084105742109410021014100210a0240034020092001460d01200441286a200520016a41086a412010f804220b450d03200141206a2101200a41016a210a200b417f4a0d000b200a417f6a21080b02402006450d002006417f6a2106200520084102746a41880b6a28020021050c010b0b200441086a41186a200441286a41186a290300220c370300200441086a41106a200441286a41106a290300220d370300200441086a41086a200441286a41086a290300220e37030020042004290328220f3703082004418c096a200e37020020044194096a200d3702002004419c096a200c37020020042000410c6a36028009200420083602fc08200420073602f808200420053602f408200441003602f0082004200f3702840920044184016a42003702002004418c016a41003a0000200441e08dc000360280012004420037036820044200370350200441f0086a200441d0006a104f21010c010b200441e8006a4200370300200441e4006a41e08dc000360200200441003602702004410036026020044200370358200441e08dc000360254200441003602502005200a41e0006c6a41e8026a2101200441d0006a10ee010b200141106a200337030020012002370308200142013703002000200028020041016a360200200441d00b6a24000f0b41aed9c1004110200441d0006a41c0d9c1001053000b41880b4108102c000b6802017f037e230041306b22012400200029020821022000290210210320002902002104200141146a4100360200200141c8ecc50036021020014201370204200120043703182001200141186a36020020012003370328200120023703202001200141206a106a000bc40101057f230041306b220124002000410c6a28020021022000280204210302400240200041086a28020022040d00200321000c010b2004210520032100034020002802880b21002005417f6a22050d000b0340200320032f01064102746a41880b6a28020021032004417f6a22040d000b0b200141246a20032f0106360200200141206a41003602002001411c6a20033602002001200236022820014100360218200142003703102001200036020c20014100360208200141086a1054200141306a24000bf61c03027f027e087f23004180046b2207240020072004370310200720033703082007200536021c02400240024002400240200128022c200128023c22082802b801460d002005420020052903082209200841386a2903007d220a200a20095622081b37030820080d01200741d8006a200241004101105b200741fc006a280200210b200741f8006a280200210c20072d0060220841037122054103460d0220050e03030203030b2000418c84c00036020420004101360200200041086a41293602002000410c6a2006290200370200200041146a200641086a2802003602000c030b200041b584c00036020420004101360200200041086a41233602002000410c6a2006290200370200200041146a200641086a2802003602000c020b200041d884c00036020420004101360200200041086a41193602002000410c6a2006290200370200200041146a200641086a28020036020020080d01200b450d01200c102e0c010b20074180016a2802002105200741386a200141e4006a290000370300200741306a200141dc006a290000370300200741206a41086a200141d4006a2900003703002007200129004c3703204100210d024002400240024002400240200841024b0d00024020080e03000102000b2005417f4c0d020240024020050d004101210d0c010b20051029220d450d04200d200c200510f6041a0b200b450d00200c102e0b200741086a41086a2903002104200729030821030b20074190016a4100360200200741d8006a41286a419c83c000360200200741fc006a200141146a220e360200200741f4006a4200370200200741d8006a41186a41e08dc000360200200741d8006a41106a2005360200200741d8006a410c6a2005360200200741ac016a200241086a290000370200200741b4016a200241106a290000370200200741bc016a200241186a29000037020020074208370388012007410036026c2007200d360260200720022900003702a4012007200128024436029c012007200129023c370294012007200128022c41016a3602840120012903002109200720012802483602a0012007200937035820074198026a200741206a41086a290300370300200741f8016a41286a200741206a41106a290300370300200741a8026a200741206a41186a290300370300200741f8016a41146a200641086a28020036020020072002360280022007200729032037039002200720062902003702840220072007411c6a3602fc012007200741086a3602f801200741f8016a41186a210f200741f8016a410c6a2110024002400240024002400240200320048450450d00410021110c010b2007200728021c4100200f200220032004200741d8006a1050200728020022060d01200728026c211120072802800221020b201141016a220641004c0d062007200636026c200741f0006a2106200741f4006a280200210c024002400240024003402006280200220b41086a2105200b2f010622124105742106410021080240024003402006450d0120022005412010f804220d450d02200641606a2106200841016a2108200541206a2105200d417f4a0d000b2008417f6a21120b200c450d02200c417f6a210c200b20124102746a41880b6a21060c010b0b200741a8036a2205200b200841e0006c6a220641ad036a290000370300200741b0036a2208200641b5036a290000370300200741b8036a220d200641bd036a2900003703002007200641a5036a2900003703a003200641a4036a2d00004101470d00200741b9026a2005290300370000200741c1026a2008290300370000200741c9026a200d290300370000200741013a00b002200720072903a0033700b1022007201136026c0c010b200741b0026a200728027c20022007280280012802101103002007200728026c417f6a36026c20072d00b0024101470d010b200741d8026a41186a200741c9026a290000370300200741d8026a41106a200741c1026a290000370300200741d8026a41086a200741b9026a290000370300200720072900b1023703d802200741a0036a200741d8026a200728029c012802001051024020072802a0034101470d0020072902a4032103200741ec016a2010290200370200200741f4016a201041086a280200360200200720033702e401200741013602e001200741e0016a41047221060c040b200741e0036a41186a2205200741a0036a410472220641186a2802002208360200200741f8026a41106a200641086a290200370300200741f8026a41186a220d200641106a29020037030020074198036a2008360200200741043602fc02200741ada4c5003602f802200720062902003703800320072802980121062005200f41186a2900002203370300200741e0036a41106a200f41106a2900002204370300200741e0036a41086a2205200f41086a2900002209370300200741c8036a2009370300200741d0036a2004370300200741d8036a20033703002007200f29000022033703e003200720033703c00320072802f801220841086a29030021032007200741d8006a3602b803200829030021042007290358210920072802a0012108200720033703a803200720043703a003200720083602bc03200720093703b0032005201041086a280200360200200720102902003703e003200741e0016a2006200741f8026a200741a0036a200741e0036a20072802fc0128020010520240200d280200450d002007418c036a280200102e0b200741d8016a200741ec016a280200360200200741ce016a200741f3016a2d00003a0000200720072902e4013703d001200720072f00f1013b01cc01200741f0016a2d0000210520072802e0014101470d01200741f4016a28020021060c040b200741e0016a41086a420037030041002105200741e0016a41106a220841003a000020074280808080103703e001200741e0016a41047221060240200741f8016a41106a280200450d00200728028402102e20082d000021050b200741d0016a41086a200641086a280200360200200741ce016a200741f3016a2d00003a0000200720072f00f1013b01cc01200720062902003703d0010b200741c8006a41086a2202200741d0016a41086a280200360200200741c4006a41026a2212200741cc016a41026a2d00003a0000200720072903d001370348200720072f01cc013b01442007280290012108200728028c01210c200728028801210b200728027821102007280274210d2007280270210602402007280260220f450d002007280264450d00200f102e0b200741a0036a41086a2002280200360200200741f8016a41026a20122d00003a0000200720072903483703a003200720072f01443b01f801200541ff0171450d03200020072903a003370204200020072f01f8013b0011200041106a20053a00002000410c6a200741a0036a41086a280200360200200041136a200741fa016a2d00003a000002402008450d00200841b0016c210141002105034002400240200b20056a22082d0000220241014b0d000240024020020e020001000b0240200841086a280200450d00200841046a280200102e0b200841106a2d00004105490d02200841386a280200450d02200841346a280200102e0c020b200841286a102f0c010b200841e8006a280200450d00200841e4006a280200102e0b2001200541b0016a2205470d000b0b0240200c450d00200b102e0b02400240200d0d00200621050c010b200d210820062105034020052802880b21052008417f6a22080d000b0340200620062f01064102746a41880b6a2802002106200d417f6a220d0d000b0b200741f4006a20062f0106360200200741f0006a4100360200200741ec006a20063602002007201036027820074100360268200742003703602007200536025c20074100360258200741d8006a10540c070b200741e0016a41086a2007280204360200200741ec016a2010290200370200200741f4016a201041086a280200360200200720063602e401200741013602e001200741e0016a41047221060b200741d0016a41086a200641086a280200360200200741ce016a2006410f6a2d00003a0000200720062902003703d001200720062f000d3b01cc01200741f0016a2d00002105200741f4016a28020021060b200020072903d001370204200020072f01cc013b001120004101360200200041106a20053a0000200041146a20063602002000410c6a200741d8016a280200360200200041136a200741ce016a2d00003a0000024020072802602206450d002007280264450d002006102e0b200741d8006a41186a28020021062007280278210d02400240200728027422050d00200621080c010b2005210020062108034020082802880b21082000417f6a22000d000b0340200620062f01064102746a41880b6a28020021062005417f6a22050d000b0b200741bc036a20062f010636020041002105200741a0036a41186a4100360200200741b4036a20063602002007200d3602c003200741003602b003200742003703a803200720083602a403200741003602a003200741a0036a105402402007280290012206450d002007280288012100200641b0016c210d034002400240200020056a22062d0000220841014b0d000240024020080e020001000b0240200641086a280200450d00200641046a280200102e0b200641106a2d00004105490d02200641386a280200450d02200641346a280200102e0c020b200641286a102f0c010b200641e8006a280200450d00200641e4006a280200102e0b200d200541b0016a2205470d000b0b200728028c01450d05200728028801102e0c050b200720103602602007200d36025c20072006360258200e200741d8006a10552007200b200841b0016c6a3602642007200b3602602007200c36025c2007200b360258200141306a200741d8006a10282000410c6a200741a8036a280200360200200020072903a003370204200041106a41003a0000200020072f01f8013b0011200041136a200741fa016a2d00003a00000c030b1032000b20054101102c000b41e3d7c1004118200741f8026a41fcd7c1001053000b200041003602000b20074180046a24000bef1704057f027e0b7f077e23004180036b22042400200441e0006a200110af010240024020042d00602205417f6a41ff017141024f0d00200041003a0000200041086a200441e0006a41d80010f6041a0c010b200441b8016a41086a2206200441e0006a413c6a290200370300200441b8016a41106a2207200441e0006a41c4006a290200370300200441b8016a41186a2208200441e0006a41cc006a2902003703002004200441e0006a41346a2902003703b801200441e0006a41106a2903002109200441e0006a41086a290300210a200441e0006a41306a280200210b200441e0006a412c6a280200210c200441e0006a41246a280200210d200441e0006a41206a280200210e200441fc006a280200210f200441e0006a41186a2802002110200441e0006a41d4006a2802002111200441e0006a41286a2802002112200441d8006a41b0f3c200410d107d0240024002400240024002400240024002400240024041004100200428025c410020042802581b221320026b2202200220134b1b220220126b2214201420024b1b2215450d00411410292202450d02200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020044294808080c0023702fc01200420023602f8012001200441f8016a104a20042802fc012102200441c0006a20042802f8012206200428028002106e200441c0006a41106a2903004200200428024022141b21162004290348420020141b211702402002450d002006102e0b200441306a2017201642e807420010fc044200200dad2218200429033022197d221a201a2018564200200441306a41086a2903002018201954ad7c7d22184200522018501b22021b22194200201820021b221884500d0302400240024002402017429080e983b1de165441002016501b0d00200441186a201942028620184202862019423e88842015ad420010fb04200441286a2001410842002017201742f0ff96fccea1697c2218200a200a201856200920162018201754ad7c427f7c22185620092018511b22021b22192004290318221a2019201a542018200920021b2219200441186a41086a29030022185420192018511b22021b221b7d221c201c20175620162019201820021b22197d2017201b54ad7d221720165620172016511b22141b4200201720141b105620042802280d010240024020020d002003450d010b200441f8016a2001201b20194108107a20042802f8014101460d0a200441f8016a41106a2903002119200441f8016a41086a2214290300211720144200370300200442003703f80141c28cc0004116200441f8016a1003200441d0026a41086a22072014290300370300200420042903f8013703d0022004200441d0026a109701200441106a29030021162004290308211b2004280200210620144200370300200442003703f80141c28cc0004116200441f8016a100320072014290300370300200420042903f8013703d002200442002016420020061b221620197d201b420020061b2219201754ad7d221b201920177d2217201956201b201656201b2016511b22141b3703800220044200201720141b3703f801200441d0026a4110200441f8016a411010040b20020d0120030d03200041003a0008200041023a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903b801370000200041c4006a200441c0016a290300370000200041cc006a200441b8016a41106a290300370000200041d4006a200441b8016a41186a290300370000200041dc006a2011360000200541037122004103460d0520000e030f05050f0b411710292202450d07200241002900b0a5433700002002410f6a41002900bfa543370000200241086a41002900b8a54337000020044297808080f0023702fc01200420023602f8012001200441f8016a104a20042802fc012102200428028002211220042802f8012101200441f8016a41186a220d4200370300200441f8016a41106a22034200370300200441f8016a41086a22134200370300200442003703f80120012012200441f8016a1000200441d0026a41186a200d290300370300200441d0026a41106a2003290300370300200441d0026a41086a2013290300370300200420042903f8013703d002200441d0026a4120100602402002450d002001102e0b2010200e1007200041023a0008200041013a00000c010b200441003602f8012010200e200441f8016a100a211420042802f8012213417f460d08200441d0026a41186a200441b8016a41186a290300370300200441d0026a41106a200441b8016a41106a290300370300200441d0026a41086a200441b8016a41086a290300370300200420042903b8013703d002200441003602f802200442013703f00220142013200441f0026a10b0010240024020042802f402220320042802f802220d6b4120490d00200d41206a211220042802f00221020c010b200d41206a2212200d490d0b20034101742202201220122002491b220b4100480d0b0240024020030d00200b102921020c010b20042802f0022003200b102a21020b2002450d0a2004200b3602f402200420023602f002200b21030b200420123602f8022002200d6a220d20042903d002370000200d41086a200441d0026a41086a290300370000200d41106a200441d0026a41106a290300370000200d41186a200441d0026a41186a290300370000200441f8016a41186a220d4200370300200441f8016a41106a220b4200370300200441f8016a41086a220c4200370300200442003703f80120022012200441f8016a1000200441d8016a41186a2212200d290300370300200441d8016a41106a220d200b290300370300200441d8016a41086a220b200c290300370300200420042903f8013703d80102402003450d002002102e0b20044191026a201229030037000020044189026a200d29030037000020044181026a200b290300370000200420042903d8013700f901200441013a00f8012001200441f8016a10b1012010200e1007200041013a0000200041086a200441f8016a41d80010f6041a2013450d002014102e0b200f450d0a2010102e0c0a0b200441a8026a200b360200200441a4026a200c360200200441a0026a20133602002004419c026a200d36020020044198026a200e36020020044194026a200f360200200441f8016a41186a2010360200200441ac026a20042903b801370200200441b4026a200441b8016a41086a290300370200200441bc026a200441b8016a41106a290300370200200441c4026a200441b8016a41186a290300370200200441f8016a41106a200920187d200a201a54ad7d370300200441003a00f8012004200a201a7d370380022001200441f8016a10b101200041023a0000200041086a200441f8016a41d80010f6041a0c090b200041003a0008200041003a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903b801370000200041c4006a2006290300370000200041cc006a2007290300370000200041d4006a2008290300370000200041dc006a20113600000c080b200f450d090c080b41144101102c000b200041003a0008200041003a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903b801370000200041c4006a200441c0016a290300370000200041cc006a200441b8016a41106a290300370000200041d4006a200441b8016a41186a290300370000200041dc006a20113600000c050b41174101102c000b200420042902fc013703d00241fbecc00041fe00200441d0026a41fcedc0001053000b41c0e6c5004138109b01000b200b4101102c000b102d000b0240200541037122004103460d0020000e03020000020b200f450d010b2010102e0b20044180036a24000bde0d03047f017e027f230041106b2202240020024100360208200242013703000240024002400240024002400240024002400240024002400240024002402001280200220341044b0d000240024002400240024020030e050001020304000b410110292203450d05200242818080801037020420022003360200200341013a0000200128020421042001410c6a28020022032002104702402003450d002004200341286c6a2105034020042002104a200441206a29030021060240024020022802042207200228020822036b4108490d00200228020021070c010b200341086a22082003490d1520074101742203200820082003491b22034100480d150240024020070d002003102921070c010b200228020020072003102a21070b2007450d092002200336020420022007360200200228020821030b2002200341086a360208200720036a20063700002005200441286a2204470d000b0b200141106a28020021070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d1320044101742203200820082003491b22034100480d130240024020040d002003102921040c010b200228020020042003102a21040b2004450d082002200336020420022004360200200228020821030b2002200341046a360208200420036a20073600000c040b410110292203450d07200242818080801037020420022003360200200341023a0000200128020421070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d1220044101742205200820082005491b22084100480d120240024020040d002008102921040c010b200228020020042008102a21040b2004450d0920022008360204200220043602000b2002200341046a360208200420036a200736000020012802082104200141106a28020022032002104702402003450d002004200341286c6a2105034020042002104a200441206a29030021060240024020022802042207200228020822036b4108490d00200228020021070c010b200341086a22082003490d1420074101742203200820082003491b22034100480d140240024020070d002003102921070c010b200228020020072003102a21070b2007450d0c2002200336020420022007360200200228020821030b2002200341086a360208200720036a20063700002005200441286a2204470d000b0b200141146a28020021070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d1220044101742203200820082003491b22034100480d120240024020040d002003102921040c010b200228020020042003102a21040b2004450d0b2002200336020420022004360200200228020821030b2002200341046a360208200420036a20073600000c030b410110292203450d0a200242818080801037020420022003360200200341033a0000200141086a29030021060240024020022802042207200228020822036b4108490d00200341086a2104200228020021070c010b200341086a22042003490d1120074101742208200420042008491b22084100480d110240024020070d002008102921070c010b200228020020072008102a21070b2007450d0c20022008360204200220073602000b20022004360208200720036a20063700000c020b410110292203450d0b200242818080801037020420022003360200200341043a0000200128020421070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d1020044101742201200820082001491b22084100480d100240024020040d002008102921040c010b200228020020042008102a21040b2004450d0d20022008360204200220043602000b2002200341046a360208200420036a20073600000c010b410110292203450d0c200242818080801037020420022003360200200341053a0000200128020421080240024020022802042207200228020822036b4104490d00200341046a2104200228020021070c010b200341046a22042003490d0f20074101742201200420042001491b22014100480d0f0240024020070d002001102921070c010b200228020020072001102a21070b2007450d0e20022001360204200220073602000b20022004360208200720036a20083600000b20002002290300370200200041086a200241086a280200360200200241106a24000f0b41014101102c000b20034101102c000b20034101102c000b41014101102c000b20084101102c000b20034101102c000b20034101102c000b41014101102c000b20084101102c000b41014101102c000b20084101102c000b41014101102c000b20014101102c000b102d000bb01405167f017e017f027e037f230041206b220224000240024020014115490d0002402001410176220341ffffff3f712003470d0020034105742204417f4c0d0041012105024002402004450d00200410292205450d010b200041606a2106200041a07f6a210741042108410021094100210a2001210b034002400240200b220c417f6a220d0d004101210e4100210b0c010b0240024002400240024002402000200d4105746a200c410574220f20006a41406a412010f8044100480d004102200c6b210d2007200f6a21044101210e03400240200d200e6a4101470d004100210b200c210e0c080b200e41016a210e200441206a2004412010f8042110200441606a21042010417f4a0d000b200c200e6b210d0c010b2007200f6a2104024003400240200d4101470d004100210d0c020b200d417f6a210d200441206a2004412010f8042110200441606a210420104100480d000b0b200c200d490d01200c20014b0d03200c200d6b220e4101762211450d002006200f6a21042000200d4105746a21100340200241186a220f201041186a2212290000370300200241106a2213201041106a2214290000370300200241086a2215201041086a221629000037030020022010290000370300200441086a22172900002118200441106a2219290000211a200441186a220b290000211b201020042900003700002012201b3700002014201a37000020162018370000200b200f290300370000201920132903003700002017201529030037000020042002290300370000200441606a2104201041206a21102011417f6a22110d000b0b0240200d0d00200d210b0c050b0240200e41094d0d00200d210b0c050b200c20014b0d01200c200d6b21112000200d4105746a210f0340200c200d417f6a220b490d040240200c200b6b220e4102490d002000200d4105746a22042000200b4105746a220d412010f804417f4a0d00200d2900002118200d2004290000370000200241186a2215200d41186a2210290000370300200241106a2216200d41106a2212290000370300200241086a2217200d41086a22132900003703002013200441086a2900003700002012200441106a2900003700002010200441186a29000037000020022018370300410121140240200e4103490d00200d41c0006a2002412010f804417f4a0d0041022110200f210402400340200441186a200441386a290000370000200441106a200441306a290000370000200441086a200441286a2900003700002004200441206a221229000037000020112010460d01200441c0006a21132010211420122104201041016a211020132002412010f804417f4a0d020c000b0b201021140b200d20144105746a22042002290300370000200441186a2015290300370000200441106a2016290300370000200441086a20172903003700000b200b450d05200f41606a210f201141016a2111200b210d200e410a4f0d050c000b0b200d200c1035000b200c200d417f6a220b490d010b200c2001105e000b200b200c1035000b0240024002402009200a470d0002400240200941016a22042009490d0020094101742210200420042010491b220441ffffffff01712004470d002004410374221041004e0d010b102d000b0240024020090d002010102921080c010b200820094103742010102a21080b2008450d01200421090b2008200a4103746a2204200e3602042004200b360200200a41016a2215210a20154102490d0103400240024002400240200820152213417f6a22154103746a2204280200450d00201341037420086a221141746a280200220e200428020422104d0d004102210a201341024d0d0620082013417d6a22044103746a280204220d2010200e6a4d0d014103210a201341034d0d06201141646a280200200d200e6a4d0d012013210a0c060b20134103490d012004280204211020082013417d6a22044103746a280204210d0b200d2010490d010b2013417e6a21040b0240024002400240024002402013200441016a221c4d0d00201320044d0d01200820044103746a2216280204221d20162802006a22042008201c4103746a22172802002219490d02200420014b0d03201641046a211e200020194105746a22122017280204221441057422106a210e2004410574210d200420196b220a20146b220420144f0d042005200e2004410574221010f604220f20106a21110240024020144101480d00200441014e0d010b200e2104200f21100c060b2006200d6a210d200e21040340200d200441606a220e201141606a220a200a200e412010f804410048220c1b2210290000370000200d41186a201041186a290000370000200d41106a201041106a290000370000200d41086a201041086a2900003700002011200a200c1b211102402012200e2004200c1b2204490d00200f21100c070b200d41606a210d200f2110200f2011490d000c060b0b41f484c000201c20131038000b41f484c000200420131038000b201920041035000b20042001105e000b20052012201010f604220f20106a21110240024020144101480d00200a20144a0d010b20122104200f21100c010b2000200d6a210c200f21102012210403402004200e2010200e2010412010f804410048220a1b220d290000370000200441186a200d41186a290000370000200441106a200d41106a290000370000200441086a200d41086a2900003700002010201041206a200a1b2110200441206a2104200e41206a200e200a1b220e200c4f0d01201120104b0d000b0b20042010201120106b41607110f6041a201e201d20146a360200201620193602002017201741086a201c417f7320136a41037410f7041a2015210a201541014d0d020c000b0b20104104102c000b200b0d000b02402009450d002008102e0b2003450d032005102e0c030b20044101102c000b1032000b20014102490d002001417f6a2110200141057420006a41206a210c410121110340024002400240024020102204417f6a221020014b0d00200120106b220d4102490d03200020044105746a2204200020104105746a220a412010f804417f4a0d03200a2900002118200a2004290000370000200241186a2212200a41186a220e290000370300200241106a2213200a41106a220f290000370300200241086a2214200a41086a22082900003703002008200441086a290000370000200f200441106a290000370000200e200441186a2900003700002002201837030041012104200d4103490d02200a41c0006a2002412010f804417f4a0d024100210f200c21040340200441406a220d200441606a220e290000370000200d41186a200e41186a290000370000200d41106a200e41106a290000370000200d41086a200e41086a2900003700002011200f220d460d02200d417f6a210f20042002412010f804210e200441206a2104200e417f4a0d020c000b0b201020011035000b4102200d6b21040b200a20044105746a22042002290300370000200441186a2012290300370000200441106a2013290300370000200441086a20142903003700000b200c41606a210c2011417f6a211120100d000b0b200241206a24000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420237020c200241d4eec500360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41e4eec500106a000bdd2003167f037e067f230041c0026b220524000240024020014115490d004101210641012107024002400240034020012108200021092006200771210a024002400240024002400240034002400240024002402004450d00024020064101710d002000200110602004417f6a21040b2001410276220b41036c210c200b410174210d4100210e024020014132490d00200b200b417f6a220e2000200b4105746a2000200e4105746a412010f804220f41004822101b2211200b41016a2212200e200b20101b220b200020124105746a2000200b4105746a412010f80441004822121b220b2000200b4105746a200020114105746a412010f80422114100481b210b200d200d417f6a220e2000200d4105746a2000200e4105746a412010f804221341004822141b2215200d4101722216200e200d20141b220d200020164105746a2000200d4105746a412010f80422144100481b220d2000200d4105746a200020154105746a412010f80422154100481b210d200c200c417f6a220e2000200c4105746a2000200e4105746a412010f804221641004822171b2218200c41016a2219200e200c20171b220c200020194105746a2000200c4105746a412010f804220e4100481b220c2000200c4105746a200020184105746a412010f80422174100481b210c4102410120101b200f411f7620121b2011411f766a2013411f766a2014411f766a2015411f766a2016411f766a200e411f766a2017411f766a210e0b2000200d4105746a2000200b4105746a412010f8042210411f76200e6a2000200c4105746a2000200b200d201041004822101b220f4105746a412010f8042211411f766a210e2000200c200f20114100481b220c4105746a2000200d200b20101b221a4105746a412010f804417f4c0d01200c211a0c020b2000200110610c0f0b200e41016a220e410c490d0002402001410176220c450d00200020014105746a41606a210b2000210d0340200541206a41186a220e200d41186a2210290000370300200541206a41106a220f200d41106a2211290000370300200541206a41086a2212200d41086a22132900003703002005200d290000370320200b41086a2214290000211b200b41106a2215290000211c200b41186a2216290000211d200d200b2900003700002010201d3700002011201c3700002013201b3700002016200e2903003700002015200f29030037000020142012290300370000200b2005290320370000200b41606a210b200d41206a210d200c417f6a220c0d000b0b2001201a417f736a211a4101210b0c010b200e45210b0b0240200a417f73200b45724101710d002000200110620d0d0b2003450d02201a20014f0d01024020032000201a4105746a220b412010f80441004e0d0020002109200121080c040b200541206a41186a2213200041186a220f290000370300200541206a41106a2214200041106a2211290000370300200541206a41086a2215200041086a221229000037030020052000290000370320200b41086a220d290000211b200b41106a220c290000211c200b41186a220e290000211d2000200b290000370000200f201d3700002011201c3700002012201b370000200e2013290300370000200c2014290300370000200d2015290300370000200b2005290320370000200541c0016a41186a2218200f290000370300200541c0016a41106a22192011290000370300200541c0016a41086a221a2012290000370300200520002900003703c001200041606a2116200041206a21174100210d2001210c03400240200d200c417f6a220e4f0d002017200d4105746a210b0340200541c0016a200b412010f804417f4c0d01200b41206a210b200e200d41016a220d470d000b200e210d0b2016200c4105746a210b02400340200d200c417f6a220c4f0d01200541c0016a200b412010f804210e200b41606a2210210b200e4100480d000b20132017200d4105746a220b41186a220e2900003703002014200b41106a221e2900003703002015200b41086a22072900003703002005200b290000370320201041286a221f290000211b201041306a2220290000211c201041386a2221290000211d200b201041206a2210290000370000200e201d370000201e201c3700002007201b3700002021201329030037000020202014290300370000201f201529030037000020102005290320370000200d41016a210d0c010b0b200020052903c001370000200f2018290300370000201120192903003700002012201a29030037000002402001200d41016a220b490d002000200b4105746a21002001200b6b220141154f0d010c0c0b0b200b20011035000b419086c000201a20011038000b2008450d010b201a20084f0d01200541206a41186a2217200941186a221f290000370300200541206a41106a2218200941106a2220290000370300200541206a41086a2219200941086a2221290000370300200520092900003703202009201a4105746a220b41086a220d290000211b200b41106a220c290000211c200b41186a220e290000211d2009200b290000370000201f201d3700002020201c3700002021201b370000200e2017290300370000200c2018290300370000200d2019290300370000200b2005290320370000200541186a2206201f290000370300200541106a220a2020290000370300200541086a2222202129000037030020052009290000370300200941206a21014100211e2008417f6a220e450d022001210b0340200b2005412010f80441004e0d03200b41206a210b200e201e41016a221e470d000b200e211e0c020b41d885c000410041001038000b41e885c000201a20081038000b200920084105746a210d200e210c02400340200d2100200c220b201e4d22070d01200b417f6a210c200041606a220d2005412010f804417f4a0d000b0b0240200b201e490d00200e200b490d02418001211541002110410021134100210e4100211241800121162001201e4105746a2223210103400240200020016b220b419fc0004b221a0d00200b410576220b41807f6a200b20132010492012200e49220d72220c1b210b0240200c450d002016200b200d1b2116200b2015200d1b21150c010b200b200b41017622166b21150b02402012200e470d00024020160d00200541c0006a220e21120c010b4100210b200541c0006a2212210e2001210d0340200e200b3a0000200e200d2005412010f804417f73411f766a210e200d41206a210d2016200b41016a220b470d000b0b024020132010470d00024020150d00200541c0016a221021130c010b200041606a210b4100210d200541c0016a2213211003402010200d3a00002010200b2005412010f804411f766a2110200b41606a210b2015200d41016a220d470d000b0b0240201020136b220b200e20126b220d200d200b4b1b2214450d002017200120122d00004105746a220b41186a2900003703002018200b41106a2900003703002019200b41086a2900003703002005200b290000370320200120122d00004105746a220b200020132d0000417f734105746a220d290000370000200b41186a200d41186a290000370000200b41106a200d41106a290000370000200b41086a200d41086a290000370000024020144101460d004100210b034020002013200b6a220f2d0000417f734105746a220d20012012200b6a41016a22112d00004105746a220c290000370000200d41186a200c41186a290000370000200d41106a200c41106a290000370000200d41086a200c41086a290000370000200120112d00004105746a220d2000200f41016a2d0000417f734105746a220c290000370000200d41186a200c41186a290000370000200d41106a200c41106a290000370000200d41086a200c41086a290000370000200b41026a210d200b41016a220c210b200d2014490d000b2013200c6a21132012200c6a21120b200020132d0000417f734105746a220b2005290320370000200b41186a2017290300370000200b41106a2018290300370000200b41086a2019290300370000201341016a2113201241016a21120b200020154105746b200020132010461b2100200120164105746a20012012200e461b2101201a0d000b024002402012200e4f0d002000210b034020172001200e417f6a220e2d00004105746a220d41186a220c2900003703002018200d41106a22102900003703002019200d41086a22002900003703002005200d290000370320200b41606a220b41086a220f290000211b200b41106a2211290000211c200b41186a2213290000211d200d200b290000370000200c201d3700002010201c3700002000201b3700002013201729030037000020112018290300370000200f2019290300370000200b20052903203700002012200e490d000c020b0b2001210b201320104f0d0003402010417f6a22102d0000210d2017200b41186a220c2900003703002018200b41106a220e2900003703002019200b41086a22012900003703002005200b2900003703202000200d417f734105746a220d41086a220f290000211b200d41106a2211290000211c200d41186a2212290000211d200b200d290000370000200c201d370000200e201c3700002001201b3700002012201729030037000020112018290300370000200f2019290300370000200d2005290320370000200b41206a210b20132010490d000b0b20092005290300370000201f20062903003700002020200a290300370000202120222903003700002008200b20236b410576201e6a22014d0d032017201f290000370300201820202900003703002019202129000037030020052009290000370320200920014105746a220b41086a220d290000211b200b41106a220c290000211c200b41186a220e290000211d2009200b290000370000201f201d3700002020201c3700002021201b370000200e2017290300370000200c2018290300370000200d2019290300370000200b2005290320370000200820016b220d450d04200d20012001200d4b1b210c2008410376210e200b41206a2100024002402001200d417f6a220d490d002000200d2002200b2004105f200921000c010b20092001200220032004105f200b2103200d21010b200c200e4f2106200141154f0d010c050b0b201e200b1035000b200b200e105e000b41e885c000200120081038000b41f885c0001058000b20014102490d00200041606a21104101210c0340200c410574210b200c417f6a210d200c41016a210c02402000200b6a220b2000200d4105746a220e412010f804417f4a0d00200541c0016a41186a220f200b41186a2211290000370300200541c0016a41106a2212200b41106a2213290000370300200541c0016a41086a2214200b41086a22152900003703002005200b2900003703c001200b200e2900003700002015200e41086a2900003700002013200e41106a2900003700002011200e41186a2900003700004100210e0240200d450d002010210b03400240200541c0016a200b412010f8044100480d00200d210e0c020b200b41206a200b290000370000200b41386a200b41186a290000370000200b41306a200b41106a290000370000200b41286a200b41086a290000370000200b41606a210b200d417f6a220d0d000b0b2000200e4105746a220b20052903c001370000200b41186a200f290300370000200b41106a2012290300370000200b41086a20142903003700000b201041206a2110200c2001470d000b0b200541c0026a24000beb050a067f017e017f017e017f017e017f017e017f017e230041206b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200020044105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c37000020052008370000024020032001490d00200321040c030b2006410d7420067322054111762005732205410574200573220620077122054100200120052001491b6b220520014f0d01200020034105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c370000200520083700002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200020044105746a22012900002108200020054105746a220041086a2205290000210a200041106a2204290000210c200041186a2203290000210e20012000290000370000200141186a220629000021102006200e370000200141106a2206290000210e2006200c370000200141086a2201290000210c2001200a370000200320103700002004200e3700002005200c370000200020083700000b200241206a24000f0b41e885c000200520011038000b41d885c000200420011038000be90609067f017e017f017e017f027e017f017e027f230041206b22022400024020014101762203450d0003402003417f6a2203210402400240024003402004410174220541017221060240200541026a220520014f0d00200620014f0d0220052006200020064105746a200020054105746a412010f8044100481b21060b200620014f0d03200420014f0d02200020044105746a2204200020064105746a2205412010f804417f4a0d03200541086a22072900002108200541106a2209290000210a200541186a220b290000210c2004290000210d20042005290000370000200441186a220e290000210f200e200c370000200441106a220e290000210c200e200a370000200441086a2204290000210a20042008370000200b200f3700002009200c3700002007200a3700002005200d370000200621040c000b0b41d887c000200620011038000b41e887c000200420011038000b20030d000b0b0240024020014102490d002001210703402007417f6a220720014f0d02200241186a2209200041186a2204290000370300200241106a220b200041106a2205290000370300200241086a220e200041086a2203290000370300200020074105746a220641086a2900002108200641106a290000210a200641186a290000210c2000290000210d200020062900003700002004200c3700002005200a370000200320083700002002200d37030041002105024002400240034020062002290300370000200641186a2009290300370000200641106a200b290300370000200641086a200e2903003700002005410174220641017221040240200641026a220620074f0d00200420074f0d0220062004200020044105746a200020064105746a412010f8044100481b21040b200420074f0d03200520074f0d02200020054105746a2205200020044105746a2206412010f804417f4a0d032009200541186a2203290000370300200b200541106a2210290000370300200e200541086a2211290000370300200641086a2900002108200641106a290000210a200641186a290000210c2005290000210d200520062900003700002003200c3700002010200a370000201120083700002002200d370300200421050c000b0b41d887c000200420071038000b41e887c000200520071038000b200741014b0d000b0b200241206a24000f0b41e885c000200720011038000bdb08030a7f017e0a7f230041c0006b22022400200041a07f6a21032001417f6a2104200141324921054101210641002107024003400240024020062001490d00410021080c010b41012108200020064105746a2209200941606a412010f8044100480d0003404101210a20042006460d03200641016a2106200941206a220a2009412010f8042108200a21092008417f4a0d000b200620014921080b2006200146210a20050d0120062001460d0102400240024002402006417f6a220920014f0d002008450d0120002006410574220b6a220a290000210c200a200020094105746a22092900003700002009200c370000200a41086a220d290000210c200d200941086a220e290000370000200e200c370000200a41106a220f290000210c200f200941106a22102900003700002010200c370000200a41186a2211290000210c2011200941186a22122900003700002012200c37000020064102490d03200920002006417e6a22084105746a2213412010f804417f4a0d032009290000210c20092013290000370000200241206a41186a22142012290000370300200241206a41106a22152010290000370300200241206a41086a2216200e290000370300200e201341086a2900003700002010201341106a2900003700002012201341186a2900003700002002200c3703204100210e2008450d022003200b6a210903400240200241206a2009412010f8044100480d002008210e0c040b200941206a2009290000370000200941386a200941186a290000370000200941306a200941106a290000370000200941286a200941086a290000370000200941606a21092008417f6a22080d000c030b0b41d885c000200920011038000b41e885c000200620011038000b2000200e4105746a22092002290320370000200941186a2014290300370000200941106a2015290300370000200941086a20162903003700000b200741016a21070240200120066b22104102490d00200a41206a2209200a412010f804417f4a0d00200a290000210c200a2009290000370000200241206a41186a22122011290000370300200241206a41106a2213200f290000370300200241206a41086a220b200d290000370300200d200941086a290000370000200f200941106a2900003700002011200941186a2900003700002002200c3703204101210d024020104103490d00200a41c0006a200241206a412010f804417f4a0d00410321084102210e0340200a200e4105746a220941606a220d2009290000370000200d41186a200941186a290000370000200d41106a200941106a290000370000200d41086a200941086a290000370000024020082010490d00200e210d0c020b20084105742109200e210d2008210e200841016a2108200a20096a200241206a412010f8044100480d000b0b200a200d4105746a22092002290320370000200941186a2012290300370000200941106a2013290300370000200941086a200b2903003700000b20074105470d000b4100210a0b200241c0006a2400200a0bd92003167f037e067f230041c0026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006712109024002400240024002400240034002400240024002402003450d00024020054101710d002000200110602003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00200a200a417f6a220d2000200a4105746a2000200d4105746a412010f804220e410048220f1b2210200a41016a2211200d200a200f1b220a200020114105746a2000200a4105746a412010f80441004822111b220a2000200a4105746a200020104105746a412010f80422104100481b210a200c200c417f6a220d2000200c4105746a2000200d4105746a412010f804221241004822131b2214200c4101722215200d200c20131b220c200020154105746a2000200c4105746a412010f80422134100481b220c2000200c4105746a200020144105746a412010f80422144100481b210c200b200b417f6a220d2000200b4105746a2000200d4105746a412010f804221541004822161b2217200b41016a2218200d200b20161b220b200020184105746a2000200b4105746a412010f804220d4100481b220b2000200b4105746a200020174105746a412010f80422164100481b210b41024101200f1b200e411f7620111b2010411f766a2012411f766a2013411f766a2014411f766a2015411f766a200d411f766a2016411f766a210d0b2000200c4105746a2000200a4105746a412010f804220f411f76200d6a2000200b4105746a2000200a200c200f410048220f1b220e4105746a412010f8042210411f766a210d2000200b200e20104100481b220b4105746a2000200c200a200f1b22194105746a412010f804417f4c0d01200b21190c020b2000200110610c0f0b200d41016a220d410c490d0002402001410176220b450d00200020014105746a41606a210a2000210c0340200441206a41186a220d200c41186a220f290000370300200441206a41106a220e200c41106a2210290000370300200441206a41086a2211200c41086a22122900003703002004200c290000370320200a41086a2213290000211a200a41106a2214290000211b200a41186a2215290000211c200c200a290000370000200f201c3700002010201b3700002012201a3700002015200d2903003700002014200e29030037000020132011290300370000200a2004290320370000200a41606a210a200c41206a210c200b417f6a220b0d000b0b20012019417f736a21194101210a0c010b200d45210a0b02402009417f73200a45724101710d002000200110620d0d0b2002450d02201920014f0d0102402002200020194105746a220a412010f80441004e0d0020002108200121070c040b200441206a41186a2212200041186a220e290000370300200441206a41106a2213200041106a2210290000370300200441206a41086a2214200041086a221129000037030020042000290000370320200a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2000200a290000370000200e201c3700002010201b3700002011201a370000200d2012290300370000200b2013290300370000200c2014290300370000200a2004290320370000200441c0016a41186a2217200e290000370300200441c0016a41106a22182010290000370300200441c0016a41086a22192011290000370300200420002900003703c001200041606a2115200041206a21164100210c2001210b03400240200c200b417f6a220d4f0d002016200c4105746a210a0340200441c0016a200a412010f804417f4c0d01200a41206a210a200d200c41016a220c470d000b200d210c0b2015200b4105746a210a02400340200c200b417f6a220b4f0d01200441c0016a200a412010f804210d200a41606a220f210a200d4100480d000b20122016200c4105746a220a41186a220d2900003703002013200a41106a221d2900003703002014200a41086a22062900003703002004200a290000370320200f41286a221e290000211a200f41306a221f290000211b200f41386a2220290000211c200a200f41206a220f290000370000200d201c370000201d201b3700002006201a37000020202012290300370000201f2013290300370000201e2014290300370000200f2004290320370000200c41016a210c0c010b0b200020042903c001370000200e2017290300370000201020182903003700002011201929030037000002402001200c41016a220a490d002000200a4105746a21002001200a6b220141154f0d010c0c0b0b200a20011035000b419086c000201920011038000b2007450d010b201920074f0d01200441206a41186a2216200841186a221e290000370300200441206a41106a2217200841106a221f290000370300200441206a41086a2218200841086a222029000037030020042008290000370320200820194105746a220a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2008200a290000370000201e201c370000201f201b3700002020201a370000200d2016290300370000200b2017290300370000200c2018290300370000200a2004290320370000200441186a2205201e290000370300200441106a2209201f290000370300200441086a2221202029000037030020042008290000370300200841206a21014100211d2007417f6a220d450d022001210a0340200a2004412010f80441004e0d03200a41206a210a200d201d41016a221d470d000b200d211d0c020b41d885c000410041001038000b41e885c000201920071038000b200820074105746a210c200d210b02400340200c2100200b220a201d4d22060d01200a417f6a210b200041606a220c2004412010f804417f4a0d000b0b0240200a201d490d00200d200a490d0241800121144100210f410021124100210d4100211141800121152001201d4105746a2222210103400240200020016b220a419fc0004b22190d00200a410576220a41807f6a200a2012200f492011200d49220c72220b1b210a0240200b450d002015200a200c1b2115200a2014200c1b21140c010b200a200a41017622156b21140b02402011200d470d00024020150d00200441c0006a220d21110c010b4100210a200441c0006a2211210d2001210c0340200d200a3a0000200d200c2004412010f804417f73411f766a210d200c41206a210c2015200a41016a220a470d000b0b02402012200f470d00024020140d00200441c0016a220f21120c010b200041606a210a4100210c200441c0016a2212210f0340200f200c3a0000200f200a2004412010f804411f766a210f200a41606a210a2014200c41016a220c470d000b0b0240200f20126b220a200d20116b220c200c200a4b1b2213450d002016200120112d00004105746a220a41186a2900003703002017200a41106a2900003703002018200a41086a2900003703002004200a290000370320200120112d00004105746a220a200020122d0000417f734105746a220c290000370000200a41186a200c41186a290000370000200a41106a200c41106a290000370000200a41086a200c41086a290000370000024020134101460d004100210a034020002012200a6a220e2d0000417f734105746a220c20012011200a6a41016a22102d00004105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200120102d00004105746a220c2000200e41016a2d0000417f734105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200a41026a210c200a41016a220b210a200c2013490d000b2012200b6a21122011200b6a21110b200020122d0000417f734105746a220a2004290320370000200a41186a2016290300370000200a41106a2017290300370000200a41086a2018290300370000201241016a2112201141016a21110b200020144105746b20002012200f461b2100200120154105746a20012011200d461b210120190d000b024002402011200d4f0d002000210a034020162001200d417f6a220d2d00004105746a220c41186a220b2900003703002017200c41106a220f2900003703002018200c41086a22002900003703002004200c290000370320200a41606a220a41086a220e290000211a200a41106a2210290000211b200a41186a2212290000211c200c200a290000370000200b201c370000200f201b3700002000201a3700002012201629030037000020102017290300370000200e2018290300370000200a20042903203700002011200d490d000c020b0b2001210a2012200f4f0d000340200f417f6a220f2d0000210c2016200a41186a220b2900003703002017200a41106a220d2900003703002018200a41086a22012900003703002004200a2900003703202000200c417f734105746a220c41086a220e290000211a200c41106a2210290000211b200c41186a2211290000211c200a200c290000370000200b201c370000200d201b3700002001201a3700002011201629030037000020102017290300370000200e2018290300370000200c2004290320370000200a41206a210a2012200f490d000b0b20082004290300370000201e2005290300370000201f2009290300370000202020212903003700002007200a20226b410576201d6a22014d0d032016201e2900003703002017201f2900003703002018202029000037030020042008290000370320200820014105746a220a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2008200a290000370000201e201c370000201f201b3700002020201a370000200d2016290300370000200b2017290300370000200c2018290300370000200a2004290320370000200720016b220c450d04200c20012001200c4b1b210b2007410376210d200a41206a2100024002402001200c417f6a220c490d002000200c200a20031063200821000c010b20082001200220031063200a2102200c21010b200b200d4f2105200141154f0d010c050b0b201d200a1035000b200a200d105e000b41e885c000200120071038000b41f885c0001058000b20014102490d00200041606a210f4101210b0340200b410574210a200b417f6a210c200b41016a210b02402000200a6a220a2000200c4105746a220d412010f804417f4a0d00200441c0016a41186a220e200a41186a2210290000370300200441c0016a41106a2211200a41106a2212290000370300200441c0016a41086a2213200a41086a22142900003703002004200a2900003703c001200a200d2900003700002014200d41086a2900003700002012200d41106a2900003700002010200d41186a2900003700004100210d0240200c450d00200f210a03400240200441c0016a200a412010f8044100480d00200c210d0c020b200a41206a200a290000370000200a41386a200a41186a290000370000200a41306a200a41106a290000370000200a41286a200a41086a290000370000200a41606a210a200c417f6a220c0d000b0b2000200d4105746a220a20042903c001370000200a41186a200e290300370000200a41106a2011290300370000200a41086a20132903003700000b200f41206a210f200b2001470d000b0b200441c0026a24000bb50404057f017e017f017e0240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a3602000240200441037122064103460d00024002400240024020060e03000102000b2004410276ad21070c020b41012106024020050d000c050b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d04200141fcff0371410276ad21070c010b410121060240200541034f0d000c040b200341036a2d0000210520032f0001210820012002417c6a3602042001200341046a3602002008200541107472410874200472220141808004490d032001410276ad21070b410021060c020b02402004410276220841044b0d000240024020080e050002020201000b20054104490d022003350001210720012002417b6a3602042001200341056a36020020074280808080045421060c030b20054108490d01200329000121072001200241776a3602042001200341096a3602002007428080808080808080015421060c020b200841046a220541084b0d002002417e6a2102200341026a2103410021044200210741012106034002402002417f470d000c030b2003417f6a310000210920012002360204200120033602002002417f6a2102200341016a210320092004410374413871ad862007842107200441016a220441ff01712005490d000b2007427f412820084103746b413871ad885821060c010b410121060b2000200737030820002006ad3703000bde0506067f017e017f017e017f017e230041206b220224000240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200024002400240200541037122074103460d0002400240024020070e03000102000b2005410276ad21080c040b410121072006450d0220042d0001210620012003417e6a3602042001200441026a3602002006410874200572220141ffff0371418002490d02200141fcff0371410276ad21080c030b4101210720064103490d01200441036a2d0000210620042f0001210920012003417c6a3602042001200441046a3602002009200641107472410874200572220141808004490d012001410276ad21080c020b024020054102762209410c4b0d0002400240024020090e0d00030303010303030303030302000b20064104490d052004350001210820012003417b6a3602042001200441056a36020020084280808080045421074200210a0c060b20064108490d04200429000121082001200341776a3602042001200441096a3602002008428080808080808080015421074200210a0c050b20064110490d03200441096a290000210a2004290001210820012003416f6a3602042001200441116a360200200a428080808080808080015421070c040b200941046a220641104b0d022003417e6a2103200441026a21044100210541012107200241186a210b420021084200210a03402003417f460d01200241106a2004417f6a3100004200200541037441f8007110f90420012003360204200120043602002003417f6a2103200441016a2104200b290300200a84210a20022903102008842108200541016a220541ff01712006490d000b2002427f427f41e80020094103746b41f8007110fa042008200229030058200a200241086a290300220c58200a200c511b21070c030b0c020b4200210a410021070c010b410121070b20002008370308200041106a200a37030020002007ad370300200241206a24000b9e0701037f02400240024002400240024020002802002202413f4b0d0002400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0620004101742204200320032004491b22044100480d060240024020000d002004102921030c010b200128020020002004102a21030b2003450d0220012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a20024102743a00000f0b200241808001490d032002418080808004490d020c010b20044101102c000b0240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0520024101742204200320032004491b22044100480d050240024020020d002004102921030c010b200128020020022004102a21030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a00002000280200210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0520024101742200200420042000491b22004100480d050240024020020d002000102921020c010b200128020020022000102a21020b2002450d0220012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b20044101102c000b20004101102c000b024002400240200141046a2802002203200141086a28020022006b4104490d00200128020021030c010b200041046a22042000490d0320034101742200200420042000491b22004100480d030240024020030d002000102921030c010b200128020020032000102a21030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20024102744102723600000f0b20004101102c000b024002400240200141046a2802002203200141086a28020022006b4102490d00200128020021030c010b200041026a22042000490d0220034101742200200420042000491b22004100480d020240024020030d002000102921030c010b200128020020032000102a21030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a20024102744101723b00000f0b20004101102c000b102d000bbd0903017f017e057f230041e0006b220224000240024002400240024002400240024002400240024020002903002203423f560d0002400240200141046a280200200141086a2802002200460d00200128020021040c010b200041016a22042000490d0b20004101742205200420042005491b22054100480d0b0240024020000d002005102921040c010b200128020020002005102a21040b2004450d0220012004360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200420006a2003a74102743a00000c080b200342808001540d062003428080808004540d054108200379a741037622056b4104490d0402400240200141046a280200200141086a2802002204460d00200128020021060c010b200441016a22072004490d0a20044101742206200720072006491b22074100480d0a0240024020040d002007102921060c010b200128020020042007102a21060b2006450d0220012006360200200141046a2007360200200141086a28020021040b200141086a2207200441016a360200200620046a411320054102746b3a0000200220002903002203370308200541786a2104200141046a2106034002400240200628020020072802002200460d00200128020021050c010b200041016a22052000490d0b20004101742208200520052008491b22084100480d0b0240024020000d002008102921050c010b200128020020002008102a21050b2005450d042001200536020020062008360200200728020021000b2007200041016a360200200520006a2003a73a000020034208882103200441016a22002004492105200021042005450d000b20022003370308200350450d030c070b20054101102c000b20074101102c000b20084101102c000b200241286a41146a411d360200200241346a411e360200200241106a41146a41033602002002200241086a360240200241e08dc000360244200241c8006a41146a4100360200200242033702142002419ce7c5003602102002411e36022c200241c8ecc5003602582002420137024c200241e88dc0003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a41f08dc000106a000b41c48dc0001058000b024002400240200141046a2802002204200141086a28020022006b4104490d00200128020021040c010b200041046a22052000490d0520044101742200200520052000491b22004100480d050240024020040d002000102921040c010b200128020020042000102a21040b2004450d0120012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a2003a74102744102723600000c020b20004101102c000b02400240200141046a2802002204200141086a28020022006b4102490d00200128020021040c010b200041026a22052000490d0320044101742200200520052000491b22004100480d030240024020040d002000102921040c010b200128020020042000102a21040b2004450d0220012004360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200420006a2003a74102744101723b00000b200241e0006a24000f0b20004101102c000b102d000b6501027f230041206b220224002001411c6a280200210320012802182101200241086a41106a200041106a290200370300200241086a41086a200041086a2902003703002002200029020037030820012003200241086a10b5042100200241206a240020000bc20202027f017e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120044101200110b50121000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000b20024180016a240020000f0b20034180011035000b20034180011035000b4b02017f017e230041206b2202240020012902002103200241146a20012902083702002002200337020c20022000360208200241c8ecc500360204200241c8ecc500360200200210d204000b910a03017f027e057f230041e0006b2202240002400240024002400240024002400240024002400240200028020022002903002203423f56200041086a290300220442005220045022051b0d0002400240200141046a280200200141086a2802002200460d00200128020021050c010b200041016a22052000490d0b20004101742206200520052006491b22064100480d0b0240024020000d002006102921050c010b200128020020002006102a21050b2005450d0220012005360200200141046a2006360200200141086a28020021000b200141086a200041016a360200200520006a2003a74102743a00000c080b20034280800154410020051b0d06200342808080800454410020051b0d05411020047920037942c0007c20044200521ba741037622066b4104490d0402400240200141046a280200200141086a2802002205460d00200128020021070c010b200541016a22082005490d0a20054101742207200820082007491b22084100480d0a0240024020050d002008102921070c010b200128020020052008102a21070b2007450d0220012007360200200141046a2008360200200141086a28020021050b200141086a2208200541016a360200200720056a413320064102746b3a0000200029030021032002200041086a290300220437030820022003370300200641706a2105200141046a2107034002400240200728020020082802002200460d00200128020021060c010b200041016a22062000490d0b20004101742209200620062009491b22094100480d0b0240024020000d002009102921060c010b200128020020002009102a21060b2006450d042001200636020020072009360200200828020021000b2008200041016a360200200620006a2003a73a00002003420888200442388684210320044208882104200541016a22002005492106200021052006450d000b2002200337030020022004370308200320048450450d030c070b20064101102c000b20084101102c000b20094101102c000b200241286a41146a411d360200200241346a411f360200200241106a41146a410336020020022002360240200241908fc000360244200241c8006a41146a4100360200200242033702142002419ce7c5003602102002411f36022c200241c8ecc5003602582002420137024c200241e88dc0003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a41a08fc000106a000b41f48ec0001058000b024002400240200141046a2802002205200141086a28020022006b4104490d00200128020021050c010b200041046a22062000490d0520054101742200200620062000491b22004100480d050240024020050d002000102921050c010b200128020020052000102a21050b2005450d0120012005360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200520006a2003a74102744102723600000c020b20004101102c000b02400240200141046a2802002205200141086a28020022006b4102490d00200128020021050c010b200041026a22062000490d0320054101742200200620062000491b22004100480d030240024020050d002000102921050c010b200128020020052000102a21050b2005450d0220012005360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200520006a2003a74102744101723b00000b200241e0006a24000f0b20004101102c000b102d000b840605027f027e017f027e027f230041a0016b220224002000280200210002400240024002400240024002400240200128020022034110710d00200041086a29030021042000290300210520034120710d0220054290ce005441002004501b450d012005a72103412721000c060b200041086a2903002105200029030021044180012100024003402000450d01200241206a20006a417f6a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a210020044204882005423c8684220420054204882205844200520d000b0b20004181014f0d022001410141f8efc5004102200241206a20006a41800120006b10b60121000c060b41272100200241186a21060340200241106a200520044290ce00420010fc042002200229031022072006290300220842f0b17f427f10fb04200241206a20006a2203417c6a200520022903007ca7220941ffff037141e4006e220a410174418aedc5006a2f00003b00002003417e6a200a419c7f6c20096a41ffff0371410174418aedc5006a2f00003b0000200542ffc1d72f56210320044200522109200450210a2000417c6a2100200721052008210420032009200a1b0d000c040b0b4180012100024003402000450d01200241206a20006a417f6a2005a7410f712203413072200341376a2003410a491b3a00002000417f6a210020054204882004423c8684220520044204882204844200520d000b0b20004181014f0d012001410141f8efc5004102200241206a20006a41800120006b10b60121000c040b20004180011035000b20004180011035000b2007a721030b02400240200341e3004a0d00200321090c010b200241206a2000417e6a22006a2003200341ffff037141e4006e2209419c7f6c6a41ffff0371410174418aedc5006a2f00003b00000b024002402009410a480d00200241206a2000417e6a22006a2009410174418aedc5006a2f00003b00000c010b200241206a2000417f6a22006a200941306a3a00000b2001410141c8ecc5004100200241206a20006a412720006b10b60121000b200241a0016a240020000bd20302047f037e230041e0006b2204240002400240411410292205450d00200541002900d88c40370000200541106a41002800e88c40360000200541086a41002900e08c4037000020044294808080c002370234200420053602302001200441306a104a20042802342105200441186a200428023022062004280238106e200441186a41106a2903004200200428021822071b21082004290320420020071b210902402005450d002006102e0b200441306a2001200920027c2202200820037c2002200954ad7c106f200441306a41106a290300210920042903382102024020042903304200520d00200221030c020b200441c28cc00041161070200441106a29030021082004290308210a2004280200210542002103200441306a41086a220142003703002004420037033041c28cc0004116200441306a1003200441d0006a41086a200129030037030020042004290330370350200442002008420020051b220820097d200a420020051b2209200254ad7d220a200920027d2202200956200a200856200a2008511b22051b37033820044200200220051b370330200441d0006a4110200441306a41101004420021090c010b41144101102c000b2000200337030020002009370308200441e0006a24000b880204017f017e037f027e230041c0006b2203240042002104200341206a41186a22054200370300200341206a41106a22064200370300200341206a41086a220742003703002003420037032020012002200341206a1000200341186a2005290300370300200341106a2006290300370300200341086a2007290300370300200320032903203703002003410036022020034120200341206a1008210102400240024020032802202202417f470d000c010b20024110490d01200141086a2900002108200129000021092001102e420121040b2000200937030820002004370300200041106a2008370300200341c0006a24000f0b41eff0c2004133200341206a4184f4c2001053000b9e0603047f037e047f230041b0016b2204240002400240411410292205450d00200541002900d88c40370000200541106a41002800e88c40360000200541086a41002900e08c4037000020044294808080c002370224200420053602202001200441206a104a20042802242106200441086a200428022022072004280228106e200441086a41106a2903002108200428020821052004290310210902402006450d002007102e0b2008420020051b210a2009420020051b2108024002400240200242ffffe883b1de1656200342005220035022051b0d002008200a84500d010b4101210602402002428080e983b1de1654410020051b0d00411410292205450d0441002106200541002900d88c40370000200541106a41002800e88c40360000200541086a41002900e08c4037000020044294808080c002370224200420053602202001200441206a104a200428022421072004280228210b20042802202105200441206a41186a220c4200370300200441206a41106a220d4200370300200441206a41086a220e4200370300200442003703202005200b200441206a100020044190016a41186a200c29030037030020044190016a41106a200d29030037030020044190016a41086a200e290300370300200420042903203703900120044190016a412041c8ecc500410041001005210b02402007450d002005102e0b200b417f470d0020011071200441d8006a2003370300200441d0006a200237030041002106200441206a41086a41003a0000200441296a2001290000370000200441316a200141086a290000370000200441396a200141106a290000370000200441c1006a200141186a290000370000200441023a002041c8ecc5004100200441206a10720b2001200220031073200041106a200a20037d2008200254ad7d2003200a7d2002200854ad7d2008200256200a200356200a2003511b22051b3703002000200820027d200220087d20051b370308200020063a001820002005ad3703000c010b20004200370300200041013a0018200041106a4200370300200041086a42003703000b200441b0016a24000f0b41144101102c000b41144101102c000bce0104017f017e017f027e230041206b2203240042002104200341106a41086a220542003703002003420037031020012002200341106a1003200341086a2005290300370300200320032903103703002003410036021020034110200341106a1008210102400240024020032802102202417f470d000c010b20024110490d01200141086a2900002106200129000021072001102e420121040b2000200737030820002004370300200041106a2006370300200341206a24000f0b41eff0c2004133200341106a4184f4c2001053000ba20a03067f037e047f230041a0016b22012400200141186a4197cac2004113107d20012802182102200128021c21030240024002400240024002400240410110292204450d00200420002d00003a0000200441014102102a2204450d01200420002d00013a0001200441024104102a2204450d02200420002d00023a0002200420002d00033a0003200441044108102a2204450d03200420002d00043a0004200420002d00053a0005200420002d00063a0006200420002d00073a0007200441084110102a2204450d04200420002d00083a0008200420002d00093a0009200420002d000a3a000a200420002d000b3a000b200420002d000c3a000c200420002d000d3a000d200420002d000e3a000e200420002d000f3a000f200441104120102a2204450d05200420002d00103a0010200420002d00113a0011200420002d00123a0012200420002d00133a0013200420002d00143a0014200420002d00153a0015200420002d00163a0016200420002d00173a0017200420002d00183a0018200420002d00193a0019200420002d001a3a001a200420002d001b3a001b200420002d001c3a001c200420002d001d3a001d200420002d001e3a001e200420002d001f3a001f20042d0000210520042d000121062004102e20014190016a2005200641087472410676220610bb0102402005413f7122042001280298014f0d00200141086a20012802900120044105746a22041084012001290308200141086a41086a290300844200520d00200041086a2900002107200041106a2900002108200041186a290000210920042000290000370000200441186a2009370000200441106a2008370000200441086a2007370000200141206a41086a20014190016a41086a28020036020020012001290390013703202006200141206a1091030c070b2003410020021b21040240200128029401450d00200128029001102e0b200141206a200410bb01024020012802282205413f4d0d000340200441016a210402402001280224450d002001280220102e0b200141206a200410bb0120012802282205413f4b0d000b0b2001280220210620012802242103200141206a41186a220a200041186a290000370300200141206a41106a220b200041106a290000370300200141206a41086a220c200041086a29000037030020012000290000370320200541016a2102024020032005470d00024020054101742203200220022003491b2203410574220d4100480d000240024020050d00200d102921060c010b20062005410574200d102a21060b20060d01200d4101102c000b102d000b200520044106746a210d200620054105746a22052001290320370000200541186a200a290300370000200541106a200b290300370000200541086a200c2903003700000240200241c000470d00200141206a41086a22054200370300200142003703204197cac2004113200141206a100320014190016a41086a200529030037030020012001290320370390012001200441016a36022020014190016a4110200141206a410410040b2001200236022820012003360224200120063602202004200141206a109103200141206a41086a2000290000370300200141206a41106a200041086a290000370300200141206a41186a200041106a290000370300200141c0006a200041186a2900003703002001200d360224200141013a002041c8ecc5004100200141206a10720c060b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000b200141a0016a24000b982203097f047e017f230041b0036b22032400200341003602a00141dff0c2004110200341a0016a100821040240024020032802a0012205417f460d002004450d00024020054104490d00200428000021062004102e410021070c020b41eff0c2004133200341a8036a4184f4c2001053000b410121070b200141057421084101210941002104410021050240024002400240024002400240024002402001450d0020084100480d05200810292209450d012001410574220a41606a410576210b410021040340200341b8026a41186a200020046a220541186a290000220c370300200341b8026a41106a200541106a290000220d370300200341b8026a41086a200541086a290000220e37030020032005290000220f3703b802200920046a220541186a200c370000200541106a200d370000200541086a200e3700002005200f370000200a200441206a2204470d000b200b41016a2105200121040b2003418c016a20063602002003200736028801200341186a200241f00010f6041a20034198016a200536020020034194016a20043602002003200936029001200341106a4197e5c5004111107d0240024002400240024002402003280214410020032802101b220641016a22052006490d00200341b8026a41086a22044200370300200342003703b8024197e5c5004111200341b8026a100320034180036a41086a22092004290300370300200320032903b80237038003200320053602a00120034180036a4110200341a0016a41041004200341a0016a200341186a41880110f6041a20044200370300200342003703b80241c4f5c200410d200341b8026a100320092004290300370300200320032903b80237038003200341003602b80220034180036a4110200341b8026a100821050240024020032802b8022204417f460d0020050d010b200341003602b002200342013703a8020c080b200320043602b002200320043602ac02200320053602a8022004450d07200341b8026a2005200410a303024020032802b8024101460d0020032802bc02210a0240200341c4026a2802002204200341c0026a2802002205460d0020032802b002200420056b6a22094188016a2202417f4c0d0d0240024020020d00410121070c010b200210292207450d040b200320023602dc02200320073602d802200320093602e0022003200341d8026a3602b802200a200341b8026a2004109d0120092004490d0420032802e002220a2009490d0520032802b002220a2005490d0620032802d802210220032802a80221072003200920046b2209360298032003200a20056b220a36029c032009200a470d07200220046a200720056a200910f6041a200341a0016a200341d8026a10a40320032802e002210520032802dc02210920032802d802210420032802ac02450d0b20032802a802102e0c0b0b2003200341a8026a3602b802200a200341b8026a2005109d01200341a0016a200341a8026a10a4030c090b20032802ac02450d0c20032802a802102e0c0c0b200341186a10a5030c0c0b20024101102c000b200420091035000b2009200a105e000b2005200a1035000b20034180036a41146a411d3602002003418c036a4120360200200341e8026a41146a4103360200200320034198036a3602a00320032003419c036a3602a403200341b8026a41146a4100360200200342033702ec022003419ce7c5003602e8022003412036028403200341c8ecc5003602c802200342013702bc02200341f0e7c5003602b802200320034180036a3602f8022003200341b8026a360290032003200341a4036a360288032003200341a0036a36028003200341e8026a41ace8c500106a000b20084101102c000b4101200341a8026a1047200341a0016a200341a8026a10a4030b20032802b002210520032802ac02210920032802a80221040b2004450d02200341b8026a41086a220a4200370300200342003703b80241c4f5c200410d200341b8026a100320034180036a41086a200a290300370300200320032903b8023703800320034180036a411020042005100402402009450d002004102e0b200341a0016a10a503200341086a41b0f3c200410d107d2001450d03200020086a2110200328020c410020032802081b210b0240024002400340200320063602ac022003200b3602a802024002400240024002400240024002400240024002400240024002400240024002400240024002400240411210292204450d00200441106a41002f00e1f5423b0000200441086a41002900d9f542370000200441002900d1f542370000200341b8026a41186a22094200370300200341b8026a41106a220a4200370300200341b8026a41086a22014200370300200342003703b80220044112200341b8026a1000200341a0016a41186a22082009290300370300200341a0016a41106a2202200a290300370300200341a0016a41086a22072001290300370300200320032903b8023703a001412010292205450d01200520032903a001370000200541186a2008290300370000200541106a2002290300370000200541086a20072903003700002004102e410110292204450d02200420002d00003a0000200441014102102a2204450d032004200041016a2d00003a0001200441024104102a2204450d042004200041026a2d00003a00022004200041036a2d00003a0003200441044108102a2204450d052004200041046a2d00003a00042004200041056a2d00003a00052004200041066a2d00003a00062004200041076a2d00003a0007200441084110102a2204450d062004200041086a2d00003a00082004200041096a2d00003a000920042000410a6a2d00003a000a20042000410b6a2d00003a000b20042000410c6a2d00003a000c20042000410d6a2d00003a000d20042000410e6a2d00003a000e20042000410f6a2d00003a000f200441104120102a2204450d072004200041106a2d00003a00102004200041116a2d00003a00112004200041126a2d00003a00122004200041136a2d00003a00132004200041146a2d00003a00142004200041156a2d00003a00152004200041166a2d00003a00162004200041176a2d00003a00172004200041186a2d00003a00182004200041196a2d00003a001920042000411a6a2d00003a001a20042000411b6a2d00003a001b20042000411c6a2d00003a001c20042000411d6a2d00003a001d20042000411e6a2d00003a001e20042000411f6a2d00003a001f20094200370300200a420037030020014200370300200342003703b80220044120200341b8026a1000200820092903003703002002200a29030037030020072001290300370300200320032903b8023703a0012005412041c000102a2205450d08200520032903a001370020200541386a2008290300370000200541306a2002290300370000200541286a20072903003700002004102e200341003602a001200541c000200341a0016a10082109024020032802a0012204417f470d00200341003602e002200342013703d8020c130b200320043602e002200320043602dc02200320093602d8022004450d12200341a0016a2009200410a303024020032802a0014101460d0020032802a4012101024020032802ac01220420032802a8012209460d0020032802e002200420096b6a220a41086a2208417f4c0d1c0240024020080d00410121020c010b200810292202450d0c0b200320083602ec02200320023602e8022003200a3602f0022003200341e8026a3602a0012001200341a0016a2004109d01200a2004490d0c20032802f0022201200a490d0d20032802e00222012009490d0e20032802e802210820032802d80221022003200a20046b220a360298032003200120096b220136029c03200a2001470d0f200820046a200220096a200a10f6041a20032802a802210a0240024020032802ec02220920032802f00222046b4104490d0020032802e80221090c010b200441046a22012004490d1c20094101742204200120012004491b22044100480d1c0240024020090d002004102921090c010b20032802e80220092004102a21090b2009450d11200320043602ec02200320093602e80220032802f00221040b2003200441046a3602f002200920046a200a36000020032802ac02210a0240024020032802ec02220920032802f00222046b4104490d0020032802e80221090c010b200441046a22012004490d1c20094101742204200120012004491b22044100480d1c0240024020090d002004102921090c010b20032802e80220092004102a21090b2009450d12200320043602ec02200320093602e80220032802f00221040b2003200441046a3602f002200920046a200a36000020032802f002210920032802ec02210a20032802e802210420032802dc02450d1620032802d802102e0c160b2003200341d8026a3602a0012001200341a0016a2009109d0120032802a802210a0240024020032802dc02220920032802e00222046b4104490d0020032802d80221090c010b200441046a22012004490d1b20094101742204200120012004491b22044100480d1b0240024020090d002004102921090c010b20032802d80220092004102a21090b2009450d12200320043602dc02200320093602d80220032802e00221040b2003200441046a3602e002200920046a200a36000020032802ac02210a0240024020032802dc02220920032802e00222046b4104490d0020032802d80221090c010b200441046a22012004490d1b20094101742204200120012004491b22044100480d1b0240024020090d002004102921090c010b20032802d80220092004102a21090b2009450d13200320043602dc02200320093602d80220032802e00221040b2003200441046a3602e002200920046a200a3600000c140b20032802dc02450d1620032802d802102e0c160b41124101102c000b41204101102c000b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000b41c0004101102c000b20084101102c000b2004200a1035000b200a2001105e000b200920011035000b20034180036a41146a411d3602002003418c036a4120360200200341b8026a41146a4103360200200320034198036a3602a00320032003419c036a3602a403200341a0016a41146a4100360200200342033702bc022003419ce7c5003602b8022003412036028403200341c8ecc5003602b001200342013702a401200341f0e7c5003602a001200320034180036a3602c8022003200341a0016a360290032003200341a4036a360288032003200341a0036a36028003200341b8026a41ace8c500106a000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b4101200341d8026a104720032802a802210a0240024020032802dc02220920032802e00222046b4104490d0020032802d80221090c010b200441046a22012004490d0720094101742204200120012004491b22044100480d070240024020090d002004102921090c010b20032802d80220092004102a21090b2009450d05200320043602dc02200320093602d80220032802e00221040b2003200441046a3602e002200920046a200a36000020032802ac02210a0240024020032802dc02220920032802e00222046b4104490d0020032802d80221090c010b200441046a22012004490d0720094101742204200120012004491b22044100480d070240024020090d002004102921090c010b20032802d80220092004102a21090b2009450d06200320043602dc02200320093602d80220032802e00221040b2003200441046a3602e002200920046a200a3600000b20032802e002210920032802dc02210a20032802d80221040b2004450d01200541c0002004200910040240200a450d002004102e0b2005102e200041206a22002010470d000c070b0b2005102e0c050b20044101102c000b20044101102c000b102d000b1032000b200341a0016a10a5030b200341b0036a24000bfb1403087f027e027f230041f0036b22032400024002400240024002400240024002400240024002400240411410292204450d00200441002900d88c40370000200441106a41002800e88c40360000200441086a41002900e08c4037000020034294808080c00237024c200320043602482000200341c8006a104a200328024c21052003280250210620032802482104200341c8006a41186a22074200370300200341c8006a41106a22084200370300200341c8006a41086a220942003703002003420037034820042006200341c8006a100020034188036a41186a200729030037030020034188036a41106a200829030037030020034188036a41086a20092903003703002003200329034837038803200320023703502003200137034820034188036a4120200341c8006a4110100402402005450d002004102e0b200142ffffe883b1de165620024200522002501b0d09411410292204450d01200441002900d88c40370000200441106a41002800e88c40360000200441086a41002900e08c4037000020034294808080c00237024c200320043602482000200341c8006a104a200328024c21052003280250210620032802482104200341c8006a41186a22074200370300200341c8006a41106a22084200370300200341c8006a41086a220942003703002003420037034820042006200341c8006a100020034188036a41186a200729030037030020034188036a41106a200829030037030020034188036a41086a20092903003703002003200329034837038803200341306a20034188036a1074200341306a41106a2903002101200329033821022003280230210a02402005450d002004102e0b410e10292204450d02200441002900848d40370000200441066a410029008a8d403700002003428e808080e00137024c200320043602482000200341c8006a104a200328024c21052003280250210620032802482104200341c8006a41186a22074200370300200341c8006a41106a22084200370300200341c8006a41086a220942003703002003420037034820042006200341c8006a100020034188036a41186a200729030037030020034188036a41106a200829030037030020034188036a41086a2009290300370300200320032903483703880320034188036a4120100602402005450d002004102e0b02402002200184500d00200a450d00200341186a41c28cc00041161070200341186a41106a290300210b2003290320210c20032802182104200341c8016a41086a22054200370300200342003703c80141c28cc0004116200341c8016a100320034188036a41086a2005290300370300200320032903c8013703880320034200200b420020041b220b20017d200c420020041b2201200254ad7d220c200120027d2202200156200c200b56200c200b511b22041b37035020034200200220041b37034820034188036a4110200341c8006a411010040b20001075411710292204450d03200441002900b0a5433700002004410f6a41002900bfa543370000200441086a41002900b8a54337000020034297808080f00237024c200320043602482000200341c8006a104a200328024c21072003280250210620032802482105200341c8006a41186a22044200370300200341c8006a41106a22084200370300200341c8006a41086a220942003703002003420037034820052006200341c8006a100020034188036a41186a200429030037030020034188036a41106a200829030037030020034188036a41086a20092903003703002003200329034837038803200341c8006a20034188036a1076024020032d004822064102460d0020034188036a412010060b200341e8006a280200210a200341e4006a28020021092004280200210802402007450d002005102e0b0240024002400240200641037122044103460d0020040e03010003010b20060d0220090d010c020b2008200a10072009450d010b2008102e0b200341b8016a2000107720032802b801210420032802c00121052003410036024820042005200341c8006a1008210720032802482206417f460d07200320063602ec03200320073602e803200341c8006a200341e8036a107820032d00484101460d0420034188036a200341c8006a41017241e00010f6041a02402006450d002007102e0b200341a8026a20034188036a41e00010f6041a200420051006200341c8016a200341a8026a41e00010f6041a20034188036a200341c8016a41e00010f6041a024020032802bc01450d002004102e0b200341c8006a20034188036a41e00010f6041a200341c8006a41206a210920034188016a210d200341c8006a210a4120417f4a210e4104210641e7e485f306210503402009210702400240200541e2c289ab06460d00200a2107200541e7e485f306460d000240200541e9dabdf306460d00410121084100210441c8ecc50021070c020b200d21070b200e450d07024041200d0041012108410021040c010b412010292208450d08412021040b20082007200410f6042107200320043602b402200320043602b002200320073602ac02200320053602a802200341c8016a200341a8026a107920032802c801220520032802d0011006024020032802cc01450d002005102e0b02402004450d002007102e0b02402006410c460d002006418cd8c1006a2800002105200641046a21060c010b0b200341013a00b801200341c8016a41086a22044200370300200342003703c80141ccdfc500410f200341c8016a1003200341a8026a41086a2004290300370300200320032903c8013703a802200341a8026a4110200341b8016a410110040c080b41144101102c000b41144101102c000b410e4101102c000b41174101102c000b41eff0c200413320034188036a4184f4c2001053000b1032000b41204101102c000b200341c8016a200341a8026a41e00010f6041a20032802bc01450d002004102e0b411810292204450d01200441002900ec8c40370000200441106a41002900fc8c40370000200441086a41002900f48c4037000020034298808080800337024c200320043602482000200341c8006a104a200328024c21042003200328024822062003280250106e200341106a2903002102200329030821012003280200210502402004450d002006102e0b02402001200284500d0020050d010b411310292204450d02200441002900eff3423700002004410f6a41002800fef342360000200441086a41002900f7f34237000020034293808080b00237024c200320043602482000200341c8006a104a200328024c21062003280250210720032802482105200341c8006a41186a22084200370300200341c8006a41106a22094200370300200341c8006a41086a220442003703002003420037034820052007200341c8006a100020034188036a41186a200829030037030020034188036a41106a200929030037030020034188036a41086a2004290300370300200320032903483703880320034188036a4120100602402006450d002005102e0b200441013a0000200341d1006a2000290000370000200341d9006a200041086a290000370000200341e1006a200041106a290000370000200341e9006a200041186a290000370000200341023a004841c8ecc5004100200341c8006a10720b200341f0036a24000f0b41184101102c000b41134101102c000b980102037f037e230041106b220224002002410036020420014120200241046a1008210302400240024020022802042204417f470d00420021050c010b20044110490d01200341086a2900002106200329000021072003102e200141201006420121050b2000200537030020002007370308200041106a2006370300200241106a24000f0b41eff0c2004133200241086a4184f4c2001053000bc60901077f23004190016b220124000240024002400240410e10292202450d00200241002900d9e743370000200241066a41002900dfe7433700002001428e808080e00137026c200120023602682000200141e8006a104a200128026c21032001280270210420012802682102200141e8006a41186a22054200370300200141e8006a41106a22064200370300200141e8006a41086a220742003703002001420037036820022004200141e8006a1000200141c8006a41186a2005290300370300200141c8006a41106a2006290300370300200141c8006a41086a200729030037030020012001290368370348200141e8006a200141c8006a412010dc010240024020012d00684101470d00200141c8006a41201006200141086a41186a20014181016a290000370300200141086a41106a200141f9006a290000370300200141086a41086a200141f1006a2900003703002001200129006937030802402003450d002002102e0b200141286a41186a200141086a41186a290300370300200141286a41106a200141086a41106a290300370300200141286a41086a200141086a41086a29030037030020012001290308370328410e10292202450d03200241002900b1e843370000200241066a41002900b7e8433700002001428e808080e00137026c20012002360268200141286a200141e8006a104a200128026c21032001280270210420012802682102200141e8006a41186a22054200370300200141e8006a41106a22064200370300200141e8006a41086a220742003703002001420037036820022004200141e8006a1000200141c8006a41186a2005290300370300200141c8006a41106a2006290300370300200141c8006a41086a200729030037030020012001290368370348200141c8006a412010062003450d012002102e0c010b2003450d002002102e0b410d10292202450d02200241002900bfe843370000200241056a41002900c4e8433700002001428d808080d00137026c200120023602682000200141e8006a104a200128026c21032001280270210420012802682102200141e8006a41186a22054200370300200141e8006a41106a22064200370300200141e8006a41086a220742003703002001420037036820022004200141e8006a1000200141c8006a41186a2005290300370300200141c8006a41106a2006290300370300200141c8006a41086a200729030037030020012001290368370348200141c8006a4120100602402003450d002002102e0b411210292202450d03200241002900cce843370000200241106a41002f00dce8433b0000200241086a41002900d4e84337000020014292808080a00237026c200120023602682000200141e8006a104a200128026c21032001280270210420012802682102200141e8006a41186a22054200370300200141e8006a41106a22064200370300200141e8006a41086a220742003703002001420037036820022004200141e8006a1000200141c8006a41186a2005290300370300200141c8006a41106a2006290300370300200141c8006a41086a200729030037030020012001290368370348200141c8006a4120100602402003450d002002102e0b200010db03200010dc0320014190016a24000f0b410e4101102c000b410e4101102c000b410d4101102c000b41124101102c000bd60a050a7f027e037f027e017f230041e0006b220224002002410036023820014120200241386a1008210302400240024002400240024002400240024020022802382204417f460d0020030d010b200041023a00000c010b20022004360214200220033602102004450d0520032d0000210120022004417f6a3602142002200341016a360210200141014b0d0502400240024020010e020001000b200241086a200241106a103120022802080d072002280214200228020c2205490d072005417f4c0d030240024020050d004101210641010d010c090b200510342206450d09200620022802102201200510f6042104200228021422072005490d052002200720056b3602142002200120056a3602102004450d080b200228021422084104490d0520022802102209280000210a20022008417c6a220b3602142002200941046a36021041002101200241003a0058417b210703400240200b2001470d000240200141ff0171450d00200241003a00580b20050d080c090b200241386a20016a200920016a220441046a2d00003a00002002200820076a3602142002200441056a3602102002200141016a22043a00582007417f6a21072004210120044120470d000b2002200228003b36003320022002280238360230200220022802303602282002200228003336002b0240024002400240200820046b2207417c6a4110490d00200241c7006a290000210c200229003f210d200228004f210b2002280053210e20022d0057210f2002200920046a220141146a220936021020022007416c6a221036021420104104490d002001410c6a2900002111200141046a2900002112200928000021092002200741686a3602142002200141186a2210360210200841686a2004460d0320102d000021102002200741676a22133602142002200141196a360210201041014b0d034100210420100e020201020b20050d090c0a0b20134104490d01200141196a28000021082002200741636a36021420022001411d6a360210410121040b2002200228002b3600232002200228022836022020022002280220360230200220022800233600332002200228001936023820022002411c6a28000036003b41002101200521070c020b2005450d070c060b41002101200241003a00582004417f6a21082004417e6a21040340024020082001470d00200141ff0171450d08200241003a00580c080b200241386a20016a200320016a220741016a2d00003a00002002200741026a3602102002200141016a22073a0058200220043602142004417f6a21042007210120074120470d000b2002200228003b360033200220022802383602302002200228003336002b20022002280230360228200220022802283602202002200228002b360023200241c7006a2900002111200229003f2112200228004f21062002280053210720022d005721052002200228002336003b2002200228022036023820022002411c6a28000036003320022002280019360230410121010b200020013a000020002002280238360001200041106a2011370300200041086a2012370300200041c3006a200c3700002000413b6a200d370000200041046a200228003b360000200041306a20083602002000412c6a2004360200200041286a2009360200200041246a200a360200200041206a20053602002000411c6a2007360200200041186a2006360200200041346a2002280230360200200041376a2002280033360000200041d3006a200f3a0000200041cf006a200e360000200041cb006a200b3600002003102e0b200241e0006a24000f0b1032000b200520071035000b2005450d010b2006102e0b41eff0c2004133200241286a4184f4c2001053000b20054101102c000bde0801067f230041c0006b220224000240024002400240024002400240024002400240411010292203450d00200341086a41002900b0f541370000200341002900a8f54137000020024290808080800237020420022003360200410d20021047024002400240024020022802042204200228020822056b410d490d002005410d6a2106200228020021030c010b2005410d6a22062005490d0120044101742203200620062003491b22074100480d010240024020040d002007102921030c010b200228020020042007102a21030b2003450d042002200736020420022003360200200721040b20022006360208200320056a220541002900e1f441370000200541056a41002900e6f441370000200241206a2003200610d70220022802282206417f4c0d04200228022021050240024020060d00410121070c010b200610292207450d0620072005200610f6041a0b02402004450d002003102e0b02402002280224450d002005102e0b410110292203450d06200320012d00003a0000200341014102102a2203450d07200320012d00013a0001200341024104102a2203450d08200320012d00023a0002200320012d00033a0003200341044108102a2203450d09200320012d00043a0004200320012d00053a0005200320012d00063a0006200320012d00073a0007200341084110102a2203450d0a200320012d00083a0008200320012d00093a0009200320012d000a3a000a200320012d000b3a000b200320012d000c3a000c200320012d000d3a000d200320012d000e3a000e200320012d000f3a000f200341104120102a2203450d0b200320012d00103a0010200320012d00113a0011200320012d00123a0012200320012d00133a0013200320012d00143a0014200320012d00153a0015200320012d00163a0016200320012d00173a0017200320012d00183a0018200320012d00193a0019200320012d001a3a001a200320012d001b3a001b200320012d001c3a001c200320012d001d3a001d200320012d001e3a001e200320012d001f3a001f200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034120200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a200529030037030020022002290320370300200641206a22012006490d0020064101742204200120012004491b22054100480d000240024020060d002005102921040c010b200720062005102a21040b20040d0120054101102c000b102d000b200420066a22062002290300370000200641186a200241186a290300370000200641106a200241106a290300370000200641086a200241086a2903003700002003102e200020013602082000200536020420002004360200200241c0006a24000f0b41104101102c000b20074101102c000b1032000b20064101102c000b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000b8b0701077f23004190026b2202240041002103200241003a002820012802042104417f210502400240034020042003460d01200241086a20036a200128020022062d00003a00002001200420056a3602042001200641016a3602002002200341016a22073a00282005417f6a21052007210320074120470d000b200241e8006a41086a200241086a41086a290300370300200241e8006a41106a200241086a41106a290300370300200241e8006a41186a200241086a41186a2903003703002002200229030837036841002103200241003a0028200420076b2108200420056a21050340024020082003470d000240200341ff0171450d00200241003a00280b200041013a00000c030b200241086a20036a200620036a220741016a2d00003a0000200120053602042001200741026a3602002002200341016a22073a00282005417f6a21052007210320074120470d000b20024188016a41086a200241086a41086a29030037030020024188016a41106a200241086a41106a29030037030020024188016a41186a200241086a41186a290300370300200220022903083703880141002103200241003a008802200620076a2106034002402005417f470d000240200341ff0171450d00200241003a0088020b200041013a00000c030b200241e8016a20036a200620036a220741016a2d00003a0000200120053602042001200741026a3602002002200341016a22073a0088022005417f6a21052007210320074120470d000b200241a8016a41086a2201200241e8016a41086a290300370300200241a8016a41106a2203200241e8016a41106a290300370300200241a8016a41186a2205200241e8016a41186a290300370300200241086a41086a200241e8006a41086a290300370300200241086a41106a200241e8006a41106a290300370300200241086a41186a200241e8006a41186a290300370300200220022903e8013703a80120022002290368370308200241c0006a20024188016a41186a290300370300200241386a20024188016a41106a290300370300200241306a20024188016a41086a2903003703002002200229038801370328200241e0006a2005290300370300200241d8006a2003290300370300200241d0006a2001290300370300200220022903a801370348200041016a200241086a41e00010f6041a200041003a00000c010b0240200341ff0171450d00200241003a00280b200041013a00000b20024190026a24000ba60a01097f230041c0006b220224000240024002400240024002400240024002400240411010292203450d00200341086a41002900b19342370000200341002900a9934237000020024290808080800237020420022003360200410d20021047024002400240024020022802042204200228020822056b410d490d002005410d6a2106200228020021030c010b2005410d6a22062005490d0120044101742203200620062003491b22074100480d010240024020040d002007102921030c010b200228020020042007102a21030b2003450d042002200736020420022003360200200721040b20022006360208200320056a220541002900e1f441370000200541056a41002900e6f441370000200241206a2003200610d70220022802282206417f4c0d04200228022021050240024020060d00410121080c010b200610292208450d0620082005200610f6041a0b02402004450d002003102e0b02402002280224450d002005102e0b2001410c6a28020041046a2204417f4c0d04024002402004450d00200410292203450d0820024100360228200220043602240c010b200241003602282002200436022420024101360220410110292203450d08200241013602240b2002200336022020024101360228200320012d00003a00000240200228022422044101470d0041000d014102410241024102491b22044100480d01200341012004102a2203450d0920022004360224200220033602200b20024102360228200320012d00013a00010240024020044102460d00200421050c010b200441016a22052004490d0120044101742207200520052007491b22054100480d010240024020040d002005102921030c010b200320042005102a21030b2003450d0a20022005360224200220033602200b20024103360228200341026a20012d00023a0000024020054103470d00200541016a22042005490d0120054101742207200420042007491b22044100480d010240024020050d002004102921030c010b200320052004102a21030b2003450d0b20022004360224200220033602200b20024104360228200341036a20012d00033a000020012802042107200128020c2201200241206a10470240024020022802242205200228022822046b2001490d00200228022021030c010b200420016a22032004490d0120054101742209200320032009491b22094100480d010240024020050d002009102921030c010b200228022020052009102a21030b2003450d0c2002200936022420022003360220200921050b200320046a2007200110f6041a200241206a41186a22074200370300200241206a41106a22094200370300200241206a41086a220a4200370300200242003703202003200420016a200241206a1000200241186a2007290300370300200241106a2009290300370300200241086a200a29030037030020022002290320370300200641206a22012006490d0020064101742204200120012004491b22074100480d000240024020060d002007102921040c010b200820062007102a21040b20040d0120074101102c000b102d000b200420066a22062002290300370000200641186a200241186a290300370000200641106a200241106a290300370000200641086a200241086a29030037000002402005450d002003102e0b200020013602082000200736020420002004360200200241c0006a24000f0b41104101102c000b20074101102c000b1032000b20064101102c000b20044101102c000b41014101102c000b20044101102c000b20054101102c000b20044101102c000b20094101102c000b8d0302047f037e230041306b2205240002400240411410292206450d00200641002900d88c40370000200641106a41002800e88c40360000200641086a41002900e08c4037000020054294808080c002370224200520063602202001200541206a104a20052802242106200541086a200528022022072005280228106e200541086a41106a2903004200200528020822081b21092005290310420020081b210a02402006450d002007102e0b410121060240200a20027d220b200a56200920037d200a200254ad7d220a200956200a2009511b4101470d002000418b8cc000360204200041086a411d3602000c020b024002400240200b428080e983b1de16544100200a501b0d00200520012004200b200a105620052802002206450d022005280204210120002006360204200041086a20013602000c010b200041a88cc000360204200041086a411a3602000b410121060c020b2001200b200a1073200041106a2003370300200041086a2002370300410021060c010b41144101102c000b20002006360200200541306a24000bd40602087f087e23004190016b220224000240024002400240411010292203450d0041002104200341002900b08f40370000200341086a41002900b88f40370000200242908080808002370274200220033602702001200241f0006a104a200228027421052002280278210320022802702106200241f0006a41186a22074200370300200241f0006a41106a22084200370300200241f0006a41086a220942003703002002420037037020062003200241f0006a1000200241d0006a41186a2007290300370300200241d0006a41106a2008290300370300200241d0006a41086a20092903003703002002200229037037035020024100360270200241d0006a4120200241f0006a1008210320022802702207417f460d022003450d0220074110490d0120074170714110460d012007417c714120460d01200341086a290000210a2003290000210b200341186a290000210c2003290010210d200328002021072003102e410121040c030b41104101102c000b41eff0c2004133200241f0006a4184f4c2001053000b0b02402005450d002006102e0b4200210e4200210f024002402004450d00411410292203450d01200341002900d88c40370000200341106a41002800e88c40360000200341086a41002900e08c4037000020024294808080c002370274200220033602702001200241f0006a104a20022802742106200241386a200228027022012002280278106e200241386a41106a290300210e42002110200228023821032002290340211102402006450d002001102e0b200e420020031b210f2011420020031b2111200241306a41b0f3c200410d107d200241106a200c420041002002280234410020022802301b220320076b2206200620034b1bad220e420010fb04200241206a200e4200200d420010fb04200242004200200d420010fb044200210e02402002290308200229031884420052200241206a41086a290300220c200229030020022903107c7c220d200c54720d00200a200d20022903202210200b54200d200a54200d200a511b22031b200d7d200b201020031b220d201054ad7d210e200d20107d21100b200e200f2011201056200f200e56200f200e511b22031b210f2010201120031b210e0b2000200e3703002000200f37030820024190016a24000f0b41144101102c000ba907030d7f037e037f230041e0006b22022400024002400240024002400240410e10292203450d00200341002900848d40370000200341066a410029008a8d403700002002428e808080e001370244200220033602402001200241c0006a104a200228024421042002280248210320022802402105200241c0006a41186a22014200370300200241c0006a41106a22064200370300200241c0006a41086a220742003703002002420037034020052003200241c0006a1000200241086a41186a2001290300370300200241086a41106a2006290300370300200241086a41086a20072903003703002002200229034037030820024100360240200241086a4120200241c0006a100821080240024020022802402209417f460d002002200936022c200220083602282002200241286a103120022802000d07200228022c22034160712201417f4c0d032002280204210a024002402003410576220b0d004108210c0c010b20011029220c450d050b0240200a450d004100210d4100210e410021070340200241c0006a200241286a107e0240024020022d00404101460d00200228022c22014110490d002002290041210f20022002280228220341106a3602282002200141706a220636022c20064104490d00200341086a29000021102003290000211120022001416c6a220636022c2002200341146a36022820060d010b200b450d0a200c102e0c0a0b200741016a210620032800102112200241366a41026a2002413d6a41026a2d000022133a0000200241326a41026a221420133a000020022001416b6a36022c2002200341156a360228200220022f003d22013b0136200220013b013220032d0014210102402007200b470d00200d20062006200d491b220b41ffffff3f71200b470d09200b41057422034100480d090240024020070d0020031029210c0c010b200c200e2003102a210c0b200c450d080b200c200e6a2203411c6a20013a00002003201037030820032011370300200341146a200f370200200341106a20123602002003411d6a20022f01323b00002003411f6a20142d00003a0000200d41026a210d200e41206a210e20062107200a2006470d000b0b200c450d07200aad422086200bad84210f02402009450d002008102e0b2000200f3702042000200c3602000c010b20004100360208200042083702000b02402004450d002005102e0b200241e0006a24000f0b410e4101102c000b1032000b20014108102c000b20034108102c000b102d000b41eff0c2004133200241c0006a4184f4c2001053000bbd0101027f230041206b22032400200341106a41086a220442003703002003420037031020012002200341106a1003200341086a200429030037030020032003290310370300410021022003410036021020034110200341106a1008210102400240024020032802102204417f470d000c010b024020010d000c010b20044104490d01200128000021042001102e410121020b2000200436020420002002360200200341206a24000f0b41eff0c2004133200341106a4184f4c2001053000bf00204027f017e017f077e0240024020012802042202450d0020012802002203310000210420012002417f6a22053602042001200341016a3602002005450d012003310001210620012002417e6a22053602042001200341026a3602002005450d012003310002210720012002417d6a22053602042001200341036a3602002005450d012003310003210820012002417c6a22053602042001200341046a3602002005450d012003310004210920012002417b6a22053602042001200341056a3602002005450d012003310005210a20012002417a6a22053602042001200341066a3602002005450d012003310006210b2001200241796a22053602042001200341076a3602002005450d01200041003a00002003310007210c2001200241786a3602042001200341086a3602002000200c423886200b42308684200a422886842009422086842008421886842007421086842006420886842004843700010f0b200041013a00000f0b200041013a00000b971d05047f017e057f017e037f23004190056b2200240020004198036a41086a22014200370300200042003703980341c8dec500411020004198036a1003200041a0026a41086a200129030037030020002000290398033703a0022000410036029004200041a0026a411020004190046a10082101024002400240024002400240024002400240024002402000280290042202417f460d002001450d002002450d0120012d000021022001102e20024102460d0020024101710d030b200041013a00900420004198036a41086a22014200370300200042003703980341c8dec500411020004198036a1003200041a0026a41086a2202200129030037030020002000290398033703a002200041a0026a411020004190046a4101100420014200370300200042003703980341d2f3c200410d20004198036a10032002200129030037030020002000290398033703a0022000410036029004200041a0026a411020004190046a1008210102402000280290042202417f460d002001450d002000200236029c03200020013602980320004190046a20004198036a103f02402000280290042203450d00200029029404210402402002450d002001102e0b2004422088a721052004a721060c030b41eff0c200413320004188056a4184f4c2001053000b4104210341002105410021060c010b41eff0c200413320004188056a4184f4c2001053000b2003200541246c22026a210720032101024002400240200241ed00490d0020004190046a41017221082003210103400240024020012d00004101460d00200041a8016a200041a0026a41f70010f6041a0c010b200141016a2800002102200141086a28020021092000200141106a28020036028c01200020093602880102400240200241c28289aa04460d00410221020c010b20004190046a20004188016a108001024020002d00900422024102470d00410221020c010b20004198036a200841f70010f6041a200041a0026a20004198036a41f70010f6041a0b200041a8016a200041a0026a41f70010f6041a20024102460d00200041a8016a21010c030b02400240200141246a2d00004101460d00200041a8016a200041a0026a41f70010f6041a0c010b200141256a28000021022001412c6a28020021092000200141346a28020036028c01200020093602880102400240200241c28289aa04460d00410221020c010b20004190046a20004188016a108001024020002d00900422024102470d00410221020c010b20004198036a200841f70010f6041a200041a0026a20004198036a41f70010f6041a0b200041a8016a200041a0026a41f70010f6041a20024102460d00200041a8016a21010c030b02400240200141c8006a2d00004101460d00200041a8016a200041a0026a41f70010f6041a0c010b200141c9006a2800002102200141d0006a28020021092000200141d8006a28020036028c01200020093602880102400240200241c28289aa04460d00410221020c010b20004190046a20004188016a108001024020002d00900422024102470d00410221020c010b20004198036a200841f70010f6041a200041a0026a20004198036a41f70010f6041a0b200041a8016a200041a0026a41f70010f6041a20024102460d00200041a8016a21010c030b02400240200141ec006a2d00004101460d00200041a8016a200041a0026a41f70010f6041a0c010b200141ed006a2800002102200141f4006a28020021092000200141fc006a28020036028c01200020093602880102400240200241c28289aa04460d00410221020c010b20004190046a20004188016a108001024020002d00900422024102470d00410221020c010b20004198036a200841f70010f6041a200041a0026a20004198036a41f70010f6041a0b200041a8016a200041a0026a41f70010f6041a20024102460d00200041a8016a21010c030b200720014190016a22016b41ec004b0d000b0b024020012007460d002003200541246c6a210720004190046a410172210803400240024020012d00004101460d00200041a8016a200041a0026a41f70010f6041a0c010b200141016a2800002102200141086a28020021092000200141106a28020036028c01200020093602880102400240200241c28289aa04460d00410221020c010b20004190046a20004188016a108001024020002d00900422024102470d00410221020c010b20004198036a200841f70010f6041a200041a0026a20004198036a41f70010f6041a0b200041a8016a200041a0026a41f70010f6041a20024102460d00200041a8016a21010c030b2007200141246a2201470d000b0b02402005450d00200541246c21022003210103400240024020012d0000220741034b0d0002400240024020070e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012002415c6a22020d000b0b20060d010c020b200020012900003703782000200141076a29000037007f200129000f2104200041206a200141176a41d80010f6041a200129006f210a20002000290378370388012000200029007f37008f0120004190046a200041206a41d80010f6041a200041106a41a9ddc5004113108101024002402000290318500d0020002802100d010b20004198036a41086a22014200370300200042003703980341a9ddc500411320004198036a1003200041a0026a41086a200129030037030020002000290398033703a00220002004200a20024101461b37039803200041a0026a411020004198036a410810040b20004198036a41086a22014200370300200042003703980341bcddc500411020004198036a1003200041a0026a41086a200129030037030020002000290398033703a00220002004200a20024101461b37039803200041a0026a411020004198036a41081004024020020d0020004198016a41086a20004190046a41086a2d00003a000020002000290388013703a8012000200029008f013700af01200020002903900437039801200041086a41a1dec5004111107d20002802082107200028020c2109411610292201450d032001410e6a41002900c0de45370000200141086a41002900bade45370000200141002900b2de4537000020014116412c102a2202450d0420022009410020071b220836001620004198036a41186a2207420037030020004198036a41106a2209420037030020004198036a41086a2201420037030020004200370398032002411a20004198036a1000200041a0026a41186a2007290300370300200041a0026a41106a2009290300370300200041a0026a41086a200129030037030020002000290398033703a00220004198036a200041a0026a108201200128020021092000280298032101200028029c0321072002102e2007410020011b21072001410120011b2102024002402009410020011b2201418002490d00412010292201450d07200120002903a8013700002001200437000f2001200029039801370017200141076a20002900af013700002001411f6a20004198016a41086a2d00003a0000411610292209450d082009410e6a41002900c0de45370000200941086a41002900bade45370000200941002900b2de4537000020094116412c102a2209450d092009200841016a220b36001620004198036a41186a220c420037030020004198036a41106a220d420037030020004198036a41086a2208420037030020004200370398032009411a20004198036a1000200041a0026a41186a200c290300370300200041a0026a41106a200d290300370300200041a0026a41086a220c200829030037030020002000290398033703a00220004198036a20014101108301200041a0026a4120200028029803220d20002802a00310040240200028029c03450d00200d102e0b2009102e2001102e20084200370300200042003703980341a1dec500411120004198036a1003200c200829030037030020002000290398033703a0022000200b36029803200041a0026a411020004198036a410410040c010b200041a0026a41086a220b20004198016a41086a2d00003a0000200020002903a80137039803200020002900af0137009f0320002000290398013703a002200141016a2109024020072001470d00024020014101742207200920092007491b2207410574220c4100480d000240024020010d00200c102921020c010b20022001410574200c102a21020b20020d01200c4101102c000b102d000b200220014105746a2201200029039803370000200029009f03210a2001200437000f200141076a200a370000200120002903a0023700172001411f6a200b2d00003a0000411610292201450d092001410e6a41002900c0de45370000200141086a41002900bade45370000200141002900b2de4537000020014116412c102a2201450d0a2001200836001620004198036a41186a2208420037030020004198036a41106a220b420037030020004198036a41086a220c420037030020004200370398032001411a20004198036a1000200041a0026a41186a2008290300370300200041a0026a41106a200b290300370300200041a0026a41086a200c29030037030020002000290398033703a00220004198036a20022009108301200041a0026a4120200028029803220920002802a00310040240200028029c03450d002009102e0b2001102e0b2007450d002002102e0b02402005450d00200541246c21022003210103400240024020012d0000220741034b0d0002400240024020070e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012002415c6a22020d000b0b2006450d010b2003102e0b20004190056a24000f0b41164101102c000b412c4101102c000b41204101102c000b41164101102c000b412c4101102c000b41164101102c000b412c4101102c000bb30a03067f017e067f230041f0016b2202240002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541014b0d0420050e020102010b200041023a00000c070b20064104490d012004280001210720012003417b6a22053602042001200441056a36020020054108490d05200429000521082001200341736a220536020420012004410d6a36020020054104490d04200428000d210920012003416f6a3602042001200441116a36020041002105200241003a00b001411120036b210a2003416e6a210603400240200a20056a0d000240200541ff0171450d00200241003a00b0010b200041023a00000c080b20024190016a20056a200420056a220b41116a2d00003a0000200120063602042001200b41126a3602002002200541016a220b3a00b0012006417f6a2106200b2105200b4120470d000b200241f0006a41186a20024190016a41186a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41086a20024190016a41086a290300370300200220022903900137037041002105200241003a00d0012004200b6a210a200b20036b41116a210303400240200320056a0d000240200541ff0171450d00200241003a00d0010b200041023a00000c080b20024190016a20056a200a20056a220441116a2d00003a0000200120063602042001200441126a3602002002200541016a22043a00d0012006417f6a210620042105200441c000470d000b200241106a41386a220120024190016a41386a290300370300200241106a41306a220420024190016a41306a290300370300200241106a41286a220520024190016a41286a290300370300200241106a41206a220320024190016a41206a290300370300200241106a41186a220620024190016a41186a290300370300200241106a41106a220b20024190016a41106a290300370300200241106a41086a220a20024190016a41086a290300370300200241d0006a41086a220c200241f0006a41086a290300370300200241d0006a41106a220d200241f0006a41106a290300370300200241d0006a41186a220e200241f0006a41186a290300370300200220022903900137031020022002290370370350200041003a000020002002290350370001200041096a200c290300370000200041116a200d290300370000200041196a200e290300370000200041216a2002290310370000200041296a200a290300370000200041316a200b290300370000200041396a2006290300370000200041c1006a2003290300370000200041c9006a2005290300370000200041d1006a2004290300370000200041d9006a2001290300370000200041e3006a2002410f6a2d00003a0000200041e1006a20022f000d3b0000200041f0006a2008370300200041e8006a2009360200200041e4006a20073602000c060b20064104490d022004280001210620012003417b6a22053602042001200441056a36020020054108490d02200429000521082001200341736a220536020420012004410d6a36020020054104490d02200428000d210520012003416f6a3602042001200441116a360200200041013a0000200020022f00103b0001200041106a2008370300200041086a2005360200200041046a2006360200200041036a200241126a2d00003a0000200041186a20024190016a41e00010f6041a0c050b200041023a00000c040b200041023a00000c030b200041023a00000c020b200041023a00000c010b200041023a00000b200241f0016a24000bc30104017f017e017f017e230041206b2203240042002104200341106a41086a220542003703002003420037031020012002200341106a1003200341086a2005290300370300200320032903103703002003410036021020034110200341106a1008210102400240024020032802102202417f470d000c010b024020010d000c010b20024108490d01200129000021062001102e420121040b2000200637030820002004370300200341206a24000f0b41eff0c2004133200341106a4184f4c2001053000b8505010e7f230041e0006b220224002002410036023820014120200241386a1008210302400240024002400240024020022802382204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a103120022802080d04200228021422054160712201417f4c0d01200228020c210602400240200541057622070d00410121080c010b200110292208450d030b02402006450d004100210903402005210a200241003a00582009220b41016a2109410021010240024002400340200a2001460d01200241386a20016a2002280210220c2d00003a00002002200c41016a3602102002200141016a220c3a0058200c2101200c4120470d000b200241186a41186a220d200241386a41186a290300370300200241186a41106a220e200241386a41106a290300370300200241186a41086a220f200241386a41086a290300370300200220022903383703182007200b470d020240200b4101742201200920092001491b220741ffffff3f712007470d002007410574220141004e0d020b102d000b200241003602140240200141ff0171450d00200241003a00580b2007450d082008102e0c080b02400240200b0d002001102921080c010b2008200b4105742001102a21080b2008450d060b200a200c6b21052008200b4105746a22012002290318370000200141186a200d290300370000200141106a200e290300370000200141086a200f29030037000020092006470d000b2002200a200c6b3602140b2008450d042000200736020420002008360200200041086a20063602002004450d002003102e0b200241e0006a24000f0b1032000b20014101102c000b20014101102c000b41eff0c2004133200241386a4184f4c2001053000ba72601047f230041106b22032400200341003602082003420137030020022003104702400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402002450d00200120024105746a2104034002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0320032006360204200320053602000b2003200241016a360208200520026a20012d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0420032006360204200320053602000b2003200241016a360208200520026a200141016a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0520032006360204200320053602000b2003200241016a360208200520026a200141026a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0620032006360204200320053602000b2003200241016a360208200520026a200141036a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0720032006360204200320053602000b2003200241016a360208200520026a200141046a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0820032006360204200320053602000b2003200241016a360208200520026a200141056a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0920032006360204200320053602000b2003200241016a360208200520026a200141066a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0a20032006360204200320053602000b2003200241016a360208200520026a200141076a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0b20032006360204200320053602000b2003200241016a360208200520026a200141086a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0c20032006360204200320053602000b2003200241016a360208200520026a200141096a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0d20032006360204200320053602000b2003200241016a360208200520026a2001410a6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0e20032006360204200320053602000b2003200241016a360208200520026a2001410b6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0f20032006360204200320053602000b2003200241016a360208200520026a2001410c6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1020032006360204200320053602000b2003200241016a360208200520026a2001410d6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1120032006360204200320053602000b2003200241016a360208200520026a2001410e6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1220032006360204200320053602000b2003200241016a360208200520026a2001410f6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1320032006360204200320053602000b2003200241016a360208200520026a200141106a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1420032006360204200320053602000b2003200241016a360208200520026a200141116a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1520032006360204200320053602000b2003200241016a360208200520026a200141126a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1620032006360204200320053602000b2003200241016a360208200520026a200141136a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1720032006360204200320053602000b2003200241016a360208200520026a200141146a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1820032006360204200320053602000b2003200241016a360208200520026a200141156a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1920032006360204200320053602000b2003200241016a360208200520026a200141166a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1a20032006360204200320053602000b2003200241016a360208200520026a200141176a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1b20032006360204200320053602000b2003200241016a360208200520026a200141186a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1c20032006360204200320053602000b2003200241016a360208200520026a200141196a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1d20032006360204200320053602000b2003200241016a360208200520026a2001411a6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1e20032006360204200320053602000b2003200241016a360208200520026a2001411b6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1f20032006360204200320053602000b2003200241016a360208200520026a2001411c6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d2020032006360204200320053602000b2003200241016a360208200520026a2001411d6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d2120032006360204200320053602000b2003200241016a360208200520026a2001411e6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d2220032006360204200320053602000b2003200241016a360208200520026a2001411f6a2d00003a0000200141206a22012004470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b820304037f017e017f037e230041c0006b2202240002400240411410292203450d00200341002900d88c40370000200341106a41002800e88c40360000200341086a41002900e08c4037000020024294808080c002370234200220033602302001200241306a104a20022802342103200241186a200228023022042002280238106e200241186a41106a2903002105200228021821062002290320210702402003450d002004102e0b411810292203450d012005420020061b21082007420020061b2107200341002900ec8c40370000200341106a41002900fc8c40370000200341086a41002900f48c40370000200242988080808003370234200220033602302001200241306a104a200228023421032002200228023022062002280238106e200241106a2903004200200228020022011b21092002290308420020011b210502402003450d002006102e0b2000200520077c22073703002000200920087c2007200554ad7c370308200241c0006a24000f0b41144101102c000b41184101102c000b8e0e06017f037e017f017e017f067e230041f0016b220724004200210842002109024020050d00200741a0016a2006ad42004280c8afa025420010fb04200741a8016a29030020072903a001220a4280a094a58d1d7c2208200a54ad7c21090b200741d0016a41086a22054200370300200742003703d00141e8e4c500411b200741d0016a1003200741b0016a41086a220b2005290300370300200720072903d0013703b00120074190016a200741b0016a1086012007280290012105200729039801210a2007418094ebdc033602b4012007200a420020051b220a200a423f87220c7c200c85220c200c428094ebdc037f220c4280ec94a37c7e7ca722053602b00120074180016a417f2004418094ebdc032004418094ebdc03491b2204417f417f2004ad200ca7417f200c428080808010541bad7e220ca7200c422088a71b2206200741b0016a2005418094ebdc034b4102746a28020022052004418094ebdc036e220d6c2005ad2004200d4180ec94a37c6c6aad7e428094ebdc0380a76a6a220520052006491b22056a220620062004491b4100200420056b2205200520044b1b200a4200551bad420042e807420010fb0441012104200741b0016a2003427f20082007290380017c220a20017c220c200c200a542205200920074180016a41086a2903007c200a200854ad7c220820027c2005ad7c220a200854200a2008511b22051b220e427f200a20051b220f4101107a0240024020072802b0014101470d00200041003a00010c010b200741b0016a41106a290300210a200741386a200b290300220242004204420010fb04200741286a420042002002420010fb04200741c8006a2007290338200741386a41086a2903002208200a42028620072903287c7c220c4205420010fc0420072903302109200741c8006a41086a290300210120072903482110200741b0016a108701200741f0006a200741b0016a42b3e6cc99b3e6cc99332010200a200a42ffffffffffffffff3f8352200942005272200c2008547222041b22082002200820025442b3e6cc99b3e6cc9933200120041b220c200a54200c200a511b22041b2208200c200a20041b220c106d200741f0006a41086a290300211020072903702109200741d8006a41c28cc00041161070200820097d200920087d20092008582010200c582010200c5122041b22051b2111200c20107d2008200954ad7d2010200c7d2009200854ad7d20051b2112200a200c7d2002200854ad7d2101200220087d210a200741d8006a41106a2903004200200728025822051b21022007290360420020051b21130240024020092008562010200c5620041b0d00200741e0016a41086a22044200370300200742003703e00141c28cc0004116200741e0016a1003200741d0016a41086a2004290300370300200720072903e0013703d00120074200200220127d2013201154ad7d2208201320117d220c201356200820025620082002511b22041b3703e80120074200200c20041b3703e001200741e0016a21040c010b200741e0016a41086a22044200370300200742003703e00141c28cc0004116200741e0016a1003200741d0016a41086a2004290300370300200720072903e0013703d0012007427f200220127c201320117c220c2013542204ad7c22082004200820025420082002511b22041b3703e8012007427f200c20041b3703e001200741e0016a21040b200741d0016a4110200441101004200741b0016a108801200741186a200741b0016a200a2001106d200741186a41086a290300210c20072903182108200741c28cc00041161070200a20087d2008200a7d2008200a58200c200158200c20015122041b22051b21102001200c7d200a200854ad7d200c20017d2008200a54ad7d20051b2113200741106a2903004200200728020022051b21092007290308420020051b2102024002402008200a56200c20015620041b0d00200741e0016a41086a22044200370300200742003703e00141c28cc0004116200741e0016a1003200741d0016a41086a2004290300370300200720072903e0013703d00120074200200920137d2002201054ad7d2208200220107d220a200256200820095620082009511b22041b3703e80120074200200a20041b3703e001200741e0016a21040c010b200741e0016a41086a22044200370300200742003703e00141c28cc0004116200741e0016a1003200741d0016a41086a2004290300370300200720072903e0013703d0012007427f200920137c200220107c220a2002542204ad7c22082004200820095420082009511b22041b3703e8012007427f200a20041b3703e001200741e0016a21040b200741d0016a4110200441101004200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a200e427f200f501b370300410021040b200020043a0000200741f0016a24000b820102027f027e230041106b220224002002410036020420014110200241046a100821010240024020022802042203417f460d002001450d00024020034108490d00200129000021042001102e420121050c020b41eff0c2004133200241086a4184f4c2001053000b420021050b2000200437030820002005370300200241106a24000bbf0301077f230041d0006b22012400024002400240024002400240410110292202450d00200241ed003a0000200241014102102a2202450d01200241ef003a0001200241024104102a2202450d02200241e4d8013b0002200241044108102a2202450d03200241f0f2bda107360004200241084110102a2203450d04200341f2e6c9cb07360008200141003a0048410c210220032104410021050340200141003a0008200141086a20042002410047220610f6041a024020020d00200141003a00080b20022006490d06200141286a20056a20012d00083a00002001200541016a22073a0048200220066b2102200420066a21042007210520074120470d000b200141086a41186a2202200141286a41186a290300370300200141086a41106a2206200141286a41106a290300370300200141086a41086a2204200141286a41086a290300370300200120012903283703082003102e200041186a2002290300370000200041106a2006290300370000200041086a200429030037000020002001290308370000200141d0006a24000f0b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b200620021035000bee0b03047f017e057f230041c0016b22012400200141306a41086a220242003703002001420037033041eef4c1004111200141306a1003200141206a41086a200229030037030020012001290330370320200141c0006a200141206a411010dc010240024020012d00404101470d0020002001290041370000200041186a200141d9006a290000370000200041106a200141c0006a41116a290000370000200041086a200141c9006a2900003700000c010b200242003703002001420037033041d2f3c200410d200141306a1003200141c0006a41086a20022903003703002001200129033037034020014100360200200141c0006a411020011008210202400240024020012802002203417f460d002002450d0020012003360234200120023602302001200141306a103f20012802002204450d02200129020421052003450d012002102e0c010b41042104420021050b20042005422088a7220641246c6a210720042102024002400240034002400240200720026b41ed00490d0003400240200222032d00004101470d00200341246a2108200341106a2109200341086a210a200341016a21020c030b0240200341246a2d00004101470d00200341c8006a2108200341346a21092003412c6a210a200341256a21020c030b0240200341c8006a2d00004101470d00200341ec006a2108200341d8006a2109200341d0006a210a200341c9006a21020c030b0240200341ec006a2d00004101470d0020034190016a2108200341fc006a2109200341f4006a210a200341ed006a21020c030b200720034190016a22026b41ec004b0d000b20034190016a21020b20022007460d020240034020022d00004101460d012007200241246a2202460d040c000b0b200241246a2108200241106a2109200241086a210a200241016a21020b20022800002102200a280200210320012009280200360204200120033602000240200241c28289aa04460d00200821020c010b0b200141c0006a200110800120012d004022024102460d00200141a4016a28020021092001280244210a200141306a41086a220342003703002001420037033041fff4c1004112200141306a1003200141206a41086a20032903003703002001200129033037032020014100360240200141206a4110200141c0006a1008210720012802402203417f460d002001200336020420012007360200200141c0006a2001103020012802402208450d02200a200920024101711b2102200141c8006a28020021092001280244210a02402003450d002007102e0b0240200920024d0d00200141186a2203200820024105746a220241186a290000370300200141106a2207200241106a290000370300200141086a2209200241086a290000370300200120022900003703000240200a450d002008102e0b200141c0006a41186a22022003290300370300200141c0006a41106a22032007290300370300200141c0006a41086a2207200929030037030020012001290300370340200141306a41086a220942003703002001420037033041eef4c1004111200141306a1003200141206a41086a200929030037030020012001290330370320200141103602342001200141206a360230200141c0006a200141306a109a02200041186a2002290300370000200041106a2003290300370000200041086a2007290300370000200020012903403700000c020b200a450d002008102e0b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000b02402006450d00200641246c21032004210203400240024020022d0000220741034b0d0002400240024020070e0404000102040b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022003415c6a22030d000b0b2005a7450d022004102e0c020b41eff0c2004133200141b8016a4184f4c2001053000b41eff0c2004133200141b8016a4184f4c2001053000b200141c0016a24000b1300200041023602042000418c90c0003602000b3400200041d8e9c10036020420004100360200200041146a4105360200200041106a41ac9fc000360200200041086a42083702000b3701017f02404110102922020d0041104101102c000b2002420037000820024200370000200042908080808002370204200020023602000bdb0a02077f027e230041e0016b220324000240024002400240411810292204450d00200441002900ec8c40370000200441106a41002900fc8c40370000200441086a41002900f48c40370000200342988080808003370254200320043602502000200341d0006a104a200328025421052003280258210620032802502104200341c0016a41186a22074200370300200341c0016a41106a22084200370300200341c0016a41086a22094200370300200342003703c00120042006200341c0016a1000200341d0006a41186a2007290300370300200341d0006a41106a2008290300370300200341d0006a41086a2009290300370300200320032903c001370350200320023703c801200320013703c001200341d0006a4120200341c0016a4110100402402005450d002004102e0b0240200142ffffe883b1de165620024200522002501b0d00411810292204450d02200441002900ec8c40370000200441106a41002900fc8c40370000200441086a41002900f48c40370000200342988080808003370254200320043602502000200341d0006a104a200328025421052003280258210620032802502104200341c0016a41186a22074200370300200341c0016a41106a22084200370300200341c0016a41086a22094200370300200342003703c00120042006200341c0016a1000200341d0006a41186a2007290300370300200341d0006a41106a2008290300370300200341d0006a41086a2009290300370300200320032903c001370350200341386a200341d0006a1074200341386a41106a2903002101200329034021022003280238210602402005450d002004102e0b02402002200184500d002006450d00200341206a41c28cc00041161070200341206a41106a290300210a2003290328210b20032802202104200341d0006a41086a220542003703002003420037035041c28cc0004116200341d0006a1003200341c0016a41086a2005290300370300200320032903503703c00120034200200a420020041b220a20017d200b420020041b2201200254ad7d220b200120027d2202200156200b200a56200b200a511b22041b37035820034200200220041b370350200341c0016a4110200341d0006a411010040b411410292204450d03200441002900d88c40370000200441106a41002800e88c40360000200441086a41002900e08c4037000020034294808080c002370254200320043602502000200341d0006a104a20032802542104200341086a200328025022062003280258106e200341086a41106a2903002102200329031021012003280208210502402004450d002006102e0b02402001200284500d0020050d010b411310292204450d04200441002900eff3423700002004410f6a41002800fef342360000200441086a41002900f7f34237000020034293808080b002370254200320043602502000200341d0006a104a200328025421052003280258210620032802502104200341c0016a41186a22074200370300200341c0016a41106a22084200370300200341c0016a41086a22094200370300200342003703c00120042006200341c0016a1000200341d0006a41186a2007290300370300200341d0006a41106a2008290300370300200341d0006a41086a22062009290300370300200320032903c001370350200341d0006a4120100602402005450d002004102e0b200641013a0000200341d9006a2000290000370000200341e1006a200041086a290000370000200341e9006a200041106a290000370000200341f1006a200041186a290000370000200341023a005041c8ecc5004100200341d0006a10720b200341e0016a24000f0b41184101102c000b41184101102c000b41144101102c000b41134101102c000b130020004105360204200041c8b0c0003602000baf0202057f037e230041c0006b22042400200441206a20011084010240024002402004290320200441206a41086a29030084500d00411410292205450d0241002106200541002900d88c40370000200541106a41002800e88c40360000200541086a41002900e08c4037000020044294808080c002370234200420053602302001200441306a104a20042802342105200441086a200428023022072004280238106e200441086a41106a2903004200200428020822081b21092004290310420020081b210a02402005450d002007102e0b2001200a20027c220b200920037c200b200a54ad7c1073200041106a2003370300200041086a20023703000c010b200041e98bc000360204200041086a4122360200410121060b20002006360200200441c0006a24000f0b41144101102c000b851507037f017e067f037e017f027e0a7f230041e0006b22032400200341b0f3c200410d107d2003280204210420032802002105200341186a427f3703002003412c6a41023a0000200341206a2002360200200341246a20002900003702002003427f3703104201210620034201370308200341c0006a2001107c41002107200328024021082003280244210902400240024002402003280248220a450d002004410020051b210502400240200341d4006a220b2000460d00200341dd006a210c200a410574210442012106200821020340200241086a290300210d200241106a290300210e2002290300210f200341c0006a41186a200241186a290300370300200341c0006a41106a200e370300200341c0006a41086a200d3703002003200f37034002400240200b2900002000290000510d002003280250221020054d0d012003413c6a41026a200c41026a2d00003a00002003200c2f00003b013c200241206a2102200341c8006a290300210e2003290340210f20032d005c21070c060b2003290308210d4200210620034200370308200d4201520d00200341086a41106a2903002111200341086a41086a2903002112200241206a2102200341086a41186a290300a7210b0c030b200241206a2102200441606a22040d000c030b0b200a4105742104200341086a41106a2903002111200341086a41086a2903002112200341086a41186a280200210b200329030821062008210202400340200241086a290300210d200241106a290300210e2002290300210f200341c0006a41186a200241186a290300370300200341c0006a41106a200e370300200341c0006a41086a200d3703002003200f3703402003420037030820064201510d01200241206a2102420021064100210b4200211242002111200441606a22040d000c030b0b200241206a21020b200341c8006a290300220620112003290340220d201256200620115620062011511b22041b210e200d201220041b210f20032802502204200b2004200b4b1b211020032d005c2003412c6a2d0000722107420021060c010b024020090d00410021104108210b410821020c020b2008102e4108210b41002110410821020c010b2003290254210d200341306a41026a22042003413c6a41026a2d00003a0000200320032f013c3b01300240024002400240024041201029220b450d00200b200f370300200b20073a001c200b200d370214200b2010360210200b20032f01303b001d200b200e370308200b411f6a20042d00003a000041012107024020022008200a4105746a2204470d00410121100c050b200341d4006a22102000460d01200341dd006a210c0340200341c0006a41186a200241186a290300370300200341c0006a41106a200241106a290300370300200341c0006a41086a200241086a290300370300200320022903003703400240024020102900002000290000510d002003280250220a20054d0d012003413c6a41026a200c41026a2d00003a00002003200c2f00003b013c200241206a2102200341c8006a290300210d2003290340210e20032d005c21130c060b2003290308210d4200210620034200370308200d4201520d00200341086a41106a290300210d200341086a41086a2903002106200241206a2102200341086a41186a290300a721100c040b2004200241206a2202470d000b410121100c040b41204108102c000b20032903084201512107200341086a41106a290300210d200341086a41086a2903002106200341086a41186a280200211002400340200341c0006a41186a200241186a290300370300200341c0006a41106a200241106a290300370300200341c0006a41086a200241086a290300370300200320022903003703402003420037030820074101710d0142002106410021074200210d410021102004200241206a2202470d000b41012107410121100c030b200241206a21020b200341c8006a290300220e200d2003290340220f200656200e200d56200e200d511b22071b210d200f200620071b210e200328025022072010200720104b1b210a20032d005c2003412c6a2d0000722113420021060b2003290254210f200341346a41026a22142003413c6a41026a22152d00003a0000200320032f013c3b0134200341dd006a2116200341d4006a210c200341086a41106a2117200341086a41086a2118200341086a41186a21192003412c6a211a41012107410121100340200341c0006a41026a221b20142d00003a0000200320032f01343b01400240024002400240024020102007470d00200741016a22102007490d082007410174221c20102010201c491b221041ffffff3f712010470d082010410574221c4100480d080240024020070d00201c1029210b0c010b200b2007410574201c102a210b0b200b450d010b200b20074105746a221c20133a001c201c200d370308201c200e370300201c200f370214201c200a360210201c20032f01403b001d201c411f6a201b2d00003a0000200741016a210720022004460d050240200c2000470d002017290300210d2018290300210e2019280200210a200329030821060340200341c0006a41186a200241186a290300370300200341c0006a41106a200241106a290300370300200341c0006a41086a200241086a290300370300200320022903003703402003420037030820064201510d03420021064100210a4200210e4200210d2004200241206a2202470d000c070b0b0340200341c0006a41186a200241186a290300370300200341c0006a41106a200241106a290300370300200341c0006a41086a221c200241086a2903003703002003200229030037034002400240200c2900002000290000510d002003280250220a20054d0d012015201641026a2d00003a0000200320162f00003b013c200241206a2102201c290300210d2003290340210e20032d005c21130c060b2003290308210d4200210620034200370308200d4201520d002017290300210d2018290300210e200241206a21022019290300a7210a0c040b2004200241206a2202470d000c060b0b201c4108102c000b200241206a21020b200341c0006a41086a2903002206200d2003290340220f200e562006200d562006200d511b221c1b210d200f200e201c1b210e2003280250221c200a201c200a4b1b210a20032d005c201a2d0000722113420021060b2003290254210f201420152d00003a0000200320032f013c3b01340c000b0b02402009450d002008102e0b200b21020b0240024020064201520d00200341c0006a41186a200341106a220041186a290300370300200341c0006a41106a200041106a290300370300200341c0006a41086a200041086a29030037030020032000290300370340024020102007470d00200741016a22022007490d0320074101742200200220022000491b221041ffffff3f712010470d03201041057422004100480d030240024020070d002000102921020c010b200b20074105742000102a21020b2002450d020b200220074105746a22002003290340370300200041186a200341c0006a41186a290300370300200041106a200341c0006a41106a290300370300200041086a200341c0006a41086a290300370300200741016a21070b2003200736024820032010360244200320023602402001200341c0006a109001200341e0006a24000f0b20004108102c000b102d000bcd1003097f027e027f230041c0006b220224000240024002400240024002400240024002400240024002400240410e10292203450d00200341002900848d40370000200341066a410029008a8d403700002002428e808080e001370224200220033602202000200241206a104a200228022421042002280228210320022802202105200241206a41186a22004200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020052003200241206a1000200241186a2000290300370300200241106a2006290300370300200241086a200729030037030020022002290320370300200128020021082001280208210320024100360228200242013703202003200241206a104702402003450d00200341057421094100210a034002400240200228022420022802282203460d00200228022021000c010b200341016a22002003490d0f20034101742206200020002006491b22064100480d0f0240024020030d002006102921000c010b200228022020032006102a21000b2000450d042002200636022420022000360220200228022821030b2002200341016a360228200020036a2008200a6a220341146a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d052002200736022420022006360220200228022821000b2002200041016a360228200620006a200341156a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d062002200736022420022006360220200228022821000b2002200041016a360228200620006a200341166a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d072002200736022420022006360220200228022821000b2002200041016a360228200620006a200341176a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d082002200736022420022006360220200228022821000b2002200041016a360228200620006a200341186a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d092002200736022420022006360220200228022821000b2002200041016a360228200620006a200341196a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d0a2002200736022420022006360220200228022821000b2002200041016a360228200620006a2003411a6a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d0b2002200736022420022006360220200228022821000b2002200041016a360228200620006a2003411b6a2d00003a0000200341086a290300210b2003290300210c0240024020022802242207200228022822066b4110490d00200228022021000c010b200641106a22002006490d0f20074101742206200020002006491b220d4100480d0f0240024020070d00200d102921000c010b20022802202007200d102a21000b2000450d0c2002200d3602242002200036022020022802282106200d21070b200020066a220d200b370008200d200c3700002002200641106a2206360228200341106a280200210d0240200720066b41034b0d00200641046a220e2006490d0f20074101742206200e200e2006491b22064100480d0f0240024020070d002006102921000c010b200020072006102a21000b2000450d0d2002200636022420022000360220200228022821060b2002200641046a360228200020066a200d36000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d0e2002200736022420022006360220200228022821000b2002200041016a360228200620006a2003411c6a2d00003a00002009200a41206a220a470d000b0b2002280224210320024120200228022022002002280228100402402003450d002000102e0b02402004450d002005102e0b0240200141046a280200450d002008102e0b200241c0006a24000f0b410e4101102c000b20064101102c000b20074101102c000b20074101102c000b20074101102c000b20074101102c000b20074101102c000b20074101102c000b20074101102c000b200d4101102c000b20064101102c000b20074101102c000b102d000bcc0c05037f017e057f0a7e017f230041d0006b22062400200641b0f3c200410d107d2006280204210720062802002108200641186a20033703002006412c6a20053a0000200641206a2004360200200641246a2000290000370200200620023703104201210920064201370308200641306a2001107c4100210a2006280230210b2006280234210c024002400240024002400240024002402006280238220d450d002007410020081b21080240200641c4006a220e2000460d00200d41057421052006290308220921022006290310220f2110200629031822112112200641086a41186a29030022132114200b210402400340200441086a2903002103200441106a290300211520042903002116200641306a41186a200441186a290300370300200641306a41106a22072015370300200641306a41086a200337030020062016370330024002400240200e2900002000290000510d00200628024020084b0d0120022103420021020c020b42002109200629032821174200210f4200211142002113420021032010211520122116201421180c010b2007290300211820062903382116200629033021152006290348211720022103420121020b20024201510d01200441206a210420032102200541606a22050d000b200641206a2013370300200620093703082006200f370310200620113703180c020b200641206a2014370300200620033703082006201037031020062012370318200441206a21040c030b200d4105742105200b41206a2104200641206a2903002118200641086a41206a2903002117200629031821162006290310211520062903082102034020024201510d02200441206a210442002102200541606a22050d000b42002109200642003703080b0240200c0d004100210d41082119410821040c030b200b102e410821194100210d410821040c020b42002103200642003703080b412010292219450d04201920173703182019201537030020192016370308201941106a2018370300024002402004200b200d4105746a2205470d004101210a4101210d0c010b200641c4006a210e200321024101210a4101210d034002400240200e2000460d00200221150340200641306a41186a200441186a290300370300200641306a41106a2207200441106a290300370300200641306a41086a200441086a29030037030020062004290300370330024002400240200e2900002000290000510d00200628024020084b0d0120152102420021150c020b420021032006420037030820062903282116420021022010211820122117201421090c010b2007290300210920062903382117200629033021182006290348211620152102420121150b024020154201510d00200221152005200441206a2204470d010c050b0b200441206a21040c010b20062903282116024003402006420037030820024201510d01420021022005200441206a2204470d000b420021030c030b200441206a210442002103420021022010211820122117201421090b0240200d200a470d00200a41016a2207200a490d06200a410174220d20072007200d491b220d41ffffff3f71200d470d06200d41057422074100480d0602400240200a0d002007102921190c010b2019200a4105742007102a21190b2019450d040b2019200a4105746a2207201737030820072018370300200741106a2009370300200741186a2016370300200a41016a210a20042005470d000b0b0240200c450d00200b102e0b20032109201921040b024020094201520d00200641306a41186a200641106a220041186a290300370300200641306a41106a200041106a290300370300200641306a41086a200041086a290300370300200620002903003703300240200d200a470d00200a41016a2204200a490d04200a4101742200200420042000491b220d41ffffff3f71200d470d04200d41057422004100480d0402400240200a0d002000102921040c010b2019200a4105742000102a21040b2004450d030b2004200a4105746a22002006290330370300200041186a200641306a41186a290300370300200041106a200641306a41106a290300370300200041086a200641306a41086a290300370300200a41016a210a0b2006200a3602382006200d360234200620043602302001200641306a109001200641d0006a24000f0b20074108102c000b20004108102c000b102d000b41204108102c000bfb0102047f027e230041306b220424000240411810292205450d00200541002900ec8c40370000200541106a41002900fc8c40370000200541086a41002900f48c40370000200442988080808003370224200420053602202001200441206a104a20042802242105200441086a200428022022062004280228106e200441086a41106a2903004200200428020822071b21082004290310420020071b210902402005450d002006102e0b20012009200220092009200256200820035620082003511b22051b22027d20082003200820051b22037d2009200254ad7d108c012000200337030820002002370300200441306a24000f0b41184101102c000bee0304047f027e017f027e230041d0006b220424000240024002400240411410292205450d00200541002900d88c40370000200541106a41002800e88c40360000200541086a41002900e08c4037000020044294808080c002370244200420053602402001200441c0006a104a20042802442105200441286a200428024022062004280248106e200441286a41106a2903004200200428022822071b21082004290330420020071b210902402005450d002006102e0b024020092002542205200820035420082003511b450d0041e1b3c0002105411521010c040b200441206a20014104200920027d2209200820037d2005ad7d22081056200428022022050d02411810292207450d0141002105200741002900ec8c40370000200741106a41002900fc8c40370000200741086a41002900f48c40370000200442988080808003370244200420073602402001200441c0006a104a20042802442107200441086a2004280240220a2004280248106e200441086a41106a2903004200200428020822061b210b2004290310420020061b210c02402007450d00200a102e0b2001200c20027c2202200b20037c2002200c54ad7c108c0120012009200810730c030b41144101102c000b41184101102c000b200428022421010b2000200136020420002005360200200441d0006a24000bb00304037f017e017f047e230041c0006b2203240002400240411810292204450d00200441002900ec8c40370000200441106a41002900fc8c40370000200441086a41002900f48c40370000200342988080808003370234200320043602302000200341306a104a20032802342104200341186a200328023022052003280238106e200341186a41106a2903002106200328021821072003290320210802402004450d002005102e0b411410292204450d0120022006420020071b22062008420020071b2208200156200620025620062002511b22071b21092001200820071b2102200441002900d88c40370000200441106a41002800e88c40360000200441086a41002900e08c4037000020034294808080c002370234200320043602302000200341306a104a200328023421042003200328023022052003280238106e200341106a2903004200200328020022071b210a2003290308420020071b210102402004450d002005102e0b2000200120027c220b200a20097c200b200154ad7c10732000200820027d200620097d2008200254ad7d108c01200341c0006a24000f0b41184101102c000b41144101102c000bbd4e06057f027e0c7f027e027f047e230041d0046b22012400200141b8036a41086a22024200370300200142003703b80341eea0c5004111200141b8036a1003200141d8036a41086a2002290300370300200120012903b8033703d803200141d8036a4110100602400240024002400240024002400240024002400240024002400240200041c0f000700d00200141d8036a1087010240024002400240411410292203450d00200341002900d88c40370000200341106a41002800e88c40360000200341086a41002900e08c4037000020014294808080c0023702f401200120033602f001200141d8036a200141f0016a104a20012802f4012103200141b0016a20012802f001220420012802f801106e200141b0016a41106a290300420020012802b00122051b210620012903b801420020051b210702402003450d002004102e0b200120073703c801200120063703d001200141f0036a2006370300200141d8036a41106a2007370300200141d8036a41086a41013a00002001410b3a00d80341c8ecc5004100200141d8036a1072200141003a00df01200142003703e801200142003703e001200141d8026a41086a22034200370300200142003703d80241ae98c5004112200141d8026a1003200141b8036a41086a2003290300370300200120012903d8023703b803200141003602d803200141b8036a4110200141d8036a1008210320012802d8032204417f460d012003450d01200120043602f401200120033602f001200141d8036a200141f0016a1041024020012802d8032205450d00200141e0036a280200210820012802dc03210902402004450d002003102e0b4100210a2005410420051b210b200545210c2008410020051b2205450d04200141e1036a210d20014198036a210e200141d8026a41206a210f200141f0016a41086a211020014190046a2111410021124100210a4100210302400240024003400240024002400240200a450d00200b20034102746a2104200b200320126a4102746a21080340200320054f0d02200141f0016a2004280200221310960120012903f0014201520d04200141d8026a201041e00010f6041a20012903c801221420012903d802221554200141c8016a41086a2903002206200141d8026a41086a29030022075420062007511b450d03200141013a00df010240201220036a221320054f0d0020082004280200360200200441046a2104200841046a2108200341016a22032005490d010c070b0b419481c000201320051038000b200b20034102746a21040340200320054f0d01200141f0016a2004280200221310960120012903f0014201520d03200141d8026a201041e00010f6041a20012903c801221420012903d80222155a200141c8016a41086a2903002206200141d8026a41086a29030022075a20062007511b0d02200441046a2104200141013a00df01200341016a22032005490d000c0b0b0b41b880c000200320051038000b2001201420157d3703c8012001200620077d2014201554ad7d3703d001411210292204450d03200441106a41002f00ffda403b0000200441086a41002900f7da40370000200441002900efda40370000200441124124102a2204450d0420042013360012200141d8036a41186a22084200370300200141d8036a41106a22164200370300200141d8036a41086a22174200370300200142003703d80320044116200141d8036a1000200141b8036a41186a2008290300370300200141b8036a41106a2016290300370300200141b8036a41086a2017290300370300200120012903d8033703b803200141b8036a412010062004102e200f20012903e802200141d8026a41186a290300109401200141a0016a200e20012903d802200141d8026a41086a2204290300106d200141e0016a41086a2208427f20082903002206200141a0016a41086a2903007c20012903e001220720012903a0017c22142007542208ad7c22072008200720065420072006511b22081b3703002001427f201420081b3703e00120012903d802210620112004290300370300200d200e290000370000200d41086a200e41086a290000370000200d41106a200e41106a290000370000200d41186a200e41186a2900003700002001200637038804200141023a00e0032001410b3a00d803200120133602840441c8ecc5004100200141d8036a10720b2012417f6a2112200a41016a210a200341016a22032005490d000b0b200a450d06200520034d0d06200b20034102746a2204200a4102746b2004200520036b41027410f7041a0c060b41124101102c000b41244101102c000b41eff0c2004133200141c8046a4184f4c2001053000b41144101102c000b4101210c410021054104210b0b4100210a0b200141d8026a41086a22034200370300200142003703d80241ae98c5004112200141d8026a1003200141b8036a41086a2003290300370300200120012903d8023703b803200141003602e003200142013703d8032005200a6b2203200141d8036a10470240024020030d0020012802e003210520012802dc03211320012802d80321040c010b2005410274200a4102746b210a20012802dc03211320012802e0032103410021080340200b20086a280200211002400240201320036b4104490d00200341046a210520012802d80321040c010b200341046a22052003490d0e20134101742204200520052004491b22124100480d0e0240024020130d002012102921040c010b20012802d80320132012102a21040b2004450d04200120123602dc03200120043602d803201221130b200120053602e003200420036a201036000020052103200a200841046a2208470d000b0b200141b8036a411020042005100402402013450d002004102e0b0240200c200945720d00200b102e0b024020012d00df010d00200141f8006a20012903c8012206200141c8016a41086a2203290300220742c0843d420010fc04200141e8006a20012903782214200141f8006a41086a290300221542c0fb42427f10fb04200141d8006a2014201542a0c21e420010fb04200320072007200141d8006a41086a29030020012903582215200620012903687c42018842ffffffff0f837c2214201554ad7c22152014200656201520075620152007511b22051b22157d20062006201420051b220754ad7d3703002001200620077d3703c801200141d8026a41086a22034200370300200142003703d80241c28cc0004116200141d8026a1003200141b8036a41086a22042003290300370300200120012903d8023703b80320014188016a200141b8036a10970120014188016a41106a29030021142001290390012106200128028801210520034200370300200142003703d80241c28cc0004116200141d8026a100320042003290300370300200120012903d8023703b80320012006420020051b22063703d80320012014420020051b22143703e003200141b8036a4110200141d8036a41101004200141e0016a41086a2203427f2003290300221820142015200620077d200656201420157d2006200754ad7d221920145620192014511b22031b7c20012903e00122142006200720031b7c22192014542203ad7c22062003200620185420062018511b22031b3703002001427f201920031b3703e001200141f0036a2015370300200141d8036a41106a2007370300200141d8036a41086a41033a00002001410b3a00d80341c8ecc5004100200141d8036a10720b200141d8036a108701200141f0016a200141d8036a20012903e0012206200141e0016a41086a29030022074102107a0240024020012802f0010d00200141f0016a41106a290300211520012903f8012114200141286a41c28cc00041161070200720157d2006201454ad7d201520077d2014200654ad7d20142006582015200758201520075122031b22051b211a200620147d201420067d20051b211b200141286a41106a2903004200200128022822051b21182001290330420020051b2119024002402014200656201520075620031b0d00200141d8026a41086a22034200370300200142003703d80241c28cc0004116200141d8026a1003200141b8036a41086a2003290300370300200120012903d8023703b8032001427f2018201a7c2019201b7c22072019542203ad7c22062003200620185420062018511b22031b3703e0022001427f200720031b3703d802200141d8026a21030c010b200141d8026a41086a22034200370300200142003703d80241c28cc0004116200141d8026a1003200141b8036a41086a2003290300370300200120012903d8023703b803200142002018201a7d2019201b54ad7d22062019201b7d2207201956200620185620062018511b22031b3703e00220014200200720031b3703d802200141d8026a21030b200141b8036a41102003411010040c010b41b1ecc00041ca001009200141d8026a41086a22034200370300200142003703d80241c28cc0004116200141d8026a1003200141b8036a41086a22042003290300370300200120012903d8023703b803200141c0006a200141b8036a109701200141c0006a41106a2903002114200129034821152001280240210520034200370300200142003703d80241c28cc0004116200141d8026a100320042003290300370300200120012903d8023703b8032001427f2014420020051b221420077c2015420020051b220720067c22152007542203ad7c22062003200620145420062014511b22031b3703f8012001427f201520031b3703f001200141b8036a4110200141f0016a411010040b20012903c8012106200141f0036a200141c8016a41086a290300370300200141e8036a2006370300200141d8036a41086a41043a00002001410b3a00d80341c8ecc5004100200141d8036a10720b20024200370300200142003703b80341ba8ec200411d200141b8036a1003200141d8026a41086a2002290300370300200120012903b8033703d802200141003602d803200141d8026a4110200141d8036a10082103024020012802d8032205417f460d002003450d00200120033602f001200120053602f40120054104490d062001200341046a3602f00120012005417c6a22043602f40120044104490d06200328000021132001200541786a3602f4012001200341086a3602f0012003280004210b200141d8036a200141f0016a103e20012802d8032212450d0620012902dc032118410021080240024020012802f40122050d000c010b20012005417f6a22103602f401200120012802f001220441016a3602f001024020042d00004101460d000c010b20104104490d0020012005417b6a3602f4012001200441056a3602f0012004280001210a410121080b2003102e2018422088a72110024020132000470d00024020080d002010ad42287e2206422088a70d042006a72203417f4c0d040240024020030d004108210a0c010b20031029220a450d060b4100210402402010450d00201041286c210841002104200a2103201221050340200541086a2903002106200541106a2903002107200541186a290300211420052903002115200341206a200541206a290300370300200341186a2014370300200341106a2007370300200341086a200637030020032015370300200341286a2103200441016a2104200541286a2105200841586a22080d000b0b20014180026a200b360200200141f0016a410c6a2004360200200141f0016a41086a20103602002001200a3602f401200141003602f001200141d8036a200141f0016a105c200141e3026a200141d8036a41086a280200360000200120012903d8033700db02200141d8036a410c6a200141df026a290000370000200141c6a4b9da043600d903200141023a00d803200120012900d8023700dd03200141d8036a1098012010450d01200a102e0c010b2010ad42287e2206422088a70d032006a72203417f4c0d030240024020030d00410821020c010b200310292202450d060b0240024020100d00410021040c010b201041286c21084100210420022103201221050340200541086a2903002106200541106a2903002107200541186a290300211420052903002115200341206a200541206a290300370300200341186a2014370300200341106a2007370300200341086a200637030020032015370300200341286a2103200441016a2104200541286a2105200841586a22080d000b0b20014184026a200b36020020014180026a2004360200200141f0016a410c6a2010360200200141f0016a41086a20023602002001200a3602f401200141013602f001200141d8036a200141f0016a105c200141e3026a200141d8036a41086a280200360000200120012903d8033700db02200141d8036a410c6a200141df026a290000370000200141c6a4b9da043600d903200141023a00d803200120012900d8023700dd03200141d8036a1098012010450d002002102e0b2018a7210a0240200b20136a2000470d00200141b8036a41086a22034200370300200142003703b80341dadcc500411b200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141003602e003200142013703d8032010200141d8036a104702402010450d002012201041286c6a21132012210503402005200141d8036a104a200541206a29030021060240024020012802dc03220420012802e00322036b4108490d0020012802d80321040c010b200341086a22082003490d0f20044101742203200820082003491b22034100480d0f0240024020040d002003102921040c010b20012802d80320042003102a21040b2004450d09200120033602dc03200120043602d80320012802e00321030b2001200341086a3602e003200420036a20063700002013200541286a2205470d000b0b20012802dc032103200141d8026a411020012802d803220520012802e003100402402003450d002005102e0b200141d8036a41106a2010360200200141e4036a200a360200200141d8036a41086a2012360200200141003602dc032001410a3a00d80341c8ecc5004100200141d8036a1072200141b8036a41086a22034200370300200142003703b80341ba8ec200411d200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141d8026a411010060c010b200a450d002012102e0b200141b8036a41086a22034200370300200142003703b80341d78ec2004115200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141003602d803200141d8026a4110200141d8036a1008210320012802d8032205417f460d092003450d092005450d0820032d0000220441034b0d080240024020040e0401090100010b2005417f6a41074b0d070c090b2003102e0c090b20124101102c000b1032000b20034108102c000b20034108102c000b20034101102c000b41eff0c2004133200141c8046a4184f4c2001053000b20032800052104200328000121052003102e024020052000470d00200141043602f001200120043602f401200141d8036a200141f0016a105c200141e3026a200141e0036a280200360000200120012903d8033700db02200141e4036a200141df026a290000370000200141c6a4b9da043600d903200141023a00d803200120012900d8023700dd03200141d8036a1098010b200420056a2000470d02200141003602f001200141b8036a41086a22034200370300200142003703b80341d78ec2004115200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141d8036a200141f0016a109901200141d8026a411020012802d803220320012802e0031004024020012802dc03450d002003102e0b200141023602dc032001410a3a00d80341c8ecc5004100200141d8036a10720c020b2005417f6a4108490d0020032800052104200328000121052003102e024020052000470d00200141033602f001200120043602f401200141d8036a200141f0016a105c200141e3026a200141e0036a280200360000200120012903d8033700db02200141e4036a200141df026a290000370000200141c6a4b9da043600d903200141023a00d803200120012900d8023700dd03200141d8036a1098010b200420056a2000470d01200141023602f001200141b8036a41086a22034200370300200142003703b80341d78ec2004115200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141d8036a200141f0016a109901200141d8026a411020012802d803220320012802e0031004024020012802dc03450d002003102e0b200141013602dc032001410a3a00d80341c8ecc5004100200141d8036a10720c010b41eff0c2004133200141c8046a4184f4c2001053000b200141b8036a41086a22034200370300200142003703b80341fbd8c0004110200141b8036a1003200141d8026a41086a22052003290300370300200120012903b8033703d802200141206a200141d8026a4110109a01200128022421022001280220211320034200370300200142003703b80341f5dcc5004115200141b8036a100320052003290300370300200120012903b8033703d802200141003602d803200141d8026a4110200141d8036a10082103024002400240024002400240024002400240024020012802d8032205417f460d002003450d002005450d0820032d000021052003102e20054102460d0020054101710d010b410410292205450d0120054100360200200141b8036a41086a22034200370300200142003703b803418bd9c0004115200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141003602e003200142013703d8034101200141d8036a1047200528020021100240024020012802dc03220820012802e00322046b4104490d0020012802d80321030c010b200441046a22032004490d0a20084101742212200320032012491b22124100480d0a0240024020080d002012102921030c010b20012802d80320082012102a21030b2003450d03200120123602dc03200120033602d803201221080b2001200441046a22123602e003200320046a2010360000200141d8026a411020032012100402402008450d002003102e0b2005102e410410292205450d0320054100360200200141b8036a41086a22034200370300200142003703b803418ceec0004116200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141003602e003200142013703d8034101200141d8036a1047200528020021100240024020012802dc03220820012802e00322046b4104490d0020012802d80321030c010b200441046a22032004490d0a20084101742212200320032012491b22124100480d0a0240024020080d002012102921030c010b20012802d80320082012102a21030b2003450d05200120123602dc03200120033602d803201221080b2001200441046a22123602e003200320046a2010360000200141d8026a411020032012100402402008450d002003102e0b2005102e200141b8036a41086a22034200370300200142003703b80341a2eec0004110200141b8036a1003200141d8026a41086a22052003290300370300200120012903b8033703d802200141003602d803200141d8026a4110200141d8036a41041004200141013a00d80320034200370300200142003703b80341f5dcc5004115200141b8036a100320052003290300370300200120012903b8033703d802200141d8026a4110200141d8036a410110040b200141b8036a41086a22034200370300200142003703b803418bd9c0004115200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141003602d803200141d8026a4110200141d8036a1008210320012802d8032205417f460d052003450d05200120053602f401200120033602f001200141d8036a200141f0016a104120012802d8032209450d04200141e0036a280200210020012802dc03210d2005450d072003102e0c070b41044104102c000b20124101102c000b41044104102c000b20124101102c000b41eff0c2004133200141c8046a4184f4c2001053000b41042109410021004100210d0c010b41eff0c2004133200141c8046a4184f4c2001053000b200141b8036a41086a22034200370300200142003703b803418ceec0004116200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d8024100210c200141003602d803200141d8026a4110200141d8036a100821030240024020012802d8032204417f460d002003450d00200120043602f401200120033602f001200141d8036a200141f0016a1041024020012802d803220c450d00200141e0036a280200210520012802dc0321112004450d022003102e0c020b41eff0c2004133200141c8046a4184f4c2001053000b0b02400240024002400240024020130d002000417f6a220320004b0d01200320004f0d01200920034102746a2203450d01200328020021020b200041002000419c7f6a22032003200041016a4b1b220f490d0120054100200c1b2112200c4104200c1b21102000200f6b210e200f450d042009200f4102746a210a2009210b0340200b280200211302400240024002400240201241014b0d004100210320120e020201020b4100210320122105034020032005410176220420036a22082013201020084102746a280200491b2103200520046b220541014b0d000b0b2013201020034102746a22052802002204460d022003201320044b6a21030c010b410021030b200120033602d80341d8eec000412e200141d8036a4188efc0001053000b201220034d0d032005200541046a2003417f7320126a41027410f7041a2012417f6a2112200b41046a220b200a460d040c000b0b41b2eec0004126109b01000b418cc6c5001058000b418080c0001058000b200e450d002009200a200e41027410f7041a0b41002103024002400240201241014b0d0020120e020201020b20122105034020032005410176220420036a22082002201020084102746a280200491b2103200520046b220541014b0d000b0b2002201020034102746a2802002205460d002003200220054b6a21030b02400240024002400240024002400240024020122003490d00201220114100200c1b2205460d01200521110c020b41c0c6c5001058000b200541016a22042005490d0720054101742208200420042008491b221141ffffffff03712011470d07201141027422044100480d070240024020050d002004102921100c010b201020054102742004102a21100b2010450d010b201020034102746a220541046a2005201220036b41027410f7041a2005200236020002400240200d200e460d00200d21160c010b200d41016a2203200d490d07200d4101742205200320032005491b221641ffffffff03712016470d07201641027422034100480d0702400240200d0d002003102921090c010b2009200d4102742003102a21090b2009450d020b2009200e4102746a20023602000240201241016a220c0d004198efc0001058000b200c200c41017622034d0d02201020034102746a280200210d0240200c4101710d00200c2003417f6a22034d0d04201020034102746a280200200d6a410176210d0b200141b8036a41086a22034200370300200142003703b803418bd9c0004115200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141003602e003200142013703d803200e41016a220e200141d8036a104702400240200e0d0020012802e003210b20012802dc03211320012802d80321050c010b2000410274200f4102746b41046a210a410020012802e00322036b210420012802dc0321132009210803402008280200210202400240201320046a4104490d0020012802d80321050c010b200341046a22052003490d092013410174220b20052005200b491b220b4100480d090240024020130d00200b102921050c010b20012802d8032013200b102a21050b2005450d072001200b3602dc03200120053602d803200b21130b200841046a21082001200341046a220b3602e003200520036a20023600002004417c6a2104200b2103200a417c6a220a0d000b0b200141d8026a41102005200b100402402013450d002005102e0b02402016450d002009102e0b200141b8036a41086a22034200370300200142003703b803418ceec0004116200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200142013703d803200141003602e003200c200141d8036a1047201241027441046a2112410020012802e00322036b210420012802dc0321132010210803402008280200210a02400240201320046a4104490d0020012802d80321050c010b200341046a22052003490d082013410174220b20052005200b491b220b4100480d080240024020130d00200b102921050c010b20012802d8032013200b102a21050b2005450d072001200b3602dc03200120053602d803200b21130b200841046a21082001200341046a220b3602e003200520036a200a3600002004417c6a2104200b21032012417c6a22120d000b200141d8026a41102005200b100402402013450d002005102e0b02402011450d002010102e0b200141b8036a41086a22034200370300200142003703b80341a2eec0004110200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d8022001200d3602d803200141d8026a4110200141d8036a410410040240200e41e500470d00200141186a41b0f3c200410d107d200d419a086a200128021c410020012802181b4b0d00200141b8036a41086a22054200370300200142003703b8034191f5c1004117200141b8036a1003200141d8026a41086a2005290300370300200120012903b8033703d802410810292205450d082005200d360004200541e400360000200141d8026a41102005410810042005102e0b20034200370300200142003703b80341e7e7c3004117200141b8036a1003200141d8036a41086a2003290300370300200120012903b8033703d8030240200141d8036a411041c8ecc500410041001005417f470d00200141086a41c5c1c200410d1081012001290310210620012802082103200141b8036a41086a22054200370300200142003703b80341e7e7c3004117200141b8036a1003200141d8036a41086a2005290300370300200120012903b8033703d80320012006420020031b3703f001200141d8036a4110200141f0016a410810040b200141b8036a41086a22034200370300200142003703b80341eef4c1004111200141b8036a1003200141d8036a41086a22052003290300370300200120012903b8033703d803200141d8036a4110100620034200370300200142003703b80341d49bc5004117200141b8036a100320052003290300370300200120012903b8033703d803200141d8036a4110100641cde2c5004113109c01220341ff01714102460d082003410171450d08200141b8036a41086a22034200370300200142003703b80341c8dec5004110200141b8036a1003200141d8036a41086a2003290300370300200120012903b8033703d803200141d8036a41101006200141d0046a24000f0b20044104102c000b20034104102c000b41b0efc0002003200c1038000b41b0efc0002003200c1038000b200b4101102c000b200b4101102c000b102d000b41084101102c000b41ccb7c2001058000ba70201047f23004190016b2202240002400240411210292203450d00200341106a41002f00ffda403b0000200341086a41002900f7da40370000200341002900efda40370000200341124124102a2203450d0120032001360012200241086a41186a22014200370300200241086a41106a22044200370300200241086a41086a220542003703002002420037030820034116200241086a1000200241f0006a41186a2001290300370300200241f0006a41106a2004290300370300200241f0006a41086a200529030037030020022002290308370370200241086a200241f0006a10ae010240024020022903084201510d00200042003703000c010b2000200241086a41e80010f6041a0b2003102e20024190016a24000f0b41124101102c000b41244101102c000b920102027f037e230041106b220224002002410036020420014110200241046a1008210102400240024020022802042203417f470d00420021040c010b20034110490d01200141086a2900002105200129000021062001102e420121040b2000200637030820002004370300200041106a2005370300200241106a24000f0b41eff0c2004133200241086a4184f4c2001053000bd20805047f017e047f027e047f230041d0006b22012400200141106a41086a220242003703002001420037031041d2f3c200410d200141106a1003200141086a2002290300370300200120012903103703002001410036021020014110200141106a1008210202400240024002400240024020012802102203417f460d002002450d002001200336023c20012002360238200141106a200141386a103f20012802102204450d022001290214210502402003450d002002102e0b2005422088a721062005a721030c010b410421044100210642002105410021030b200141106a41206a2207200041206a280200360200200141106a41186a2208200041186a290200370300200141106a41106a2209200041106a290200370300200141106a41086a2202200041086a29020037030020012000290200370310024020062003470d00024020062005a7470d00200641016a22002006490d0520064101742203200020002003491bad220a42247e220b422088a70d05200ba722004100480d050240024020060d002000102921040c010b2004200641246c2000102a21040b2004450d03200542808080807083200a8421050b2005422088a721060b2004200641246c22036a22002001290310370200200041206a2007280200360200200041186a2008290300370200200041106a2009290300370200200041086a2002290300370200200242003703002001420037031041d2f3c200410d200141106a1003200141086a2002290300370300200120012903103703002001410036024020014201370338200641016a220c200141386a104702400240200c20064f0d0020012802402102200128023c2109200128023821030c010b200341246a210d200128023c210920012802402100200421070340200141106a200710452001280210210e02400240200920006b20012802182208490d00200020086a2102200128023821030c010b200020086a22022000490d0620094101742203200220022003491b220f4100480d060240024020090d00200f102921030c010b20012802382009200f102a21030b2003450d052001200f36023c20012003360238200f21090b20012002360240200320006a200e200810f6041a02402001280214450d00200e102e0b200741246a210720022100200d415c6a220d0d000b0b2001411020032002100402402009450d002003102e0b0240200c450d00200641246c41246a21022004210003400240024020002d0000220341034b0d0002400240024020030e0404000102040b2000410c6a280200450d03200041086a280200102e0c030b2000410c6a280200450d02200041086a280200102e0c020b2000410c6a280200450d01200041086a280200102e0c010b200041086a280200450d00200041046a280200102e0b200041246a21002002415c6a22020d000b0b02402005a7450d002004102e0b200141d0006a24000f0b41eff0c2004133200141c8006a4184f4c2001053000b20004104102c000b200f4101102c000b102d000bd60201037f0240024002400240024002400240024002400240024002400240024020012802000e0400010203000b41012102410110292201450d05200141003a0000410121030c040b410110292202450d05200241013a000020012802042103200241014105102a2202450d062002200336000120012802082104410a210320024105410a102a2201450d07200120043600050c020b41012102410110292201450d07200141023a0000410121030c020b410110292202450d07200241033a000020012802042103200241014105102a2202450d082002200336000120012802082104410a210320024105410a102a2201450d09200120043600050b410921020b2000200236020820002003360204200020013602000f0b41014101102c000b41014101102c000b41054101102c000b410a4101102c000b41014101102c000b41014101102c000b41054101102c000b410a4101102c000b8b0101047f230041106b22032400410021042003410036020420012002200341046a1008210502400240024020032802042206417f470d000c010b024020050d000c010b20064104490d01200528000021062005102e200120021006410121040b2000200436020020002006360204200341106a24000f0b41eff0c2004133200341086a4184f4c2001053000b5e01017f230041306b220224002002200136020c20022000360208200241246a410136020020024201370214200241e897c6003602102002411c36022c2002200241286a3602202002200241086a360228200241106a41f097c600106a000ba80101027f230041206b22022400200241106a41086a220342003703002002420037031020002001200241106a1003200241086a2003290300370300200220022903103703002002410036021020024110200241106a1008210002400240024020022802102201417f470d00410221010c010b2001450d0120002d000021012000102e2002411010060b200241206a240020010f0b41eff0c2004133200241106a4184f4c2001053000b9e0301027f230041e0006b22032400200341003a0005024002402000413f4b0d0041012104200341013a0005200320004102743a00000c010b02400240200041808001490d0020004180808080044f0d0141042104200341043a0005200320004102744102723602000c020b41022104200341023a0005200320004102744101723b01000c010b41052104200341053a0005200341033a0000200320003600010b024002402001280200220028020822012002490d0020002802002100200320023602082003200436020c20042002470d0120002003200210f6041a200341e0006a24000f0b20022001105e000b200341286a41146a411d360200200341346a4120360200200341106a41146a41033602002003200341086a36024020032003410c6a360244200341c8006a41146a4100360200200342033702142003419ce7c5003602102003412036022c200341c8ecc5003602582003420137024c200341f0e7c5003602482003200341286a3602202003200341c8006a3602382003200341c4006a3602302003200341c0006a360228200341106a41ace8c500106a000bb90201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210420034120710d012004ad4101200110b50121000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000b20024180016a240020000f0b20044180011035000b20044180011035000b130020004101360204200041f8b5c0003602000b3400200041d4e9c10036020420004100360200200041146a410b360200200041106a41bcb8c000360200200041086a42043702000b3001017f02404102102922020d0041024101102c000b20024181023b00002000428280808020370204200020023602000b130020004102360204200041c0cfc0003602000b3101017f02404108102922020d0041084101102c000b20004288808080800137020420002002360200200242f02e3700000b3101017f02404108102922020d0041084101102c000b20004288808080800137020420002002360200200242e4003700000bdc0805037f037e027f017e017f23004180016b220724002004a7210802400240024002400240024020014201510d0041012109024020084101460d00427f200320067c200220057c220a2002542208ad7c220b2008200b200354200b2003511b22081b210b427f200a20081b210a4200210c4100210d0c040b2002200556200320065620032006511b450d01200320067d2002200554ad7d210b200220057d210a4200210c0c020b4101210d024020084101470d00427f200320067c200220057c22012002542208ad7c22022008200220035420022003511b22081b210b427f200120081b210a410021094201210c0c040b200741306a20042005200642012002200310a501200741c0006a290300210b2007290338210a2007290330210c0c040b200620037d2005200254ad7d210b200520027d210a4201210c0b410021094101210d0b2001500d00200741f0006a41086a220842003703002007420037037041c28cc0004116200741f0006a1003200741e0006a41086a220e200829030037030020072007290370370360200741c8006a200741e0006a109701200741c8006a41106a29030021012007290350210f20072802482110200842003703002007420037037041c28cc0004116200741f0006a1003200e200829030037030020072007290370370360200742002001420020101b220120037d200f420020101b2203200254ad7d220f200320027d2202200356200f200156200f2001511b22081b37037820074200200220081b370370200741e0006a4110200741f0006a411010040b02402004500d002009450d01200741f0006a41086a220842003703002007420037037041c28cc0004116200741f0006a1003200741e0006a41086a220d200829030037030020072007290370370360200741186a200741e0006a109701200741186a41106a29030021032007290320210220072802182109200842003703002007420037037041c28cc0004116200741f0006a1003200d200829030037030020072007290370370360200742002003420020091b220320067d2002420020091b2202200554ad7d2204200220057d2205200256200420035620042003511b22081b37037820074200200520081b370370200741e0006a4110200741f0006a411010040c010b200d450d00200741f0006a41086a220842003703002007420037037041c28cc0004116200741f0006a1003200741e0006a41086a220d2008290300370300200720072903703703602007200741e0006a109701200741106a29030021032007290308210220072802002109200842003703002007420037037041c28cc0004116200741f0006a1003200d2008290300370300200720072903703703602007427f2003420020091b220320067c2002420020091b220220057c22052002542208ad7c22022008200220035420022003511b22081b3703782007427f200520081b370370200741e0006a4110200741f0006a411010040b2000200a3703082000200c370300200041106a200b37030020074180016a24000bf20403037f027e017f230041d0006b220424004101210502402001a722064101470d002000427f2000290300220720027c220820082007542205200041086a2209290300220720037c2005ad7c220820075420082007511b22051b3703002009427f200820051b370300410021050b0240024020014201560d00024020060e020200020b2005450d01200441c0006a41086a220042003703002004420037034041c28cc0004116200441c0006a1003200441306a41086a2206200029030037030020042004290340370330200441186a200441306a109701200441186a41106a29030021012004290320210720042802182105200042003703002004420037034041c28cc0004116200441c0006a100320062000290300370300200420042903403703302004427f2001420020051b220120037c2007420020051b220320027c22072003542200ad7c22022000200220015420022001511b22001b3703482004427f200720001b370340200441306a4110200441c0006a411010040c010b200441c0006a41086a220042003703002004420037034041c28cc0004116200441c0006a1003200441306a41086a22062000290300370300200420042903403703302004200441306a109701200441106a29030021012004290308210720042802002105200042003703002004420037034041c28cc0004116200441c0006a100320062000290300370300200420042903403703302004427f2001420020051b220120037c2007420020051b220320027c22072003542200ad7c22022000200220015420022001511b22001b3703482004427f200720001b370340200441306a4110200441c0006a411010040b200441d0006a24000b130020004103360204200041e0dbc0003602000b3400200041abeac10036020420004100360200200041146a4103360200200041106a41c8e2c000360200200041086a42083702000b130020004104360204200041e0e6c0003602000b0b00200041a0c21e10ab010b3001017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200220013600000b3201017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241c0f0003600000b0b00200041d0860310ab010bee0704077f027e047f027e230041d0016b22022400200241003602a80120014120200241a8016a10082103024002400240024020022802a8012204417f460d0020030d010b200042003703000c010b41002101200241003a00c801200441706a21050340024020042001470d00200141ff0171450d03200241003a00c8010c030b200241a8016a20016a200320016a2d00003a00002002200141016a22063a00c8012005417f6a21052006210120064120470d000b200241c8006a41086a200241a8016a41086a290300370300200241c8006a41106a200241a8016a41106a290300370300200241c8006a41186a200241a8016a41186a290300370300200220022903a801370348200420066b22074110490d01200320066a22082900002109200841086a290000210a41002101200241003a00c801200741706a21070340024020072001470d00200141ff0171450d03200241003a00c8010c030b200241a8016a20016a200820016a41106a2d00003a00002002200141016a22063a00c8012006210120064120470d000b200241e8006a41086a220b200241a8016a41086a2201290300370300200241e8006a41106a220c200241a8016a41106a2207290300370300200241e8006a41186a220d200241a8016a41186a220e290300370300200220022903a801370368200520066b410f4d0d012001200241c8006a41086a2903003703002007200241c8006a41106a290300370300200e200241c8006a41186a29030037030020024188016a41086a2205200b29030037030020024188016a41106a220b200c29030037030020024188016a41186a220c200d290300370300200220022903483703a8012002200229036837038801200820066a220641186a290000210f200641106a2900002110200241286a41086a2001290300370300200241286a41106a2007290300370300200241286a41186a200e290300370300200241086a41086a2005290300370300200241086a41106a200b290300370300200241086a41186a200c290300370300200220022903a801370328200220022903880137030802402004450d002003102e0b20002009370308200041206a200f370300200041186a2010370300200041106a200a370300200041286a2002290328370300200041c8006a2002290308370300200041306a200241286a41086a290300370300200041386a200241286a41106a290300370300200041c0006a200241286a41186a290300370300200041d0006a200241086a41086a290300370300200041d8006a200241086a41106a290300370300200041e0006a200241086a41186a290300370300200042013703000b200241d0016a24000f0b41eff0c2004133200241e8006a4184f4c2001053000bc10201067f23004180016b220224000240411710292203450d00200341002900b0a5433700002003410f6a41002900bfa543370000200341086a41002900b8a54337000020024297808080f00237020c200220033602082001200241086a104a200228020c21012002280210210420022802082103200241086a41186a22054200370300200241086a41106a22064200370300200241086a41086a220742003703002002420037030820032004200241086a1000200241e0006a41186a2005290300370300200241e0006a41106a2006290300370300200241e0006a41086a200729030037030020022002290308370360200241086a200241e0006a10760240024020022d00084102470d00200041023a00000c010b2000200241086a41d80010f6041a0b02402001450d002003102e0b20024180016a24000f0b41174101102c000bbc0301057f230041106b2203240002400240024002400240200141046a2204417f4c0d000240024020040d00410121050c010b200410292205450d020b2003410036020820032004360204200320053602002001200310470240024020032802042206200328020822056b2001490d00200328020021040c010b200520016a22042005490d0520064101742207200420042007491b22074100480d050240024020060d002007102921040c010b200328020020062007102a21040b2004450d032003200736020420032004360200200721060b200420056a2000200110f6041a02400240200241046a2802002207200241086a28020022006b200520016a2201490d00200228020021050c010b200020016a22052000490d0520074101742200200520052000491b22004100480d050240024020070d002000102921050c010b200228020020072000102a21050b2005450d0420022005360200200241046a2000360200200241086a28020021000b200241086a200020016a360200200520006a2004200110f6041a02402006450d002004102e0b200341106a24000f0b1032000b20044101102c000b20074101102c000b20004101102c000b102d000b990201067f230041c0006b220224000240411710292203450d00200341002900b0a5433700002003410f6a41002900bfa543370000200341086a41002900b8a54337000020024297808080f002370224200220033602202000200241206a104a200228022421002002280228210420022802202103200241206a41186a22054200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032004200241206a1000200241186a2005290300370300200241106a2006290300370300200241086a20072903003703002002200229032037030020024120360224200220023602202001200241206a10d50302402000450d002003102e0b200241c0006a24000f0b41174101102c000b110020002802002000280204200110b3010bbe0f020d7f017e230041206b220324004101210402400240200228021841222002411c6a2802002802101102000d000240024020010d00410021050c010b200020016a21062000210741002105410021080240034020072109200741016a210a02400240024020072c0000220b417f4a0d0002400240200a2006470d004100210c200621070c010b20072d0001413f71210c200741026a220a21070b200b411f7121040240200b41ff0171220b41df014b0d00200c200441067472210b0c020b0240024020072006470d004100210d2006210e0c010b20072d0000413f71210d200741016a220a210e0b200d200c41067472210c0240200b41f0014f0d00200c2004410c7472210b0c020b02400240200e2006470d004100210b200a21070c010b200e41016a2107200e2d0000413f71210b0b200c4106742004411274418080f0007172200b72220b418080c400470d020c040b200b41ff0171210b0b200a21070b4102210a024002400240024002400240200b41776a220c411e4d0d00200b41dc00470d010c020b41f400210e02400240200c0e1f05010202000202020202020202020202020202020202020202030202020203050b41f200210e0c040b41ee00210e0c030b02400240200b10e1040d0002400240200b41808004490d00024002400240200b418080084f0d00200b4180fe0371410876210f41f183c600210c410021040340200c41026a210d2004200c2d0001220a6a210e0240200c2d0000220c200f460d00200c200f4b0d06200e2104200d210c200d41b784c600470d010c060b200e2004490d02200e41a6014b0d03200441b784c6006a210c02400340200a450d01200a417f6a210a200c2d00002104200c41016a210c2004200b41ff0171470d000c080b0b200e2104200d210c200d41b784c600470d000c050b0b200b41ef83384b0d04200b41e28b746a41e28d2c490d04200b419fa8746a419f18490d04200b41dee2746a410e490d04200b41feffff0071419ef00a460d04200b41a9b2756a4129490d04200b41cb91756a410a4b0d090c040b2004200e1035000b200e41a601105e000b200b4180fe0371410876210f41c0fec500210c41002104024002400340200c41026a210d2004200c2d0001220a6a210e0240200c2d0000220c200f460d00200c200f4b0d03200e2104200d210c200d4192ffc500470d010c030b0240200e2004490d00200e41a5024b0d0220044192ffc5006a210c02400340200a450d01200a417f6a210a200c2d00002104200c41016a210c2004200b41ff0171470d000c070b0b200e2104200d210c200d4192ffc500470d010c030b0b2004200e1035000b200e41a502105e000b200b41ffff0371210441b781c600210a4101210e02400340200a41016a210d02400240200a2d0000220c411874411875220f4100480d00200d210a0c010b200d41f183c600460d02200f41ff0071410874200a2d000172210c200a41026a210a0b02402004200c6b22044100480d00200e410173210e200a41f183c600470d010b0b200e410171450d020c070b41d8f0c5001058000b200b41ffff0371210441dd85c600210a4101210e0340200a41016a210d02400240200a2d0000220c411874411875220f4100480d00200d210a0c010b200d41f588c600460d03200f41ff0071410874200a2d000172210c200a41026a210a0b02402004200c6b22044100480d00200e410173210e200a41f588c600470d010b0b200e4101710d050b200b41017267410276410773ad4280808080d0008421104103210a0c020b41d8f0c5001058000b0b200b210e0b2003200136020420032000360200200320053602082003200836020c0240024020082005490d0002402005450d0020052001460d00200520014f0d01200020056a2c000041bf7f4c0d010b02402008450d0020082001460d00200820014f0d01200020086a2c000041bf7f4c0d010b2002280218200020056a200820056b200228021c28020c110400450d01410121040c060b20032003410c6a3602182003200341086a36021420032003360210200341106a10e804000b0340200a210c4101210441dc0021054101210a024002400240024002400240200c0e0402010500020b02400240024002402010422088a741ff01710e06050302010006050b201042ffffffff8f60834280808080308421104103210a41f50021050c070b201042ffffffff8f60834280808080208421104103210a41fb0021050c060b200e2010a7220c410274411c7176410f71220a413072200a41d7006a200a410a491b21050240200c450d002010427f7c42ffffffff0f832010428080808070838421100c050b201042ffffffff8f60834280808080108421100c040b201042ffffffff8f608321104103210a41fd0021050c040b4100210a200e21050c030b4101210a0240200b418001490d004102210a200b418010490d0041034104200b41808004491b210a0b200a20086a21050c040b201042ffffffff8f60834280808080c0008421100b4103210a0b20022802182005200228021c2802101102000d050c000b0b200820096b20076a210820062007470d000b0b2005450d0020052001460d00200520014f0d02200020056a2c000041bf7f4c0d020b410121042002280218200020056a200120056b200228021c28020c1104000d0020022802184122200228021c28021011020021040b200341206a240020040f0b200020012005200110de04000bb20201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad4101200110b50121000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000b20024180016a240020000f0b20044180011035000b20044180011035000bd50203027f017e037f230041306b22032400412721040240024020004290ce005a0d00200021050c010b412721040340200341096a20046a2206417c6a200020004290ce0080220542f0b17f7e7ca7220741ffff037141e4006e2208410174418aedc5006a2f00003b00002006417e6a2008419c7f6c20076a41ffff0371410174418aedc5006a2f00003b00002004417c6a2104200042ffc1d72f5621062005210020060d000b0b02402005a7220641e3004c0d00200341096a2004417e6a22046a2005a7220741ffff037141e4006e2206419c7f6c20076a41ffff0371410174418aedc5006a2f00003b00000b024002402006410a480d00200341096a2004417e6a22046a2006410174418aedc5006a2f00003b00000c010b200341096a2004417f6a22046a200641306a3a00000b2002200141c8ecc5004100200341096a20046a412720046b10b6012104200341306a240020040be40501057f024002402001450d00412b418080c4002000280200220641017122011b2107200120056a21080c010b200541016a210820002802002106412d21070b0240024020064104710d00410021020c010b4100210902402003450d002003210a200221010340200920012d000041c00171418001466a2109200141016a2101200a417f6a220a0d000b0b200820036a20096b21080b410121010240024020002802084101460d00200020072002200310dd040d012000280218200420052000411c6a28020028020c1104000f0b02402000410c6a280200220920084b0d00200020072002200310dd040d012000280218200420052000411c6a28020028020c1104000f0b0240024020064108710d00200920086b210941002101024002400240410120002d0030220a200a4103461b0e0402000100020b20092101410021090c010b20094101762101200941016a41017621090b200141016a210103402001417f6a2201450d0220002802182000280204200028021c280210110200450d000b41010f0b41012101200041013a003020004130360204200020072002200310dd040d01200920086b210941002101024002400240410120002d0030220a200a4103461b0e0402000100020b20092101410021090c010b20094101762101200941016a41017621090b200141016a2101024003402001417f6a2201450d0120002802182000280204200028021c280210110200450d000b41010f0b2000280204210a41012101200028021820042005200028021c28020c1104000d01200941016a2109200028021c210320002802182100034002402009417f6a22090d0041000f0b410121012000200a2003280210110200450d000c020b0b2000280204210a41012101200020072002200310dd040d00200028021820042005200028021c28020c1104000d00200941016a2109200028021c210320002802182100034002402009417f6a22090d0041000f0b410121012000200a2003280210110200450d000b0b20010b930c04047f017e097f067e23004180066b22022400200241286a2001103102400240024002400240024020022802280d0020012802042203450d01200128020022042d0000210520012003417f6a3602042001200441016a36020002400240200541ff00714103470d0020054118744118754100480d01420221060c060b200042033703680c060b20024198046a2001104820022d0098044102460d02200241f0036a41206a20024198046a41206a280200360200200241f0036a41186a20024198046a41186a290300370300200241f0036a41106a20024198046a41106a290300370300200241f0036a41086a20024198046a41086a29030037030020022002290398043703f00341002103200241003a00c00220012802042107417f2105024002400240034020072003460d0120024180026a20036a200128020022082d00003a00002001200720056a3602042001200841016a3602002002200341016a22043a00c0022005417f6a210520042103200441c000470d000b200241c0056a41386a220320024180026a41386a290300370300200241c0056a41306a220920024180026a41306a290300370300200241c0056a41286a220a20024180026a41286a290300370300200241c0056a41206a220b20024180026a41206a290300370300200241c0056a41186a220c20024180026a41186a290300370300200241c0056a41106a220d20024180026a41106a290300370300200241c0056a41086a220e20024180026a41086a29030037030020022002290380023703c005200441ff017141c000490d0520024180056a41386a220f200329030037030020024180056a41306a2009290300220637030020024180056a41286a200a290300221037030020024180056a41206a200b290300221137030020024180056a41186a200c290300221237030020024180056a41106a200d290300221337030020024180056a41086a200e2903002214370300200220022903c005221537038005200241c0046a41306a2006370300200241c0046a41286a2010370300200241c0046a41206a2011370300200241c0046a41186a2012370300200241c0046a41106a2013370300200241c0046a41086a2014370300200241c0046a41386a200f290300370300200220153703c00420072004460d05200831000121112001200720056a3602042001200841026a360200201150450d01420021060c020b200341ff0171450d04200241003a00c0020c040b2007417f6a2004460d03200831000221122001200841036a3602002001200720046b417e6a36020442022011420f838622104204540d034201210620124208862011844204882010420c882211420120114201561b7e221120105a0d030b200241206a2001103120022802200d0220022802242103200241086a200110652002290308a70d02200241086a41106a290300211320022903102112200241e8026a41206a200241f0036a41206a280200360200200241e8026a41186a200241f0036a41186a290300370300200241e8026a41106a200241f0036a41106a290300370300200241e8026a41086a200241f0036a41086a29030037030020024194036a200241c0046a41086a2903003702002002419c036a200241c0046a41106a290300370200200241a4036a200241c0046a41186a290300370200200241ac036a200241c0046a41206a290300370200200241b4036a200241e8046a290300370200200241bc036a200241f0046a290300370200200241c4036a200241f8046a290300370200200220022903f0033703e802200220022903c00437028c0320024180026a200241e8026a41e80010f6041a0c030b200042033703680c040b200042033703680c030b420221060b20024198016a20024180026a41e80010f6041a024020064202520d00200042033703680c020b200241306a20024198016a41e80010f6041a0b200241e8026a200110b801024020022d00e8024113460d002000200241306a41e80010f60422014190016a201337030020014188016a201237030020014180016a2003360200200141f8006a2011370300200120103703702001200637036820014198016a200241e8026a41880110f6041a0c010b200042033703680b20024180066a24000bb18a0107087f017e067f057e017f027e017f230041e0096b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541124b0d14200141046a210720050e130102030405060708090a0b0c0d0e0f10111213010b200041133a00000c440b02402006450d0020042d0001210620012003417e6a22083602042001200441026a360200200641054b0d004101210902400240024002400240024020060e06490001020304490b200241086a2001103120022802080d052001280204200228020c2204490d052004417f4c0d1d02400240024020040d00410121050c010b200410342205450d0120072802002004490d0620052001280200200410f6041a200128020422032004490d202001200320046b3602042001200128020020046a3602000b2005450d062004ad220a422086200a84210a410221090c490b20044101102c000b20084108490d042004290002210a2001200341766a36020420012004410a6a360200410321090c470b200241106a2001103120022802100d03200128020420022802142204490d032004417f4c0d1b02400240024020040d00410121050c010b200410342205450d0120072802002004490d0420052001280200200410f6041a200128020422032004490d1f2001200320046b3602042001200128020020046a3602000b2005450d042004ad220a422086200a84210a410421090c470b20044101102c000b200241286a2001103120022802280d02200728020041186e220b41186c2204417f4c0d1a200228022c210c0240024020040d00410421050c010b200410292205450d1e0b0240200c450d004100210d41002106410021080340200241206a2001103102400240024020022802200d00200128020420022802242204490d002004417f4c0d1f02400240024020040d004101210e0c010b20041034220e450d3820072802002004490d01200e2001280200200410f6041a200128020422032004490d252001200320046b3602042001200128020020046a3602000b200241186a20011031024020022802180d002001280204200228021c2203490d002003417f4c0d21024002400240024020030d004101210f0c010b20031034220f450d0120072802002003490d02200f2001280200200310f6041a200128020422092003490d292001200920036b3602042001200128020020036a3602000b200841016a21092008200b470d06200d20092009200d491b220bad42187e220a422088a70d4d200aa7221041004e0d050c4d0b20034101102c000b200f102e0b2004450d010b200e102e0b02402008450d002005210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141186a2101200641686a22060d000b0b200b0d050c060b0240024020080d002010102921050c010b200520062010102a21050b2005450d230b200520066a2208200e360200200841146a2003ad220a3e02002008410c6a200a422086200fad84370200200841046a2004ad220a422086200a84370200200d41026a210d200641186a210620092108200c2009470d000b0b2005450d02200cad422086200bad84210a410521090c450b200241386a2001103120022802380d012007280200410c6e220e410c6c2204417f4c0d19200228023c210f0240024020040d00410421050c010b200410292205450d210b024002400240200f450d004100210841002103410021090340200241306a2001103120022802300d03200128020420022802342204490d032004417f4c0d1d0240024020040d004101210d0c010b20041034220d450d3620072802002004490d03200d2001280200200410f6041a200128020422062004490d262001200620046b3602042001200128020020046a3602000b200941016a210602402009200e470d002008200620062008491b220ead420c7e220a422088a70d48200aa7220b4100480d480240024020090d00200b102921050c010b20052003200b102a21050b2005450d270b200520036a2209200d360200200941086a2004360200200941046a2004360200200841026a21082003410c6a210320062109200f2006470d000b0b2005450d03200fad422086200ead84210a410621090c460b200d102e0b02402009450d002005210103400240200141046a280200450d002001280200102e0b2001410c6a2101200341746a22030d000b0b200e450d010b2005102e0b200041133a00000c430b2006450d2020042d0001210520012003417e6a22063602042001200441026a36020020050d202006450d2020042d0002210520012003417d6a22073602042001200441036a360200200541014b0d20410221060240024020050e020100010b2007450d2120042d0003210620012003417c6a3602042001200441046a3602000b200020063a0001200041013a0000200041026a200241d8086a41860110f6041a0c420b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241c0006a200110642002290340a70d002002290348210a200041023a0000200020022800d007360001200041086a200a370300200041046a200241d3076a280000360000200041106a200241d8086a41f80010f6041a0c420b200041133a00000c410b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241d0076a2001103b20022802d00722010d110b200041133a00000c400b02402006450d0020012003417e6a3602042001200441026a3602000b200041133a00000c3f0b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541014b0d0002400240024020050e020001000b200241d0076a2001104820022d00d0074102460d02200241b8056a41086a2209200241ec076a2902003703002002200241e4076a2902003703b805200241d0076a41106a2802002104200241dc076a2802002103200241d0076a41086a280200210520022802d407210620022802d0072107200241d0006a200110652002290350a70d02200241d0006a41106a290300210a20022903582111200241e0066a41086a2009290300370300200220022903b8053703e006410121010c010b200241d0076a2001104820022d00d0074102460d01200241b8056a41086a200241ec076a2902003703002002200241e4076a2902003703b805200241d0076a41106a2802002104200241dc076a2802002103200241d0076a41086a280200210520022802d407210620022802d007210720024180016a20011065200229038001a70d0120024180016a41106a290300210a2002290388012111200241e8006a200110652002290368a70d01200241e8006a41106a290300211220022903702113200241e0066a41086a200241b8056a41086a290300370300200220022903b8053703e006410221010b20024198066a41086a200241e0066a41086a2903002214370300200220022903e006221537039806200041c8006a2012370000200041c0006a2013370000200041386a200a370000200041306a2011370000200041053a0000200020022800b807360001200041046a200241bb076a2800003600002000411c6a2004360000200041186a2003360000200041146a2005360000200041106a20063600002000410c6a2007360000200041086a2001360000200041206a2015370000200041286a2014370000200041d0006a20022903d808370300200041d8006a200241d8086a41086a290300370300200041e0006a200241d8086a41106a290300370300200041e8006a200241d8086a41186a290300370300200041f0006a200241d8086a41206a290300370300200041f8006a200241d8086a41286a29030037030020004180016a200241d8086a41306a2903003703000c3f0b200041133a00000c3e0b2006450d3a20042d0001210520012003417e6a220b3602042001200441026a3602002005410d4b0d3a4104210f024002400240024002400240024002400240024002400240024020050e0e00010246030405060708090a0b0c000b200241d0076a2001104820022d00d0074102460d46200241bc056a200241ec076a2d00003a00002002200241e8076a2802003602b8052002200241ee076a2f01003b01d804200241dc076a2902002111200241e4076a2802002108200241ed076a2d0000210d200241f0076a280200210e20022902d407210a20022802d007210620024198016a20011065200229039801a70d4620072802002204450d46200241a8016a290300211220022903a0012113200128020022032d0000210920012004417f6a3602044101210f2001200341016a360200200941024b0d46200241c4076a41046a200241b8056a41046a2d00003a0000200220022802b8053602c407200220022f01d8043b01d006200220022f0198063b01d8060c450b200241b0016a2001106520022903b001a70d45200241c0016a290300211120022903b801210a200241c4076a41046a20024188076a41046a2d00003a0000200220022f01d0073b01d80620022002280288073602c407200220022f0186073b01d0064102210f0c430b200241c8016a2001106520022903c801a70d44200241d8016a290300211120022903d001210a200241c4076a41046a20024190076a41046a2d00003a0000200220022f01d0073b01d80620022002280290073602c407200220022f018e073b01d0064103210f0c420b200241f8016a2001103120022802f8010d4320022802fc012108200241e0016a2001106520022903e001a70d43200241f0016a290300211120022903e801210a200241c4076a41046a200241d0076a41046a2d00003a0000200220022f01b8053b01d806200220022802d0073602c407200220022f01d8043b01d0064105210f0c410b20024180026a200110312002280280020d42200728020041246e221041246c2204417f4c0d1920022802840221160240024020040d00410421060c010b200410292206450d250b02402016450d00200241d0076a41017221034100210941002107410021040340200241d0076a20011048200241b8056a41086a2208200341086a290000370300200241b8056a41106a220d200341106a290000370300200241b8056a41186a220e200341186a290000370300200220032900003703b805200220022f01f2073b01b807024020022d00d007220f4102470d002010450d452006102e0c450b200441016a210520022d00f107210b200241d8046a41186a220c200e290300370300200241d8046a41106a220e200d290300370300200241d8046a41086a220d2008290300370300200220022903b8053703d804200220022f01b8073b01a007024020042010470d002009200520052009491b2210ad42247e220a422088a70d46200aa722084100480d460240024020040d002008102921060c010b200620072008102a21060b2006450d280b200620076a2204200f3a0000200c290300210a200e2903002111200d290300211320022903d8042112200441216a200b3a0000200441016a2012370000200441096a2013370000200441116a2011370000200441196a200a370000200441226a20022f01a0073b0000200941026a2109200741246a21072005210420162005470d000b0b2006450d422016ad4220862010ad84210a200241c4076a41046a20024198066a41046a2d00003a0000200220022f0198073b01d80620022002280298063602c407200220022f0190073b01d006420021114106210f0c400b4107210f0c3f0b200b450d4020042d0002210920012003417d6a3602042001200441036a360200200941034f0d40200241c4076a41046a200241d0076a41046a2d00003a0000200220022f01b8053b01d806200220022801d0073602c407200220022f01d8043b01d0064108210f0c3f0b200241d0076a2001104820022d00d0074102460d3f200241a0076a41046a200241ec076a2d000022013a0000200241c4076a41046a20013a00002002200241e8076a28020022013602a0072002200241ee076a2f010022043b018807200220022f0190073b01d806200220013602c407200241dc076a2902002111200241e4076a2802002108200241ed076a2d0000210d200241f0076a280200210e20022902d407210a20022802d0072106200220043b01d0064109210f0c3d0b20024188026a200110312002280288020d3e200228028c022106200241c4076a41046a200241d0076a41046a2d00003a0000200220022f01b8053b01d806200220022802d0073602c407200220022f01d8043b01d006410a210f0c3c0b410b210f0c3b0b410c210f0c3a0b20024190026a200110312002280290020d3b2002280294022106200241c4076a41046a200241b8076a41046a2d00003a0000200220022f01d8043b01d806200220022802b8073602c407200220022f0198073b01d006410d210f0c390b200241d0076a2001103020022802d0072206450d3a200241c4076a41046a200241b8056a41046a2d00003a0000200220022f0188073b01d806200220022802b8053602c407200220022f01d8043b01d00620022902d407210a42002111410e210f0c380b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241d8086a2001107820022d00d8084101460d00200241d0076a200241d8086a41017241e00010f6041a20024198026a200110312002280298020d002001280204200228029c022204490d002004417f4c0d11024002400240024020040d004101210341010d010c040b200410342203450d0120072802002004490d0220032001280200200410f6042105200128020422062004490d212001200620046b3602042001200128020020046a3602002005450d030b200241b8056a200241d0076a41e00010f6041a200241d8046a200241b8056a41e00010f6041a200041073a0000200020022f0098063b0001200041036a2002419a066a2d00003a00002000410c6a2004360000200041086a2004360000200041046a2003360000200041106a200241d8046a41e00010f6041a20004180016a200241e0066a41106a290300370300200041f8006a200241e0066a41086a290300370300200041f0006a20022903e0063703000c3f0b20044101102c000b2003102e0b200041133a00000c3c0b200241b8056a200110f90120022d00b8054112470d0c200041133a00000c3b0b200241b8056a200110fa0120022d00b8054105470d0c200041133a00000c3a0b200241b8056a200110fa0120022d00b8054105470d0c200041133a00000c390b2006450d3220042d0001210520012003417e6a3602042001200441026a360200200541094b0d32024002400240024002400240024002400240024020050e0a00010203040506070809000b200241b8056a2001104020022802b8052204450d3b200241c0056a280200210520022802bc052103200241a0026a20011031024020022802a002450d002003450d3c0c3b0b0240200728020022094104490d0020022802a402210620012802002208280000210720012009417c6a3602042001200841046a360200200241e0066a41086a200241d0076a41086a290300370300200220022903d0073703e006410121010c3a0b20030d3a0c3b0b200241b8056a2001104020022802b8052204450d3a200241c0056a280200210520022802bc052103200241a8026a20011031024020022802a802450d0020030d3a0c3b0b0240200728020022094104490d0020022802ac02210620012802002208280000210720012009417c6a3602042001200841046a360200200241e0066a41086a200241d0076a41086a290300370300200220022903d0073703e006410221010c390b20030d390c3a0b200241c0026a2001103120022802c0020d3920022802c4022104200241d0076a2001104820022d00d0074102460d39200241b8056a41086a200241e8076a2903003703002002200241e0076a2903003703b805200241dc076a2802002107200241d0076a41086a2802002106200241f0076a280200210920022802d407210520022802d0072103200241b8026a2001103120022802b8020d3920022802bc022108200241b0026a2001103120022802b0020d3920022802b4022101200241e0066a41086a200241b8056a41086a290300370300200220022903b8053703e0062001ad210a42002111410321010c370b200241c8026a2001103120022802c8020d3820022802cc022104200241e0066a41086a200241d0076a41086a290300370300200220022903d0073703e006410421010c360b200241d0026a2001103120022802d0020d3720022802d4022104200241e0066a41086a200241d0076a41086a290300370300200220022903d0073703e006410521010c350b200241d0076a2001104820022d00d0074102460d36200241b8056a41086a200241ec076a2902003703002002200241e4076a2902003703b805200241d0076a41106a2802002107200241dc076a2802002106200241d0076a41086a280200210520022802d407210320022802d0072104200241e0026a2001106520022903e002a70d36200241e0026a41106a290300211120022903e802210a200241d8026a2001103120022802d8020d3620022802dc022109200241e0066a41086a200241b8056a41086a290300370300200220022903b8053703e006410621010c340b200241f8026a2001103120022802f8020d3520022802fc022104200241e0066a41086a200241d0076a41086a290300370300200220022903d0073703e006410721010c330b200241d0076a2001104820022d00d0074102460d3441082101200241e0066a41086a200241ec076a2902003703002002200241e4076a2902003703e006200241e0076a2802002107200241dc076a2802002106200241d0076a41086a280200210520022802d407210320022802d00721040c320b20024180036a200110312002280280030d332002280284032104200241e0066a41086a200241d0076a41086a290300370300200220022903d0073703e006410921010c310b20024188036a200110312002280288030d32200228028c032104200241e0066a41086a200241d0076a41086a290300370300200220022903d0073703e006410a21010c300b2006450d2e20042d0001210520012003417e6a3602042001200441026a360200200541034b0d2e0240024002400240024020050e0400010203000b41002105200241003a00f0072003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d34200241003a00f0070c340b200241d0076a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00f0072003417f6a21032006210520064120470d000b2002418c076a200241d0076a41086a2d00003a0000200220022802d4072201360288072002419e076a20022d008a073a0000200220022f01da0722033b018607200220022802d007220836029807200220013b019c07200241d0076a41186a290300210a20022903e007211120022802dc07210420022f008b072101200220022d00d9073a00ba05200220013b01b805200220043600bd05200220033b00bb05200241c9056a200a370000200220113700c105200220022f0099073b01d006200228009b07210120022903b8052113200241e0066a41186a200241d8046a41186a290000370300200241e0066a41106a200241d8046a41106a290000370300200241e0066a41086a200241d8046a41086a290000370300200220022900d8043703e006200220022f01a0073b01c4062004411876210d410121040c030b41002105200241003a00f0072003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d33200241003a00f0070c330b200241d0076a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00f0072003417f6a21032006210520064120470d000b2002418c076a200241d0076a41086a2d00003a0000200220022802d407220136028807200241b2076a20022d008a073a0000200220022f01da0722033b018607200220022802d00722083602ac07200220013b01b007200241d0076a41186a290300210a20022903e007211120022802dc07210420022f008b072101200220022d00d9073a00a207200220013b01a007200220043600a507200220033b00a307200220022f00ad073b01d00620022800af07210120022903a0072113200241e0066a41186a200241b8056a41186a290000370300200241e0066a41106a200241b8056a41106a290000370300200241e0066a41086a200241b8056a41086a290000370300200220022900b8053703e006200220022f01b8073b01c4062004411876210d410221040c020b41002105200241003a00f007410220036b21092003417d6a210603400240200920056a0d00200541ff0171450d32200241003a00f0070c320b200241d0076a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00f0072006417f6a21062007210520074120470d000b2002418c076a200241d8076a2d00003a0000200220022802d407220536028807200241ca076a20022d008a073a0000200220022f01da0722093b018607200220022802d00722083602c407200220053b01c807200241d0076a41186a290300210a20022903e007211120022802dc07210d20022f008b072105200220022d00d9073a00ba07200220053b01b8072002200d3600bd07200220093b00bb0741002105200241003a00f007200420076a2109200d411876210d200720036b41026a210303400240200320056a0d00200541ff0171450d32200241003a00f0070c320b200241d0076a20056a200920056a220441026a2d00003a0000200120063602042001200441036a3602002002200541016a22043a00f0072006417f6a21062004210520044120470d000b2002418c076a200241d0076a41086a2d00003a0000200220022802d407220136028807200241a6076a20022d008a073a0000200220022f01da0722043b018607200220022802d0073602a007200220013b01a407200241d0076a41186a290300211320022903e007211220022802dc07210120022f008b072103200220022d00d9073a00ba05200220033b01b805200220013600bd05200220043b00bb05200241c9056a2013370000200220123700c105200220022f00c50722043b01b60720022903b807211320022800c7072101200220043b01d006200220022800a3073600e306200220022802a0073602e006200241ff066a200241b8056a41186a2d00003a0000200241f7066a200241c8056a290300370000200241ef066a200241b8056a41086a290300370000200220022903b8053700e706200220022f01d8043b01c406410321040c010b200241b8056a2001103020022802b8052201450d2f200241e0066a41086a200241d0076a41086a290000370300200241e0066a41106a200241d0076a41106a290000370300200241e0066a41186a200241d0076a41186a290000370300200220022f0188073b01d006200220022900d0073703e006200220022f01d8043b01c40620022902bc052113410421040b20024198066a41086a2203200241e0066a41086a29030037030020024198066a41106a2205200241e0066a41106a29030037030020024198066a41186a2206200241e0066a41186a290300370300200220022f01d0063b01bc06200220022903e00637039806200220022f01c4063b01ce072000410c3a0000200020022f00d8063b0001200041036a200241da066a2d00003a0000200041056a20083a0000200041046a20043a00002000411d6a200a370000200041156a2011370000200041146a200d3a00002000410c6a2013370000200041086a2001360000200041066a20022f01bc063b0000200041256a2002290398063700002000412d6a2003290300370000200041356a20052903003700002000413d6a2006290300370000200041c6006a20022f01ce073b000020004180016a20024190096a290300370300200041f8006a20024188096a290300370300200041f0006a20024180096a290300370300200041e8006a200241f8086a290300370300200041e0006a200241d8086a41186a290300370300200041d8006a200241d8086a41106a290300370300200041d0006a200241d8086a41086a290300370300200041c8006a20022903d8083703000c370b024002402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d0020024190036a20011031200228029003450d010b200041133a00000c370b20022802940321012000410d3a0000200020022f00d0073b0001200041046a2001360200200041036a200241d2076a2d00003a0000200041086a200241d8086a41800110f6041a0c360b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d0020024198036a200110312002280298030d002001280204200228029c032204490d002004417f4c0d0a024002400240024020040d00410121030c010b200410342203450d0120072802002004490d0220032001280200200410f6041a200128020422052004490d1b2001200520046b3602042001200128020020046a3602000b2003450d022000410e3a0000200020022f00d0073b0001200041086a2004ad220a422086200a84370000200041046a2003360000200041036a200241d2076a2d00003a0000200041106a200241d8086a41f80010f6041a0c380b20044101102c000b2003102e0b200041133a00000c350b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541024b0d0002400240024020050e03000102000b200241a0036a2001106520022903a003a70d02200241b0036a290300210a20022903a8032111200241d0076a2001104820022d00d0074102460d02200241b8056a41086a200241ec076a2902003703002002200241e4076a2902003703b805200241e0076a2802002101200241dc076a2802002104200241d0076a41086a280200210320022802d407210520022802d0072106410121070c2d0b200241b8036a2001103120022802b8030d0120022802bc032106200241b8056a41086a200241d0076a41086a290300370300200220022903d0073703b805410221070c2c0b200241c0036a2001103120022802c0030d0020022802c4032106200241b8056a41086a200241d0076a41086a290300370300200220022903d0073703b805410321070c2b0b200041133a00000c340b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541044b0d0002400240024002400240024020050e050001020304000b200241d8086a200110fb0120022d00c8094102460d05200241d8066a41046a200241f0086a2d00003a0000200241d8076a20024188096a290300370300200241e0076a20024190096a290300370300200220022802ec083602d806200220022f01f2083b01d60620022002290380093703d00720022802e808210520022903e008210a20022903d808211120022d00f108210420022802f408210320022903f8082113200241d0066a41046a200241b8096a2d00003a0000200220022802b4093602d006200220022f01ba093b01ce06200220022f01b8053b01de06200241a8096a2903002114200241c8096a290300211520022903a009211720022802b009210d200229039809211220022d00b909210120022802bc09210620022903c0092118410121070c2e0b200241d0036a2001106420022903d003a70d0420022903d803210a200241c8036a2001103120022802c8030d04200128020420022802cc032204490d042004417f4c0d0c02400240024020040d00410121090c010b200410342209450d0120072802002004490d0520092001280200200410f6041a200128020422032004490d1d2001200320046b3602042001200128020020046a3602000b2009450d052004ad22114220862011842111200241d8066a41046a200241b8056a41046a2d00003a0000200241d0076a41086a200241d8086a41086a290300370300200241d0076a41106a200241d8086a41106a290300370300200241d0066a41046a200241e0066a41046a2d00003a0000200220022f0198073b01de06200220022802b8053602d806200220022f01b8073b01d606200220022903d8083703d007200220022802e0063602d006200220022f01a0073b01ce06410221070c2e0b20044101102c000b200241d8086a2001104820022d00d8084102460d03200241bc056a200241f4086a2d00003a00002002200241f0086a2802003602b8052002200241f6086a2f01003b01e006200241e4086a290200210a200241ec086a2802002105200241f5086a2d00002104200241f8086a280200210320022902dc08211120022802d8082109200241f8036a2001106520022903f803a70d0320024188046a29030021132002290380042114200241e8036a2001106420022903e803a70d0320022903f0032112200241e0036a2001103120022802e0030d03200128020420022802e4032206490d032006417f4c0d0b024002400240024020060d004101210841010d010c070b200610342208450d0120072802002006490d0220082001280200200610f60421072001280204220d2006490d1e2001200d20066b3602042001200128020020066a3602002007450d060b200241a0076a41046a200241b8056a41046a2d000022013a0000200241e0076a2013370300200241d8066a41046a20013a0000200241d0066a41046a200241b8076a41046a2d00003a0000200220022802b80522013602a007200220022f01e00622073b018807200220143703d807200220022f0190073b01de06200220013602d806200220073b01d606200220022802b8073602d006200220063602d007200220022f0198073b01ce062006ad4220862008ad842113410321070c2e0b20064101102c000b2008102e0c030b200241a8046a2001106520022903a804a70d02200241b8046a290300211220022903b004211420024198046a20011064200229039804a70d0220022903a004211541002103200241003a00f8082007280200417f6a21040240024002400240024003402004417f460d01200241d8086a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00f8082004417f6a21042005210320054120470d000b200241a8076a200241e7086a2d00003a0000200220022800db083600c707200220022802d8083602c407200220022900df083703a007200220022802c4073602ac07200220022800c7073600af07200241f0086a290300211720022903e808211820024190046a200110312002280290040d0720012802042002280294042204490d072004417f4c0d0f20040d01410121030c020b200341ff0171450d06200241003a00f8080c060b200410342203450d0120072802002004490d0220032001280200200410f6041a200128020422052004490d1e2001200520046b3602042001200128020020046a3602000b2003450d042004ad220a422086200a842113200220183700c105200241c9056a2017370000200241b8056a41086a2201200241a0076a41086a2d00003a0000200220022802ac07220836029807200220022800af0736009b07200220022903a00722113703b805200220022f0099073b01de062001290300210a41042107200228009b072109200241d8066a41046a200241d0056a2d00003a0000200220022802cc053602d806200220022f0188073b01d606200220123703d807200220143703d007200220153703e007200241d0066a41046a200241e0066a41046a2d00003a0000200220022802e0063602d006200220022f0190073b01ce062018423888201742088684a721050c2d0b20044101102c000b2003102e0c020b41002105200241003a00f8082003417e6a21092003417d6a21060340024020092005470d00200541ff0171450d03200241003a00f8080c030b200241d8086a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00f8082006417f6a21062007210520074120470d000b200220022802d80822083602c407200220022800db083600c707200220022f00c5073b01b6072003417e6a2007460d01200241f0086a2903002112200241e7086a2d0000210e20022903e808211420022900df08211120022800c7072109200420076a220d41026a2d00002105200120063602042001200d41036a360200200541014b0d01410021040240024020050e020100010b41002104200241003a00f808200720036b41036a2106200320076b417c6a210303400240200620046a0d00200441ff0171450d04200241003a00f8080c040b200241d8086a20046a200d20046a220541036a2d00003a0000200120033602042001200541046a3602002002200441016a22053a00f8082003417f6a21032005210420054120470d000b2002418c076a2201200241e0086a2d00003a0000200220022802dc0836028807200220022f01e20822043b018607200220022802d8083602b807200241f0086a290300211720022903e808211520022802e408210320022d00e1082105200220022f0188073b01bc07200220012d00003a00e206200220022f018a073b01e006200220053a00e306200220033601e606200220043b01e4064101210420022903e00621130b200220143700c105200241c9056a2012370000200220022f01b8073b01d606200220022f01e8063b01d007200220083a00a007200220093600a307200220022f01b60722013b00a1072002200e3a00c005200220113703b805200220013b01de0620022801ba07210320022903c005210a200241d8066a41046a200241d0056a2d00003a0000200220022802cc053602d806200241da076a2017370100200220153701d207200241e6076a200241ac076a41046a2f01003b0100200220022801ac073601e207200241d0066a41046a20024198076a41046a2d00003a000020022002280198073602d006200220022f01ce073b01ce062014423888201242088684a72105410521070c2a0b2009102e0b200041133a00000c330b2006450d2620042d0001210520012003417e6a3602042001200441026a360200200541014b0d2602400240024020050e020001000b200241d0076a200110b80120022d00d0074113470d010c280b200241d8086a200110484102210120022d00d8084102460d27200241e0066a41086a200241f4086a2902003703002002200241ec086a2902003703e006200241e8086a2802002103200241e4086a2802002105200241d8086a41086a280200210620022802dc08210720022802d80821040c260b200241d8086a200241d0076a41880110f6041a41880110292204450d182004200241d8086a41880110f6041a200241e0066a41086a200241d8046a41086a290200370300200220022902d8043703e006410121010c250b2006450d2320042d0001210520012003417e6a22063602042001200441026a36020020050d2320064104490d232004280002210b20012003417a6a3602042001200441066a360200200241d0046a2001103120022802d0040d23200128020420022802d4042205490d232005417f4c0d050240024020050d004101210c41010d010c250b20051034220c450d1f20072802002005490d23200c2001280200200510f6042104200128020422032005490d192001200320056b3602042001200128020020056a3602002004450d240b200241c8046a2001103120022802c8040d212007280200410c6e220f410c6c2204417f4c0d0520022802cc0421100240024020040d004104210e0c010b20041029220e450d1a0b0240024002400240024002402010450d004100210841002103410021090340200241c0046a2001103120022802c0040d03200128020420022802c4042204490d032004417f4c0d0c0240024020040d004101210d0c010b20041034220d450d2720072802002004490d03200d2001280200200410f6041a200128020422062004490d222001200620046b3602042001200128020020046a3602000b200941016a210602402009200f470d002008200620062008491b220fad420c7e220a422088a70d37200aa722164100480d370240024020090d0020161029210e0c010b200e20032016102a210e0b200e450d230b200e20036a2209200d360200200941046a2004ad220a422086200a84370200200841026a21082003410c6a21032006210920102006470d000b0b200e450d26200c450d28200728020022034104490d0220012802002207280000210820012003417c6a22043602042001200741046a36020020044104490d032007280004210d2001200341786a22093602042001200741086a36020041002104200241003a009809200341776a2103034020092004460d05200241d8086a20046a200720046a220641086a2d00003a0000200120033602042001200641096a3602002002200441016a22063a0098092003417f6a210320062104200641c000470d000b200241d0076a41386a2201200241d8086a41386a290300370300200241d0076a41306a2204200241d8086a41306a290300370300200241d0076a41286a2203200241d8086a41286a290300370300200241d0076a41206a2207200241d8086a41206a290300370300200241d0076a41186a2209200241d8086a41186a290300370300200241d0076a41106a2216200241d8086a41106a290300370300200241d0076a41086a2219200241d8086a41086a290300370300200220022903d8083703d007200641ff017141c000490d25200241b8056a41386a22062001290300370300200241b8056a41306a2004290300220a370300200241b8056a41286a20032903002211370300200241b8056a41206a20072903002213370300200241b8056a41186a20092903002212370300200241b8056a41106a20162903002214370300200241b8056a41086a20192903002215370300200220022903d00722173703b805200241d8046a41306a2201200a370300200241d8046a41286a22042011370300200241d8046a41206a22032013370300200241d8046a41186a22072012370300200241d8046a41106a22092014370300200241d8046a41086a22162015370300200241d8046a41386a22192006290300370300200220173703d804200041123a0000200041246a200d360000200041206a20083600002000411c6a2010360000200041186a200f360000200041146a200e360000200041106a20053600002000410c6a2005360000200041086a200c360000200041046a200b360000200020022f0098063b0001200041036a2002419a066a2d00003a0000200041286a20022903d804370000200041306a2016290300370000200041386a2009290300370000200041c0006a2007290300370000200041c8006a2003290300370000200041d0006a2004290300370000200041d8006a2001290300370000200041e0006a201929030037000020004180016a200241e0066a41186a290300370300200041f8006a200241e0066a41106a290300370300200041f0006a200241e0066a41086a290300370300200041e8006a20022903e0063703000c360b200d102e0b02402009450d00200e210103400240200141046a280200450d002001280200102e0b2001410c6a2101200341746a22030d000b0b200f450d24200e102e0c240b02402005450d00200c102e0b02402010450d002010410c6c2104200e210103400240200141046a280200450d002001280200102e0b2001410c6a2101200441746a22040d000b0b200f450d25200e102e0c250b02402005450d00200c102e0b02402010450d002010410c6c2104200e210103400240200141046a280200450d002001280200102e0b2001410c6a2101200441746a22040d000b0b200f450d24200e102e0c240b200441ff0171450d20200241003a0098090c200b200041133a00000c300b20022902d407210a200041033a0000200020022f00b8053b0001200041086a200a370000200041046a2001360000200041036a200241ba056a2d00003a0000200041106a200241d8086a41f80010f6041a0c2f0b200241d8046a41286a200241b8056a41286a290300220a370300200241d8046a41206a200241b8056a41206a2903002211370300200241df076a200241b8056a41086a290300370000200241e7076a200241b8056a41106a290300370000200241ef076a200241b8056a41186a290300370000200241f7076a2011370000200241ff076a2201200a370000200220022903b8053700d707200041083a0000200041096a200241d0076a41086a290000370000200041116a200241d0076a41106a290000370000200041196a200241d0076a41186a290000370000200041216a200241d0076a41206a290000370000200041296a200241d0076a41286a290000370000200020022900d007370001200041306a2001290000370000200041386a200241d8086a41d00010f6041a0c2e0b200241d8046a41206a200241b8056a41206a290300220a370300200241db076a200241b8056a41086a290300370000200241e3076a200241b8056a41106a290300370000200241eb076a200241b8056a41186a290300370000200241f3076a200a370000200220022903b8053700d307200041093a0000200020022900d007370001200041096a200241d0076a41086a290000370000200041116a200241d0076a41106a290000370000200041196a200241d0076a41186a290000370000200041216a200241d0076a41206a290000370000200041286a200241f7076a2800003600002000412c6a200241d8086a41dc0010f6041a0c2d0b200241d8046a41206a200241b8056a41206a290300220a370300200241db076a200241b8056a41086a290300370000200241e3076a200241b8056a41106a290300370000200241eb076a200241b8056a41186a290300370000200241f3076a200a370000200220022903b8053700d3072000410a3a0000200020022900d007370001200041096a200241d0076a41086a290000370000200041116a200241d0076a41106a290000370000200041196a200241d0076a41186a290000370000200041216a200241d0076a41206a290000370000200041286a200241f7076a2800003600002000412c6a200241d8086a41dc0010f6041a0c2c0b1032000b200420031035000b200420031035000b20044104102c000b200420031035000b200320091035000b20104104102c000b20044104102c000b200420061035000b200b4104102c000b200041133a00000c210b20044104102c000b20084104102c000b200420061035000b200420051035000b200420031035000b2006200d1035000b200420051035000b4188014108102c000b200520031035000b20044104102c000b200420061035000b20164104102c000b20044101102c000b20044101102c000b20054101102c000b20044101102c000b02402005450d00200c102e0b02402010450d002010410c6c2104200e210103400240200141046a280200450d002001280200102e0b2001410c6a2101200441746a22040d000b0b200f450d02200e102e0c020b2005450d010b200c102e0b200041133a00000c0d0b20024198066a41086a200241e0066a41086a290300220a370300200220022903e006221137039806200041113a0000200020022f00b8073b0001200041036a200241ba076a2d00003a0000200041186a2003360000200041146a2005360000200041106a20063600002000410c6a2007360000200041086a2004360000200041046a20013600002000411c6a2011370000200041246a200a3700002000412c6a200241b8056a41dc0010f6041a0c0c0b200041133a00000c0b0b200241c4066a41046a220e200241d8066a41046a2d00003a0000200241d8046a41086a220f200241d0076a41086a290300370300200241d8046a41106a220b200241d0076a41106a290300370300200241bc066a41046a220c200241d0066a41046a2d00003a0000200220022f01de063b01cc06200220022802d8063602c406200220022f01d6063b01c206200220022903d0073703d804200220022802d0063602bc06200220022f01ce063b01ba06200041103a00002000200228009806360001200041046a2002419b066a280000360000200041096a20083a0000200041086a20073a0000200041206a2005360000200041186a200a370000200041106a20113700002000410c6a20093600002000410a6a20022f01cc063b0000200041296a20043a0000200041246a20022802c406360000200041286a200e2d00003a000020022f01c2062104200041306a20133700002000412c6a20033600002000412a6a20043b0000200041c8006a200b290300370000200041c0006a200f290300370000200041386a20022903d804370000200041e0006a2014370000200041d8006a2017370000200041e8006a200d360000200041d0006a2012370000200041f0006a200c2d00003a0000200041ec006a20022802bc06360000200041f1006a20013a000020022f01ba06210120004180016a2015370000200041f8006a2018370000200041f4006a2006360000200041f2006a20013b00000c0a0b200241e0066a41086a200241b8056a41086a2903002213370300200220022903b80522123703e006200041386a200a370000200041306a20113700002000410f3a00002000200228009806360001200041046a2002419b066a2800003600002000411c6a2001360000200041186a2004360000200041146a2003360000200041106a20053600002000410c6a2006360000200041086a2007360000200041206a2012370000200041286a2013370000200041c0006a200241d8086a41c80010f6041a0c090b200041133a00000c080b20024198066a41086a200241e0066a41086a2903002213370300200220022903e006221237039806200041c0006a2011370000200041386a200a3700002000410b3a0000200020022800b807360001200041046a200241bb076a2800003600002000411c6a2007360000200041186a2006360000200041146a2005360000200041106a20033600002000410c6a2004360000200041086a2001360000200041206a2012370000200041286a2013370000200041346a2008360000200041306a2009360000200041c8006a20022903d808370300200041d0006a200241d8086a41086a290300370300200041d8006a200241d8086a41106a290300370300200041e0006a200241d8086a41186a290300370300200041e8006a200241d8086a41206a290300370300200041f0006a200241d8086a41286a290300370300200041f8006a200241d8086a41306a29030037030020004180016a200241d8086a41386a2903003703000c070b2004102e0b200041133a00000c050b0b200241ac076a41046a2201200241c4076a41046a2d00003a0000200220022f01d80622043b01c406200220022802c4073602ac07200220022f01d0063b01bc06200041186a2011370000200041106a200a370000200041063a0000200020022800e006360001200041046a200241e3066a280000360000200041096a20093a0000200041086a200f3a0000200041206a20083600002000410c6a20063600002000410a6a20043b0000200041296a200d3a0000200041246a20022802ac07360000200041286a20012d00003a000020022f01bc062101200041386a2012370000200041306a20133700002000412c6a200e3600002000412a6a20013b0000200041c0006a200241d8086a41c80010f6041a0c030b200041133a00000c020b102d000b200041003a0000200020022800d007360001200041106a200a3700002000410c6a2005360000200041086a2009360000200041046a200241d3076a280000360000200041186a200241d8086a41f00010f6041a0b200241e0096a24000b901e07017f027e037f017e037f017e087f230041c0066b22022400420221030240024002400240024002400240200129036822044202520d00200241106a20014198016a41880110f6041a0c010b200241fc016a41026a200141036a2d00003a0000200241e0016a41086a200141146a290200370300200241e0016a410d6a200141196a290000370000200220012f00013b01fc012002200129020c3703e00120012d000021052001280204210620012802082107200241b8026a200141dc006a290000370300200241b0026a200141d4006a290000370300200241a8026a200141cc006a290000370300200241a0026a200141c4006a29000037030020024180026a41186a2001413c6a29000037030020024180026a41106a200141346a29000037030020024180026a41086a2001412c6a2900003703002002200129002437038002200241c0026a41086a20014188016a290300370300200241c0026a41106a20014190016a290300370300200220014180016a2903003703c002200141f8006a29030021032001290370210841002109200241c8036a410010ba01200241c0056a410d6a220a200241c8036a41186a290000370000200241c0056a41086a220b200241db036a290000370300200241f8056a41026a20022d00ca033a0000200241e0056a41086a200b290300370300200241e0056a410d6a200a290000370000200220022f01c8033b01f805200220022900d303220c3703c0052002200c3703e00520022800cb03210d20022800cf03210e200241086a41b0f3c200410d107d02400240024002400240024020044201520d0020084200510d01200228020c410020022802081b210a417f2109200aad220c20032003200c541b220c200c20037d2008827d220c42ffffffff0f560d00200ca721090b41101029220a450d01200a41086a41002900e7f342370000200a41002900dff342370000200a41104120102a220a450d02200a2009360010200241a0066a41186a220f4200370300200241a0066a41106a220b4200370300200241a0066a41086a22104200370300200242003703a006200a4114200241a0066a100020024180066a41186a200f29030037030020024180066a41106a200b29030037030020024180066a41086a2010290300370300200220022903a0063703800620024180066a412041c8ecc500410041001005210f200a102e02400240200f417f470d004101210a411f210941edf4c200210f0c010b200241c8036a200910ba0120024182066a20022d00ca033a0000200241a8066a200241db036a290000370300200241ad066a200241c8036a41186a290000370000200220022f01c8033b018006200220022900d3033703a00620022800cb03210f20022800cf0321094100210a0b200241fc056a41026a221020024180066a41026a2d00003a0000200241c8036a41086a2211200241a0066a41086a2212290300370300200241c8036a41106a200b290300370300200220022f0180063b01fc05200220022903a0063703c80302400240200a450d004101210a2009210e200f210d0c010b200241c4036a41026a200241f8056a41026a2d00003a00002012200241e0056a41086a290300370300200241a0066a410d6a200241e0056a410d6a290000370000200241b7066a20102d00003a000020024180066a410d6a200241c8036a410d6a29000037000020024180066a41086a2011290300370300200220022f01f8053b01c403200220022903e0053703a006200220022f01fc053b00b506200220022903c803370380064100210a0b200241c0036a41026a220b200241c4036a41026a2d00003a0000200241a8036a41086a2210200241a0066a41086a2211290300370300200241a8036a41106a2212200241a0066a41106a29030037030020024190036a41086a221320024180066a41086a29030037030020024190036a410d6a221420024180066a410d6a290000370000200220022f01c4033b01c003200220022903a0063703a8032002200229038006370390030240200a450d002000200d36020420004101360200200041086a200e36020020014198016a102f0c0b0b2002418c036a41026a220a200b2d00003a0000200241f0026a41086a220b2010290300370300200241f0026a41106a22102012290300370300200241d8026a41086a22122013290300370300200241d8026a410d6a22132014290000370000200220022f01c0033b018c03200220022903a8033703f00220022002290390033703d802200241c8036a20014198016a41880110f6041a200241c8036a4198016a2003370300200241d8046a200837030020024187056a200e36000020024183056a200d360000200241e8046a220d20022903c002370300200241f0046a200241c0026a41086a290300370300200241f8046a200241c0026a41106a29030037030020024182056a200a2d00003a00002002418b056a20022903f00237000020024193056a200b2903003700002002419b056a2010290300370000200220043703d004200220022f018c033b018005200241a7056a2009360000200241a3056a200f360000200241ab056a20022903d802370000200241b3056a2012290300370000200241b8056a201329000037000020024190036a41026a200241fc016a41026a2d00003a0000200220022f01fc013b0190032011200241e0016a41086a290300370300200241a0066a410d6a200241e0016a410d6a290000370000200220022903e0013703a0060240200541ff01714101460d00200241fc056a41026a20024190036a41026a2d00003a0000200241a8036a41086a200241a0066a41086a290300370300200241a8036a410d6a200241a0066a410d6a290000370000200220022f0190033b01fc05200220022903a0063703a8030c040b200241e0056a200641067610bb0120022802e005210a0240024020022802e8052006413f7122014b0d00410021010c010b200241fc056a41026a200a20014105746a220141026a2d00003a0000200241b0036a200141136a290000370300200241b5036a200141186a290000370000200220012f00003b01fc052002200129000b3703a8032001280007210720012800032106410121010b024020022802e405450d00200a102e0b20010d034101210141ccc4c2002106411521070c040b41b8e5c5001058000b41104101102c000b41204101102c000b200241e0056a41026a200241fc056a41026a2d00003a0000200241a0066a41086a200241a8036a41086a290300370300200241a0066a410d6a200241a8036a410d6a290000370000200220022f01fc053b01e005200220022903a8033703a006410021010b200241f8056a41026a220a200241e0056a41026a2d00003a000020024180066a41086a2209200241a0066a41086a29030037030020024180066a41106a200241a0066a41106a290300370300200220022f01e0053b01f805200220022903a0063703800602402001450d002000200636020420004101360200200041086a2007360200200241c8036a102f0c060b200241d3056a2009290300370000200241d8056a2002418d066a290000370000200220022f01f8053b01c005200220073600c705200220063600c30520022002290380063700cb052002200a2d00003a00c205200241003602a806200242013703a006200241c8036a200241a0066a10bc010240024020022903d0044201510d000240024020022802a40620022802a8062201460d0020022802a006210a0c010b200141016a220a2001490d0620014101742209200a200a2009491b22094100480d060240024020010d0020091029210a0c010b20022802a00620012009102a210a0b200a450d04200220093602a4062002200a3602a00620022802a80621010b2002200141016a3602a806200a20016a41003a00000c010b20022903e00420022903d8042204420c882203420120034201561b8021030240024020022802a406220a20022802a80622016b4102490d0020022802a006210a0c010b200141026a22092001490d05200a4101742201200920092001491b22014100480d0502400240200a0d0020011029210a0c010b20022802a006200a2001102a210a0b200a450d04200220013602a4062002200a3602a00620022802a80621010b2002200141026a3602a806200a20016a2003a741047420047aa7417f6a22014101200141014b1b2201410f2001410f491b723b00000b200d200241a0066a10662002200241f0046a3602800620024180066a200241a0066a106b20024180056a200241a0066a1046200241a0056a200241a0066a104620022802a406210a20022802a00621010240024020022802a80622094180024b0d0020024180026a20012009200241c0056a10bd0121090c010b200241a0066a41186a220b4200370300200241a0066a41106a220d4200370300200241a0066a41086a220e4200370300200242003703a00620012009200241a0066a100020024180066a41186a200b29030037030020024180066a41106a200d29030037030020024180066a41086a200e290300370300200220022903a0063703800620024180026a20024180066a4120200241c0056a10bd0121090b0240200a450d002001102e0b2009450d04200241c0016a41186a200241c0056a41186a290300370300200241c0016a41106a200241c0056a41106a290300370300200241c0016a41086a200241c0056a41086a29030037030020024198016a41086a200241e0046a29030037030020024198016a41106a200241e8046a29030037030020024198016a41186a200241f0046a290300370300200241b8016a200241f8046a290300370300200220022903c0053703c0012002200241d8046a2903003703980120022903d0042103200241106a200241c8036a41880110f6041a0b200041086a20022903c001370300200041286a2003370300200041306a200229039801370300200041206a200241c0016a41186a290300370300200041186a200241c0016a41106a290300370300200041106a200241c0016a41086a290300370300200041386a20024198016a41086a290300370300200041c0006a20024198016a41106a290300370300200041c8006a20024198016a41186a290300370300200041d0006a20024198016a41206a290300370300200041d8006a200241106a41880110f6041a20004100360200200241c0066a24000f0b20094101102c000b20014101102c000b102d000b200041949dc20036020420004101360200200041086a411a360200200241c8036a102f0b200241c0066a24000be00201047f230041d0006b2202240002400240411010292203450d00200341086a41002900e7f342370000200341002900dff342370000200341104120102a2203450d0120032001360010200241086a41186a22014200370300200241086a41106a22044200370300200241086a41086a220542003703002002420037030820034114200241086a1000200241306a41186a2001290300370300200241306a41106a2004290300370300200241306a41086a200529030037030020022002290308370330200241086a200241306a412010dc010240024020022d00084101460d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20002002290009370000200041186a200241216a290000370000200041106a200241196a290000370000200041086a200241116a2900003700000b2003102e200241d0006a24000f0b41104101102c000b41204101102c000bec0202047f017e230041d0006b22022400024002400240410f10292203450d00200341076a410029008fc24237000020034100290088c2423700002003410f411e102a2203450d012003200136000f200241286a41186a22014200370300200241286a41106a22044200370300200241286a41086a220542003703002002420037032820034113200241286a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903283703002002410036022820024120200241286a100821040240024020022802282201417f460d002002200136022420022004360220200241286a200241206a103020022802282205450d04200229022c210602402001450d002004102e0b20002006370204200020053602000c010b20004100360208200042013702000b2003102e200241d0006a24000f0b410f4101102c000b411e4101102c000b41eff0c2004133200241c8006a4184f4c2001053000bfe8c0203057f017e077f230041206b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d0000220341124b0d00024002400240024002400240024002400240024002400240024002400240024002400240024020030e13000102030405060708090a0b0c0d0e0f101112000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5f20034101742205200420042005491b22054100480d5f0240024020030d002005102921040c010b200128020020032005102a21040b2004450d1420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000280208417f6a220341054b0d1202400240024002400240024020030e06000102030405000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d6420034101742204200020002004491b22044100480d640240024020030d002004102921000c010b200128020020032004102a21000b2000450d1a20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c170b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6320034101742205200420042005491b22054100480d630240024020030d002005102921040c010b200128020020032005102a21040b2004450d1a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200028020c2106200041146a28020022032001104702400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d6320044101742200200520052000491b22004100480d630240024020040d002000102921040c010b200128020020042000102a21040b2004450d1b20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310f6041a0c160b200241023a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6220034101742205200420042005491b22054100480d620240024020030d002005102921040c010b200128020020032005102a21040b2004450d1b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000290310210702400240200141046a2802002200200528020022036b4108490d00200128020021000c010b200341086a22042003490d6220004101742203200420042003491b22034100480d620240024020000d002003102921000c010b200128020020002003102a21000b2000450d1c20012000360200200141046a2003360200200141086a28020021030b200141086a200341086a360200200020036a20073700000c150b200241033a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6120034101742205200420042005491b22054100480d610240024020030d002005102921040c010b200128020020032005102a21040b2004450d1c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200028020c2106200041146a28020022032001104702400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d6120044101742200200520052000491b22004100480d610240024020040d002000102921040c010b200128020020042000102a21040b2004450d1d20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310f6041a0c140b200141086a2802002103200241043a001c024002402003200141046a280200460d00200128020021050c010b200341016a22042003490d6020034101742205200420042005491b22044100480d600240024020030d002004102921050c010b200128020020032004102a21050b2005450d1d20012005360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200520036a41043a0000200028020c2103200041146a2802002200200110472000450d132003200041186c6a2108200141046a2106034020032802002109200341086a280200220020011047024002402006280200220a200428020022056b2000490d002001280200210a0c010b200520006a220b2005490d61200a4101742205200b200b2005491b22054100480d6102400240200a0d0020051029210a0c010b2001280200200a2005102a210a0b200a450d1f2001200a36020020062005360200200428020021050b2004200520006a360200200a20056a2009200010f6041a2003410c6a2802002109200341146a280200220020011047024002402006280200220a200428020022056b2000490d002001280200210a0c010b200520006a220b2005490d61200a4101742205200b200b2005491b22054100480d6102400240200a0d0020051029210a0c010b2001280200200a2005102a210a0b200a450d202001200a36020020062005360200200428020021050b2004200520006a360200200a20056a2009200010f6041a200341186a22032008470d000c140b0b200241053a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5f20034101742205200420042005491b22054100480d5f0240024020030d002005102921040c010b200128020020032005102a21040b2004450d1f20012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41053a0000200028020c2104200041146a2802002203200110472003450d1220042003410c6c6a2108200141046a210903402004280200210a200441086a2802002203200110470240024020092802002205200628020022006b2003490d00200128020021050c010b200020036a220b2000490d6020054101742200200b200b2000491b22004100480d600240024020050d002000102921050c010b200128020020052000102a21050b2005450d212001200536020020092000360200200628020021000b2006200020036a360200200520006a200a200310f6041a2004410c6a22042008470d000c130b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200141046a280200210420052802002103024020002d00014102470d000240024020042003460d00200128020021000c010b200341016a22002003490d5f20034101742204200020002004491b22044100480d5f0240024020030d002004102921000c010b200128020020032004102a21000b2000450d2320012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c120b0240024020042003460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00013a00000c110b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5d20034101742205200420042005491b22054100480d5d0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5d20034101742205200420042005491b22054100480d5d0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041086a200110670c100b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2620012004360200200141046a2005360200200141086a28020021030b200141086a220a200341016a360200200420036a41003a00002000280204210c2000410c6a2802002203200110472003450d0f200c200341f0006c6a210d200141046a210b0340200c41106a20011046200c20011066200c41306a20011046200c41d0006a20011046200c2802042104200c28020c22032001104702402003450d00200341246c21090340200241086a200410452002280208210602400240200b2802002205200a28020022036b20022802102200490d00200128020021050c010b200320006a22082003490d5f20054101742203200820082003491b22034100480d5f0240024020050d002003102921050c010b200128020020052003102a21050b2005450d2a20012005360200200b2003360200200a28020021030b200a200320006a360200200520036a2006200010f6041a0240200228020c450d002006102e0b200441246a21042009415c6a22090d000b0b200c41f0006a220c200d470d000c100b0b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d5b20034101742204200020002004491b22044100480d5b0240024020030d002004102921000c010b200128020020032004102a21000b2000450d2720012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41043a0000200110fc010c0e0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a20034101742205200420042005491b22054100480d5a0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a00002000280208417f6a220341014b0d0d02400240024020030e020001000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d5c20034101742205200420042005491b22044100480d5c0240024020030d002004102921050c010b200128020020032004102a21050b2005450d2a20012005360200200141046a2004360200200141086a28020021030b200041306a2104200141086a200341016a360200200520036a41003a00002000410c6a20011049200241186a21030c010b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d5b20034101742205200420042005491b22044100480d5b0240024020030d002004102921050c010b200128020020032004102a21050b2005450d2a20012005360200200141046a2004360200200141086a28020021030b200041c0006a2104200141086a200341016a360200200520036a41013a00002000410c6a200110492002200041306a36021c2002411c6a2001106b200241086a21030b2003200436020020032001106b0c0d0b02400240200141046a2206280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d592003410174220a20052005200a491b220a4100480d590240024020030d00200a102921050c010b20012802002003200a102a21050b2005450d2920012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41063a000020002d0008417f6a2203410d4b0d0c0240024002400240024002400240024002400240024002400240024020030e0e000102030405060708090a0b0c0d000b200241003a001c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d662003410174220a20052005200a491b220a4100480d660240024020030d00200a102921050c010b20012802002003200a102a21050b2005450d3720012005360200200141046a200a360200200141086a28020021030b200141086a200341016a360200200520036a41003a00002000410c6a200110492002200041306a360208200241086a2001106b20002d0009220341024b0d1902400240024020030e03000102000b200241003a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d6820034101742205200020002005491b22054100480d680240024020030d002005102921000c010b200128020020032005102a21000b2000450d3a20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41003a00000c1b0b200241013a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d6720034101742205200020002005491b22054100480d670240024020030d002005102921000c010b200128020020032005102a21000b2000450d3a20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41013a00000c1a0b200241023a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d6620034101742205200020002005491b22054100480d660240024020030d002005102921000c010b200128020020032005102a21000b2000450d3a20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41023a00000c190b200241013a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6520034101742205200420042005491b22054100480d650240024020030d002005102921040c010b200128020020032005102a21040b2004450d3a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002002200041106a360208200241086a2001106b0c180b200241023a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6420034101742205200420042005491b22054100480d640240024020030d002005102921040c010b200128020020032005102a21040b2004450d3a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002002200041106a360208200241086a2001106b0c170b200241033a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d6320034101742205200020002005491b22054100480d630240024020030d002005102921000c010b200128020020032005102a21000b2000450d3a20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41033a00000c160b200241043a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6220034101742205200420042005491b22054100480d620240024020030d002005102921040c010b200128020020032005102a21040b2004450d3a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41043a0000200041206a200110662002200041106a360208200241086a2001106b0c150b200241053a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6120034101742205200420042005491b22054100480d610240024020030d002005102921040c010b200128020020032005102a21040b2004450d3a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a0000200028020c2103200041146a2802002200200110472000450d14200041246c21000340200320011049200341246a21032000415c6a22000d000c150b0b200241063a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d6020034101742205200020002005491b22054100480d600240024020030d002005102921000c010b200128020020032005102a21000b2000450d3a20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41063a00000c130b200241073a001c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5f2003410174220a20052005200a491b220a4100480d5f0240024020030d00200a102921050c010b20012802002003200a102a21050b2005450d3a20012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41073a000020002d0009220341024b0d1202400240024020030e03000102000b200241003a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d6120034101742205200020002005491b22054100480d610240024020030d002005102921000c010b200128020020032005102a21000b2000450d3d20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41003a00000c140b200241013a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d6020034101742205200020002005491b22054100480d600240024020030d002005102921000c010b200128020020032005102a21000b2000450d3d20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41013a00000c130b200241023a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5f20034101742205200020002005491b22054100480d5f0240024020030d002005102921000c010b200128020020032005102a21000b2000450d3d20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41023a00000c120b200241083a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005102921040c010b200128020020032005102a21040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a00002000410c6a200110490c110b200241093a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5d20034101742205200420042005491b22054100480d5d0240024020030d002005102921040c010b200128020020032005102a21040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a00002000410c6a200110660c100b2002410a3a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5c20034101742205200020002005491b22054100480d5c0240024020030d002005102921000c010b200128020020032005102a21000b2000450d3d20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a410a3a00000c0f0b2002410b3a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5b20034101742205200020002005491b22054100480d5b0240024020030d002005102921000c010b200128020020032005102a21000b2000450d3d20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a410b3a00000c0e0b2002410c3a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5a20034101742205200420042005491b22054100480d5a0240024020030d002005102921040c010b200128020020032005102a21040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a00002000410c6a200110660c0d0b2002410d3a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5920034101742205200420042005491b22054100480d590240024020030d002005102921040c010b200128020020032005102a21040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410d3a0000200028020c2103200041146a2802002200200110472000450d0c20004105742100034020032001104a200341206a2103200041606a22000d000c0d0b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5820034101742205200420042005491b22054100480d580240024020030d002005102921040c010b200128020020032005102a21040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41073a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5820034101742205200420042005491b22054100480d580240024020030d002005102921040c010b200128020020032005102a21040b2004450d3e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041106a2001104a200041306a2001104a200041d0006a2001104a200028020421062000410c6a28020022032001104702400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d5820044101742200200520052000491b22004100480d580240024020040d002000102921040c010b200128020020042000102a21040b2004450d3f20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310f6041a0c0b0b02400240200141046a2206280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d572003410174220a20052005200a491b220a4100480d570240024020030d00200a102921050c010b20012802002003200a102a21050b2005450d3f20012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41083a000020002d0008417f6a220341104b0d0a0240024002400240024002400240024002400240024002400240024002400240024020030e11000102030405060708090a0b0c0d0e0f10000b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6720034101742205200420042005491b22054100480d670240024020030d002005102921040c010b200128020020032005102a21040b2004450d5020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200028020c200110bc012002200041106a360208200241086a2001106b0c1a0b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6620034101742205200420042005491b22054100480d660240024020030d002005102921040c010b200128020020032005102a21040b2004450d5020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a200110660c190b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d6520034101742206200520052006491b22064100480d650240024020030d002006102921050c010b200128020020032006102a21050b2005450d5020012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a41023a00002000410c6a20011066200041096a2d000021052000410a6a2d0000210a02400240200141046a28020020062802002203460d00200128020021000c010b200341016a22002003490d6520034101742206200020002006491b22064100480d650240024020030d002006102921000c010b200128020020032006102a21000b2000450d5120012000360200200141046a2006360200200141086a28020021030b2004200341016a360200200020036a2005410047410774200a723a00000c180b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d6420034101742206200520052006491b22064100480d640240024020030d002006102921050c010b200128020020032006102a21050b2005450d5120012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a41033a00002000410c6a20011066200041096a2d000021052000410a6a2d0000210a02400240200141046a28020020062802002203460d00200128020021000c010b200341016a22002003490d6420034101742206200020002006491b22064100480d640240024020030d002006102921000c010b200128020020032006102a21000b2000450d5220012000360200200141046a2006360200200141086a28020021030b2004200341016a360200200020036a2005410047410774200a723a00000c170b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d632003410174220a20052005200a491b220a4100480d630240024020030d00200a102921050c010b20012802002003200a102a21050b2005450d5220012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41043a0000200028020c21050240024020062802002200200428020022036b4104490d00200128020021000c010b200341046a22062003490d6320004101742203200620062003491b22034100480d630240024020000d002003102921000c010b200128020020002003102a21000b2000450d5320012000360200200141046a2003360200200141086a28020021030b2004200341046a360200200020036a20053600000c160b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6220034101742205200420042005491b22054100480d620240024020030d002005102921040c010b200128020020032005102a21040b2004450d5320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a0000200028020c200110bc010c150b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6120034101742205200420042005491b22054100480d610240024020030d002005102921040c010b200128020020032005102a21040b2004450d5320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a0000200028020c200110bc010c140b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6020034101742205200420042005491b22054100480d600240024020030d002005102921040c010b200128020020032005102a21040b2004450d5320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a0000200028020c200110bc010c130b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5f2003410174220a20052005200a491b220a4100480d5f0240024020030d00200a102921050c010b20012802002003200a102a21050b2005450d5320012005360200200141046a200a360200200141086a28020021030b200141086a220a200341016a360200200520036a41083a0000200041096a20011046200028022c210902400240200141046a2802002205200a28020022036b4104490d00200128020021050c010b200341046a220a2003490d5f20054101742203200a200a2003491b22034100480d5f0240024020050d002003102921050c010b200128020020052003102a21050b2005450d5420012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a2009360000200028023021050240024020062802002200200428020022036b4104490d00200128020021000c010b200341046a22062003490d5f20004101742203200620062003491b22034100480d5f0240024020000d002003102921000c010b200128020020002003102a21000b2000450d5520012000360200200141046a2003360200200141086a28020021030b2004200341046a360200200020036a20053600000c120b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005102921040c010b200128020020032005102a21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a0000200041096a200110460c110b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5d20034101742205200420042005491b22054100480d5d0240024020030d002005102921040c010b200128020020032005102a21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a00002000410c6a200110660c100b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005102921040c010b200128020020032005102a21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a00002000410c6a20011066200041106a20011066200041146a200110660c0f0b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5b20034101742205200420042005491b22054100480d5b0240024020030d002005102921040c010b200128020020032005102a21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a0000200041096a2001104a0c0e0b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5a20034101742205200020002005491b22054100480d5a0240024020030d002005102921000c010b200128020020032005102a21000b2000450d5520012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a410d3a00000c0d0b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5920034101742205200420042005491b22054100480d590240024020030d002005102921040c010b200128020020032005102a21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410e3a0000200041096a2001104a0c0c0b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d582003410174220a20052005200a491b220a4100480d580240024020030d00200a102921050c010b20012802002003200a102a21050b2005450d5520012005360200200141046a200a360200200141086a28020021030b200141086a200341016a360200200520036a410f3a0000200041096a2001104a20002d0029220341064b0d0b0240024002400240024002400240024020030e0700010203040506000b410021000c060b410121000c050b410221000c040b410321000c030b410421000c020b410521000c010b410621000b200220003a001c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5820034101742206200520052006491b22064100480d580240024020030d002006102921050c010b200128020020032006102a21050b2005450d5620012005360200200141046a2006360200200141086a28020021030b2004200341016a360200200520036a20003a00000c0b0b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5720034101742205200020002005491b22054100480d570240024020030d002005102921000c010b200128020020032005102a21000b2000450d5620012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41103a00000c0a0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da10120034101742205200420042005491b22054100480da1010240024020030d002005102921040c010b200128020020032005102a21040b2004450d5720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a0000200041046a200110fd010c090b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da00120034101742205200420042005491b22054100480da0010240024020030d002005102921040c010b200128020020032005102a21040b2004450d5720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a0000200041046a200110fd010c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f0120034101742205200420042005491b22054100480d9f010240024020030d002005102921040c010b200128020020032005102a21040b2004450d5720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a00002000280208417f6a220341094b0d07024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da80120034101742205200420042005491b22054100480da8010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6120012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41003a0000200028020c2104200041146a280200220a200110470240200a450d00200141046a2109034002400240200928020020062802002203460d00200128020021050c010b200341016a22052003490daa012003410174220b20052005200b491b220b4100480daa010240024020030d00200b102921050c010b20012802002003200b102a21050b2005450d64200120053602002009200b360200200628020021030b2006200341016a360200200520036a20042d00003a0000200441016a2104200a417f6a220a0d000b0b200041186a20011066200028021c210402400240200141046a2802002200200628020022036b4104490d00200128020021000c010b200341046a22052003490da80120004101742203200520052003491b22034100480da8010240024020000d002003102921000c010b200128020020002003102a21000b2000450d6320012000360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200020036a20043600000c100b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da70120034101742205200420042005491b22054100480da7010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6320012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41013a0000200028020c2104200041146a280200220a200110470240200a450d00200141046a2109034002400240200928020020062802002203460d00200128020021050c010b200341016a22052003490da9012003410174220b20052005200b491b220b4100480da9010240024020030d00200b102921050c010b20012802002003200b102a21050b2005450d66200120053602002009200b360200200628020021030b2006200341016a360200200520036a20042d00003a0000200441016a2104200a417f6a220a0d000b0b200041186a20011066200028021c210402400240200141046a2802002200200628020022036b4104490d00200128020021000c010b200341046a22052003490da70120004101742203200520052003491b22034100480da7010240024020000d002003102921000c010b200128020020002003102a21000b2000450d6520012000360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200020036a20043600000c0f0b200241023a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da60120034101742205200420042005491b22054100480da6010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a20011066200041106a20011049200041346a20011066200041386a200110660c0e0b200241033a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da50120034101742205200420042005491b22054100480da5010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a00002000410c6a200110660c0d0b200141086a2802002103200241043a001c024002402003200141046a280200460d00200128020021040c010b200341016a22042003490da40120034101742205200420042005491b22054100480da4010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41043a00002000410c6a200110660c0c0b200241053a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da30120034101742205200420042005491b22054100480da3010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a00002000410c6a200110492002200041386a360208200241086a2001106b200041306a200110660c0b0b200241063a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da20120034101742205200420042005491b22054100480da2010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a00002000410c6a200110660c0a0b200241073a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da10120034101742205200420042005491b22054100480da1010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a00002000410c6a200110490c090b200141046a2802002104200241083a001c024002402004200141086a2802002203460d00200128020021040c010b200341016a22042003490da00120034101742205200420042005491b22054100480da0010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a00002000410c6a200110660c080b200241093a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f0120034101742205200420042005491b22054100480d9f010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a00002000410c6a200110660c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e0120034101742205200420042005491b22054100480d9e010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a000020002d0004417f6a220341034b0d06024002400240024020030e0400010203000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da10120034101742205200420042005491b22054100480da1010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041056a2001104a0c090b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da00120034101742205200420042005491b22054100480da0010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041056a2001104a0c080b200241023a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f0120034101742205200420042005491b22054100480d9f010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a0000200041056a2001104a200041256a2001104a0c070b200241033a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e0120034101742205200420042005491b22054100480d9e010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a000020002802082103200041106a2802002200200110472000450d0620004105742100034020032001104a200341206a2103200041606a22000d000c070b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d0120034101742205200420042005491b22054100480d9d010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410d3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d9d0120034101742205200420042005491b22054100480d9d010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041046a200110660c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c0120034101742205200420042005491b22054100480d9c010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410e3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d9c0120034101742205200420042005491b22054100480d9c010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200028020421062000410c6a28020022032001104702400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9c0120044101742200200520052000491b22004100480d9c010240024020040d002000102921040c010b200128020020042000102a21040b2004450d6c20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310f6041a0c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9b0120034101742205200420042005491b22054100480d9b010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410f3a00002000280208417f6a220341024b0d0302400240024020030e03000102000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d0120034101742205200420042005491b22054100480d9d010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002002200041306a360208200241086a2001106b2000410c6a200110490c050b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c0120034101742205200420042005491b22054100480d9c010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a200110660c040b200241023a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9b0120034101742205200420042005491b22054100480d9b010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a200110660c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9a0120034101742205200420042005491b22054100480d9a010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41103a000020002d0008417f6a220341044b0d020240024002400240024020030e050001020304000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e0120034101742205200420042005491b22054100480d9e010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041106a200110fe010c060b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d0120034101742205200420042005491b22054100480d9d010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041186a20011067200028020c2106200041146a28020022032001104702400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9d0120044101742200200520052000491b22004100480d9d010240024020040d002000102921040c010b200128020020042000102a21040b2004450d7520012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310f6041a0c050b200241023a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c0120034101742205200420042005491b22054100480d9c010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000410c6a200110492002200041c0006a360208200241086a2001106b200041d0006a2001106720002802302106200041386a28020022032001104702400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9c0120044101742200200520052000491b22004100480d9c010240024020040d002000102921040c010b200128020020042000102a21040b2004450d7620012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310f6041a0c040b200241033a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9b0120034101742205200420042005491b22054100480d9b010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a00002002200041386a360208200241086a2001106b200041c8006a20011067200041096a20011046200028022c2106200041346a28020022032001104702400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9b0120044101742200200520052000491b22004100480d9b010240024020040d002000102921040c010b200128020020042000102a21040b2004450d7720012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310f6041a0c030b200141086a2802002103200241043a001c024002402003200141046a280200460d00200128020021040c010b200341016a22042003490d9a0120034101742205200420042005491b22054100480d9a010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a0000200041096a2001104a024020002d00294101460d00200241003a001c02400240200141046a28020020052802002203460d00200128020021000c010b200341016a22002003490d9b0120034101742204200020002004491b22044100480d9b010240024020030d002004102921000c010b200128020020032004102a21000b2000450d7920012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c030b200241013a001c02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d9a0120034101742205200420042005491b22054100480d9a010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000412a6a2001104a0c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d990120034101742205200420042005491b22054100480d99010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41113a00002000280204417f6a220341014b0d010240024020030e020001000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9a0120034101742205200420042005491b22054100480d9a010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7b20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000280208200110bc010c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d990120034101742205200420042005491b22054100480d99010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7b20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041086a200110490c010b02400240200141046a220a280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d7b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a41123a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d7c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a41003a00002000280204210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d980120054101742204200920092004491b22044100480d98010240024020050d002004102921050c010b200128020020052004102a21050b2005450d7d20012005360200200141046a2004360200200141086a28020021040b200141086a2209200441046a360200200520046a2006360000200041086a280200210b200041106a28020022042001104702400240200141046a2802002206200928020022056b2004490d00200128020021060c010b200520046a22092005490d980120064101742205200920092005491b22054100480d98010240024020060d002005102921060c010b200128020020062005102a21060b2006450d7e20012006360200200141046a2005360200200141086a28020021050b200141086a2208200520046a360200200620056a200b200410f6041a200041146a28020021062000411c6a28020022042001104702402004450d0020062004410c6c6a210e200141046a210c03402006280200210b200641086a28020022042001104702400240200c2802002209200828020022056b2004490d00200128020021090c010b200520046a220d2005490d9a0120094101742205200d200d2005491b22054100480d9a010240024020090d002005102921090c010b200128020020092005102a21090b2009450d810120012009360200200c2005360200200828020021050b2003200520046a360200200920056a200b200410f6041a2006410c6a2206200e470d000b0b200041206a280200210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d980120054101742204200920092004491b22044100480d98010240024020050d002004102921050c010b200128020020052004102a21050b2005450d800120012005360200200141046a2004360200200141086a28020021040b2003200441046a360200200520046a2006360000200041246a280200210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d980120054101742204200920092004491b22044100480d98010240024020050d002004102921050c010b200128020020052004102a21050b2005450d810120012005360200200141046a2004360200200141086a28020021040b2003200441046a360200200520046a200636000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d820120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00283a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d830120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00293a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d840120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002a3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d850120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002b3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d860120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002c3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d870120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002d3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d880120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002e3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d890120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002f3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d8a0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00303a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d8b0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00313a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d8c0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00323a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d8d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00333a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d8e0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00343a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d8f0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00353a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d900120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00363a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d910120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00373a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d920120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00383a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d930120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00393a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d940120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003a3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d950120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003b3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d960120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003c3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d970120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003d3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450d990120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003e3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450d9a0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003f3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450d9b0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00403a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450d9c0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00413a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450d9d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00423a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450d9e0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00433a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450d9f0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00443a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da00120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00453a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da10120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00463a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da20120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00473a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da30120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00483a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da40120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00493a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da50120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004a3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da60120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004b3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da70120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004c3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da80120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004d3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da90120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004e3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450daa0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004f3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dab0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00503a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dac0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00513a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dad0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00523a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dae0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00533a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450daf0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00543a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db00120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00553a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db10120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00563a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db20120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00573a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db30120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00583a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db40120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00593a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db50120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005a3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db60120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005b3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db70120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005c3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db80120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005d3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db90120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005e3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dba0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005f3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dbb0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00603a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dbc0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00613a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dbd0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00623a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dbe0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00633a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dbf0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00643a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dc00120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00653a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dc10120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00663a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dc20120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00673a00000b200241206a24000f0b20054101102c000b20044101102c000b20054101102c000b20004101102c000b20054101102c000b20034101102c000b20054101102c000b20004101102c000b20044101102c000b20054101102c000b20054101102c000b20054101102c000b20004101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20034101102c000b20044101102c000b20054101102c000b20044101102c000b20044101102c000b200a4101102c000b200a4101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b200a4101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20004101102c000b200a4101102c000b20054101102c000b20054101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b200a4101102c000b20034101102c000b20054101102c000b20054101102c000b20054101102c000b200a4101102c000b20034101102c000b20034101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b200a4101102c000b20064101102c000b20054101102c000b102d000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b200b4101102c000b20034101102c000b20054101102c000b200b4101102c000b20034101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20004101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20004101102c000b20054101102c000b20004101102c000b20054101102c000b20004101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20064101102c000b20064101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20044101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b8305010f7f230041a0026b22042400200441c0016a41386a2205200041386a2206290000370300200441c0016a41306a2207200041306a2208290000370300200441c0016a41286a2209200041286a220a290000370300200441c0016a41206a220b200041206a220c290000370300200441c0016a41186a220d200041186a220e290000370300200441c0016a41106a220f200041106a2210290000370300200441c0016a41086a2211200041086a2212290000370300200420002900003703c0010240024020012002200441c0016a2003100c0d00410121000c010b20052006290000370300200720082900003703002009200a290000370300200b200c290000370300200d200e290000370300200f20102900003703002011201229000037030020044188026a2205200341086a29000037030020044190026a2206200341106a29000037030020044198026a2207200341186a290000370300200420002900003703c00120042003290000370380022004200441c0016a41e00010f604220041c0016a200041e00010f6041a200041e0006a41386a200041386a290000370300200041e0006a41306a200041306a290000370300200041e0006a41286a200041286a290000370300200041e0006a41206a200041206a290000370300200041e0006a41186a200041186a290000370300200041e0006a41106a200041106a290000370300200041e0006a41086a200041086a29000037030020002000290000370360200041a0016a41186a2007290300370300200041a0016a41106a2006290300370300200041a0016a41086a200529030037030020002000290380023703a00120012002200041e0006a200041a0016a10214521000b200441a0026a240020000bda0401057f230041106b220324002003410036020820034201370300200220031047024002400240024002402002450d0020024190016c2104034020032802042105200328020821020240024020012d00004113470d000240024020052002460d00200328020021050c010b200241016a22052002490d0820024101742206200520052006491b22064100480d080240024020020d002006102921050c010b200328020020022006102a21050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a00000c010b0240024020052002460d00200328020021050c010b200241016a22052002490d0720024101742206200520052006491b22064100480d070240024020020d002006102921050c010b200328020020022006102a21050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a00002001200310bc0120014188016a28020021060240024020032802042205200328020822026b4104490d00200328020021050c010b200241046a22072002490d0720054101742202200720072002491b22024100480d070240024020050d002002102921050c010b200328020020052002102a21050b2005450d062003200236020420032005360200200328020821020b2003200241046a360208200520026a20063600000b20014190016a2101200441f07e6a22040d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b20064101102c000b20064101102c000b20024101102c000b102d000bc50301047f230041106b22032400200341003602082003420137030020012003104702400240024002402001450d00200141216c210403400240024020002d00004101460d0002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d0720014101742206200520052006491b22064100480d070240024020010d002006102921050c010b200328020020012006102a21050b2005450d052003200636020420032005360200200328020821010b2003200141016a360208200520016a41003a00000c010b02400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d0620014101742206200520052006491b22064100480d060240024020010d002006102921050c010b200328020020012006102a21050b2005450d052003200636020420032005360200200328020821010b2003200141016a360208200520016a41013a0000200041016a2003104a0b200041216a21002004415f6a22040d000b0b2003280204210020022802002002280204200328020022012003280208100402402000450d002001102e0b200341106a24000f0b20064101102c000b20064101102c000b102d000b6801037f024041094101200128020022024101461b220310292204450d000240024020020d00200441003a0000410121010c010b200441013a000020042001290204370001410921010b2000200136020820002003360204200020043602000f0b20034101102c000b130020004101360204200041ccf0c0003602000b13002000410236020420004184f2c0003602000b3101017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241e8073600000b3101017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241e5003600000bbd0201067f230041c0006b220224000240411610292203450d00200341002900d7f8403700002003410e6a41002900e5f840370000200341086a41002900dff84037000020024296808080e002370224200220033602202001200241206a104a200228022421042002280228210520022802202103200241206a41186a22064200370300200241206a41106a22074200370300200241206a41086a220142003703002002420037032020032005200241206a1000200241186a2006290300370300200241106a2007290300370300200241086a200129030037030020022002290320370300200241206a2002412010c6010240024020022802204101460d00200041003602000c010b20002002290320370200200041086a20012802003602000b02402004450d002003102e0b200241c0006a24000f0b41164101102c000ba50101027f230041206b22032400410021042003410036021420012002200341146a100821010240024020032802142202417f460d002001450d002003410036020c20024104490d0120012800002104200341003602102002417c714104460d01200128000421022001102e200041086a200236020020002004360204410121040b20002004360200200341206a24000f0b41eff0c2004133200341186a4184f4c2001053000bed02030a7f017e017f230041206b220124002001410010c801200141106a410110c80102400240024020012802182202450d004102210320012802042104200128020821050340200128021421062001280210210702400240200420056b200241216c220841216d2209490d00200520096a2109200128020021020c010b200520096a22092005490d0420044101742202200920092002491b220aad42217e220b422088a70d04200ba7220c4100480d040240024020040d00200c102921020c010b2001280200200441216c200c102a21020b2002450d0320012002360200200a21040b2002200541216c6a2007200810f6041a02402006450d002007102e0b200141106a200310c801200341016a210320092105200128021822020d000b20012004360204200120093602080b02402001280214450d002001280210102e0b20002001290300370200200041086a200141086a280200360200200141206a24000f0b200c4101102c000b102d000bc908030c7f037e027f230041e0016b22022400024002400240024002400240410e10292203450d00200341066a41002900f6fa40370000200341002900f0fa403700002003410e411c102a2204450d012004200136000e200241306a41186a22034200370300200241306a41106a22014200370300200241306a41086a220542003703002002420037033020044112200241306a1000200241106a41186a2003290300370300200241106a41106a2001290300370300200241106a41086a200529030037030020022002290330370310200241003602b801200241106a4120200241b8016a100821060240024020022802b8012207417f460d002002200736025420022006360250200241086a200241d0006a103120022802080d072002280254220541216e220841216c2203417f4c0d04200228020c21090240024020030d004101210a0c010b20031029220a450d060b02402009450d004100210b03402005450d0820022005417f6a220536025420022002280250220c41016a360250200c2d0000220341014b0d084100210d0240024020030e020100010b41002103200241003a00d8010340024020052003470d0020024100360254200341ff0171450d0b200241003a00d8010c0b0b200241b8016a20036a200c20036a220141016a2d00003a00002002200141026a3602502002200341016a22013a00d8012001210320014120470d000b200241306a41106a200241b8016a41106a290300220e37030020024198016a41086a200241b8016a41086a29030037030020024198016a41106a200e37030020024198016a41186a200241b8016a41186a2903003703002002200520016b2205360254200220022903b801370398014101210d0b200b41016a2101200241f8006a41186a20024198016a41186a290300220e370300200241f8006a41106a20024198016a41106a290300220f370300200241f8006a41086a20024198016a41086a2903002210370300200241d8006a41086a220c2010370300200241d8006a41106a2211200f370300200241d8006a41186a2212200e3703002002200229039801220e3703782002200e37035802402008200b470d000240200b4101742203200120012003491b2208ad42217e220e422088a70d00200ea722034100480d0002400240200b0d0020031029210a0c010b200a200b41216c2003102a210a0b200a0d0120034101102c000b102d000b200a200b41216c6a2203200d3a000020032002290358370001200341096a200c290300370000200341116a2011290300370000200341196a20122903003700002001210b20012009470d000b0b200a450d072009ad4220862008ad84210e02402007450d002006102e0b2000200e3702042000200a3602000c010b20004100360208200042013702000b2004102e200241e0016a24000f0b410e4101102c000b411c4101102c000b1032000b20034101102c000b2008450d00200a102e0b41eff0c2004133200241b8016a4184f4c2001053000bc00402067f017e230041d0006b220224000240024002400240411310292203450d00200341002900ddfa403700002003410f6a41002800ecfa40360000200341086a41002900e5fa4037000020024293808080b002370224200220033602202001200241206a104a200128022021040240024020022802242201200228022822036b4104490d00200228022021010c010b200341046a22052003490d0320014101742203200520052003491b22034100480d030240024020010d002003102921010c010b200228022020012003102a21010b2001450d022002200336022420022001360220200228022821030b2002200341046a360228200120036a2004360000200228022421052002280228210120022802202103200241206a41186a22044200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032001200241206a1000200241186a2004290300370300200241106a2006290300370300200241086a2007290300370300200220022903203703002002410036022020024120200241206a100821040240024020022802202201417f460d002002200136024420022004360240200241206a200241c0006a104120022802202206450d052002290224210802402001450d002004102e0b20002008370204200020063602000c010b20004100360208200042043702000b02402005450d002003102e0b200241d0006a24000f0b41134101102c000b20034101102c000b102d000b41eff0c2004133200241c8006a4184f4c2001053000bef0302067f047e230041c0006b220224000240024002400240411310292203450d0020034100290086fa403700002003410f6a4100280095fa40360000200341086a410029008efa4037000020024293808080b002370224200220033602202001200241206a104a200228022421042002280228210320022802202105200241206a41186a22014200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020052003200241206a1000200241186a2001290300370300200241106a2006290300370300200241086a2007290300370300200220022903203703002002410036022020024120200241206a1008210320022802202201417f460d022003450d0220014104490d012001417c714104460d01200141786a4110490d01200141686a4110490d012003280000210620032800042107200341106a290000210820032900082109200341206a290000210a2003290018210b02402001450d002003102e0b20002009370308200041206a200a370300200041186a200b370300200041106a20083703002000412c6a2007360200200041286a2006360200420121080c030b41134101102c000b41eff0c2004133200241206a4184f4c2001053000b420021080b2000200837030002402004450d002005102e0b200241c0006a24000bd30102027f027e200028022021020240024002400240410410292203450d002003200236000020002802242102200341044108102a2203450d0120032002360004200041086a290300210420002903002105200341084118102a2203450d0220032005370008200341106a2004370000200041186a290300210420002903102105200341184130102a2200450d0320002005370018200041206a2004370000200128020020012802042000412810042000102e0f0b41044101102c000b41084101102c000b41184101102c000b41304101102c000b13002000410a360204200041c8fbc0003602000b3400200041e0e9c10036020420004100360200200041146a4110360200200041106a41d0a1c100360200200041086a42073702000b3001017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241003600000b2201017f230041106b22022400200241003602002000200210c001200241106a24000b13002000410a360204200041a0bdc1003602000b3101017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241c0003600000b3201017f02404104102922020d0041044101102c000b20004284808080c0003702042000200236020020024180e1013600000b3001017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241013600000b3001017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241063600000b3d01017f02404110102922020d0041104101102c000b200242003700082002428080d287e2bc2d370000200042908080808002370204200020023602000b3d01017f02404110102922020d0041104101102c000b200242003700082002428080e983b1de16370000200042908080808002370204200020023602000b3e01017f02404110102922020d0041104101102c000b2002420037000820024280809aa6eaafe301370000200042908080808002370204200020023602000be50901047f230041206b220224000240024002400240024002400240024002400240024002400240024002402001280200417f6a220341094b0d0020030e0a0102030405060708090a010b4190cec1001058000b2001410c6a2802002203417f4c0d0a200128020421044101210502402003450d00200310292205450d0c0b20052004200310f60421052000410c6a2003360200200041086a20033602002000200536020420004101360200200041106a20012902103703000c090b2001410c6a2802002203417f4c0d09200128020421050240024020030d00410121040c010b200310292204450d0c0b20042005200310f60421052000410c6a2003360200200041086a20033602002000200536020420004102360200200041106a20012902103703000c080b200128020421054101210302400240200141086a22042d00004101460d002002411e6a200441036a2d00003a0000200241086a200141186a290200370300200241106a200141206a290200370300200241186a200141286a2d00003a0000200220042f00013b011c2002200141106a2902003703002001410c6a2802002104410021030c010b2001410c6a28020021040b20002005360204200020022f011c3b0009200041086a20033a00002000410c6a2004360200200041106a20022903003702002000412c6a200129022c3702002000410b6a2002411e6a2d00003a0000200041186a200241086a290300370200200041206a200241106a290300370200200041286a200241186a280200360200200041033602000c070b20004104360200200020012802043602040c060b20004105360200200020012802043602040c050b410121030240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002105410021030c010b200141086a28020021050b200020033a0004200020022f011c3b0005200041306a2001290330370300200041086a20053602002000410c6a2002290300370200200041386a200141386a290300370300200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602002001280228210120004106360200200041286a20013602000c040b20004107360200200020012802043602040c030b410121030240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002101410021030c010b200141086a28020021010b200020033a0004200020022f011c3b000520004108360200200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c020b20004109360200200020012802043602040c010b2000410a360200200020012802043602040b200241206a24000f0b1032000b20034101102c000b20034101102c000ba2a10106197f017e037f017e087f0b7e230041f0046b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e0b000102030405060708090a000b20034184036a4101360200200342013702f402200341cc91c5003602f0022003411c3602c404200341c491c5003602c0042003200341c0046a36028003200341f0026a41eccec100106a000b200141086a2802002104200128020421050240024020022d00000d004101210620022d00014101460d010b41b5f0c2002107412a210841002109410121062004450d282005102e0c280b200241196a2d00002107200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182001410c6a2802002119200141146a280200211a200141106a280200211b20032002411a6a29010037038803200320073a008703200320083a008603200320093b0184032003200a3a0083032003200b3a0082032003200c3b0180032003200d3a00ff022003200e3a00fe022003200f3b01fc02200320103a00fb02200320173a00f202200320183b01f002200320132012410874201141187472723600f702200320162015410874722014411874723600f302200320193602c804200320043602c404200320053602c0042003200341f0026a200341c0046a201b201a10db012003280204210820032802002107410021090c270b200141086a2802002104200128020421050240024020022d00000d0020022d00014101460d010b41b5f0c2002107412a21080c260b2001410c6a2802002118200141146a2802002119200141106a280200211a200241196a2d00002107200241186a2d00002108200241166a2f01002106200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211720032002411a6a2901003703b004200320073a00af04200320083a00ae04200320063b01ac04200320093a00ab042003200a3a00aa042003200b3b01a8042003200c3a00a7042003200d3a00a6042003200e3b01a4042003200f3a00a304200320163a009a04200320173b0198042003201220114108742010411874727236009f042003201520144108747220134118747236009b04410d10292202450d0841002107200241002900fcce41370000200241056a4100290081cf413700002003428d808080d0013702f402200320023602f00220034198046a200341f0026a104a20032802f402210620032802f802210920032802f0022102200341f0026a41186a220a4200370300200341f0026a41106a22084200370300200341f0026a41086a220b4200370300200342003703f00220022009200341f0026a1000200341c0046a41186a200a290300370300200341c0046a41106a2008290300370300200341c0046a41086a200b290300370300200320032903f0023703c004200341f0026a200341c0046a412010dc010240024020032d00f0024101460d000c010b20034189036a290000211c20034188036a2d0000210a20034187036a2d0000210b20034185036a2f0000210c20034184036a2d0000210d20034183036a2d0000210e20034181036a2f0000210f20082d00002110200341ff026a2d00002111200341fd026a2f00002112200341fc026a2d00002113200341f8026a280200211520032802f402211420032d00f302210820032f00f1022109410121070b02402006450d002002102e0b024020070d0041c992c5002107410b21080c260b2003201c370388032003200a3a0087032003200b3a0086032003200c3b0184032003200d3a0083032003200e3a0082032003200f3b018003200320103a00ff02200320113a00fe02200320123b01fc02200320133a00fb02200320153600f702200320143600f302200320083a00f202200320093b01f002200320183602c804200320043602c404200320053602c004200341086a200341f0026a200341c0046a201a201910db01200328020c21082003280208210741012109410021060c260b200141216a290000211c200141206a2d0000210a2001411d6a2f0000210b2001411c6a2d0000210c200141196a2f0000210d200141186a2d0000210e200141156a2f0000210f200141146a2d00002110200141106a28020021112001410c6a2802002105200141086a2d00002117200141306a280200211d2001412c6a280200211e20012d001f211220012d001b211320012d0017211420012d000b211520012f000921162001280204211f2002411a6a2901002120200241196a2d00002118200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d00002121200241126a2f01002122200241116a2d00002123200241106a2d000021242002410e6a2f010021252002410d6a2d00002126200241046a2d00002127200241026a2f01002128412a210841b5f0c20021070240024020022d0000450d004101210641002109410021040c010b41012106410021094100210420022d00014101470d002002410c6a2d000021092002410a6a2f01002104200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021060b200441ffff0371410874200941187472200841ff017172210820060d23200320203703d802200320183a00d702200320193a00d6022003201a3b01d4022003201b3a00d302200320213a00d202200320223b01d002200320233a00cf02200320243a00ce02200320253b01cc02200320263a00cb02200320083600c702200320073600c302200320273a00c202200320283b01c0020240201741ff01714101470d00200341f0026a200541067610bb0120032802f00221070240024020032802f8022005413f7122024b0d00410021020c010b200720024105746a2202290018211c20022d0017210a20022d0016211220022f0014210b20022d0013210c20022d0012211320022f0010210d20022d000f210e20022d000e211420022f000c210f20022d000b2110200228000721112002280003210520022d0002211520022f00002116410121020b024020032802f402450d002007102e0b2002450d230b2003201c370388042003200a3a008704200320123a0086042003200b3b0184042003200c3a008304200320133a0082042003200d3b0180042003200e3a00ff03200320143a00fe032003200f3b01fc03200320103a00fb03200320113600f703200320053600f303200320153a00f203200320163b01f003200341e0036a41086a22024200370300200342003703e00341fcf8c0004114200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e0020240200341e0026a411041c8ecc500410041001005417f460d004189cfc1002107412621080c240b200341f0026a200341c0026a10ca01024020032903f0024201510d0041afcfc1002107411821080c240b200341f0026a200341f0036a10ca01024020032903f0024201510d004192d0c1002107412c21080c240b20034198036a280200210c20034180016a41bfd9c5004111107d41ddcfc10021074116210820032802840141002003280280011b201d470d230240200c41016a201d490d0041f3cfc1002107411f21080c240b200341f0026a201f41067610c80141002107201f413f71220220032802f8024f0d1920032802f002200241216c6a22022d00004101470d1920022f00012106200241196a290000211c200241186a2d00002109200241176a2d00002104200241156a2f00002105200241146a2d0000210a200241136a2d0000210b200241116a2f0000210d200241106a2d0000210e2002410f6a2d0000210f2002410d6a2f000021102002410c6a2d00002111200241086a2800002113200241046a2800002112200241036a2d00002102410121070c1a0b41b5f0c2002107412a210820022d00000d2220022d00014101470d2220012802042116200241196a2d00002107200241186a2d00002108200241166a2f01002106200241156a2d00002109200241146a2d00002104200241126a2f01002105200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a2901003703b004200320073a00af04200320083a00ae04200320063b01ac04200320093a00ab04200320043a00aa04200320053b01a8042003200a3a00a7042003200b3a00a6042003200c3b01a4042003200d3a00a304200320143a009a04200320153b01980420032010200f41087472200e4118747236009f042003201320124108747220114118747236009b04200341e0036a41086a22024200370300200342003703e00341fcf8c0004114200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e0020240200341e0026a411041c8ecc500410041001005417f460d0041a5d1c1002107411e21080c230b411310292202450d0720024100290086fa403700002002410f6a4100280095fa40360000200241086a410029008efa4037000020034293808080b0023702f402200320023602f00220034198046a200341f0026a104a20032802f402210720032802f802210620032802f002210241182108200341f0026a41186a22094200370300200341f0026a41106a22044200370300200341f0026a41086a22054200370300200342003703f00220022006200341f0026a1000200341c0046a41186a2009290300370300200341c0046a41106a2004290300370300200341c0046a41086a2005290300370300200320032903f0023703c004200341c0046a412041c8ecc500410041001005210602402007450d002002102e0b02402006417f470d0041c3d1c10021070c230b200341c0046a201641067610c801410021072016413f71220220032802c8044f0d1620032802c004200241216c6a22022d00004101470d1620022f00012106200241196a290000211c200241186a2d00002109200241176a2d00002104200241156a2f00002105200241146a2d0000210a200241136a2d0000210b200241116a2f0000210c200241106a2d0000210d2002410f6a2d0000210e2002410d6a2f0000210f2002410c6a2d00002110200241086a2800002112200241046a2800002111200241036a2d00002102410121070c170b200128020421052002411a6a290100211c200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d00002113200241046a2d00002114200241026a2f0100211541b5f0c2002107412a21080240024020022d0000450d004101210641002109410021040c010b41012106410021094100210420022d00014101470d002002410c6a2d000021042002410a6a2f01002109200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021060b200941ffff0371410874200841ff017172200441187472210820060d212003201c3703b0042003200a3a00af042003200b3a00ae042003200c3b01ac042003200d3a00ab042003200e3a00aa042003200f3b01a804200320103a00a704200320113a00a604200320123b01a404200320133a00a3042003200836009f042003200736009b04200320143a009a04200320153b019804411610292202450d07200241002900d7f8403700002002410e6a41002900e5f840370000200241086a41002900dff84037000020034296808080e0023702f402200320023602f00220034198046a200341f0026a104a20032802f402210720032802f802210820032802f0022102200341f0026a41186a22064200370300200341f0026a41106a22094200370300200341f0026a41086a22044200370300200342003703f00220022008200341f0026a1000200341c0046a41186a2006290300370300200341c0046a41106a2009290300370300200341c0046a41086a2004290300370300200320032903f0023703c004200341c0046a412041c8ecc500410041001005210802402007450d002002102e0b02402008417f460d0041dbd1c1002107411e21080c220b200341a0016a41f6d9c5004116107d20032802a401210820032802a0012104200341e0036a41086a22024200370300200342003703e00341f4f9c0004112200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002200341003602f002200341e0026a4110200341f0026a1008210720032802f002220a417f460d092007450d092003200a3602c404200320073602c004200341f0026a200341c0046a103020032802f0022206450d08200341f8026a280200210220032802f4022109200a450d0f2007102e0c0f0b200141386a290300211c200141306a29030021202001411d6a29000021292001411c6a2d00002116200141196a2f00002117200141186a2d00002118200141156a2f00002119200141146a2d0000211a200141116a2f0000211b200141106a2d000021212001410c6a2802002122200141086a2802002105200141286a280200211d20012d001b212320012d0017212420012d0013212520012d0007212620012f0005212720012d000421282002411a6a290100212a200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d00002113200241046a2d00002114200241026a2f0100211541b5f0c2002107412a21080240024020022d0000450d004101210641002109410021040c010b41012106410021094100210420022d00014101470d002002410c6a2d000021042002410a6a2f01002109200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021060b200941ffff0371410874200841ff017172200441187472210820060d202003202a370388042003200a3a0087042003200b3a0086042003200c3b0184042003200d3a0083042003200e3a0082042003200f3b018004200320103a00ff03200320113a00fe03200320123b01fc03200320133a00fb03200320083600f703200320073600f303200320143a00f203200320153b01f00302402020201c8450450d0041ebd2c100210741d00021080c210b0240202841ff01714101470d00200341f0026a200541067610bb0120032802f00221070240024020032802f8022005413f7122024b0d00410021020c010b200720024105746a2202290018212920022d0017211620022d0016212320022f0014211720022d0013211820022d0012212420022f0010211920022d000f211a20022d000e212520022f000c211b20022d000b2121200228000721222002280003210520022d0002212620022f00002127410121020b024020032802f402450d002007102e0b2002450d200b200320293703b004200320163a00af04200320233a00ae04200320173b01ac04200320183a00ab04200320243a00aa04200320193b01a8042003201a3a00a704200320253a00a6042003201b3b01a404200320213a00a3042003202236009f042003200536009b04200320263a009a04200320273b01980441112108200341a8026a41bfd9c5004111107d41dad2c100210720032802ac02410020032802a8021b201d470d20200341e0036a41086a22024200370300200342003703e00341fcf8c0004114200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002200341f0026a200341e0026a10dd01024020032802f802220a0d0041add2c1002107412d21080c210b20032902fc02212b200341a0026a41e4d9c5004112107d20034190026a20032802a402410020032802a0021bad42004280a094a58d1d420010fb04411410292202450d0920034190026a41086a290300212a200329039002212c200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702f402200320023602f002200341f0036a200341f0026a104a20032802f4022102200341f8016a20032802f002220820032802f802106e200341f8016a41106a290300420020032802f80122071b2129200329038002420020071b212d02402002450d002008102e0b202d202c542029202a542029202a511b450d0c41ecd3c1002107412e21080c0d0b4101210620022d000120022d0000720d0a20012802042102200341e0036a41086a22074200370300200342003703e00341abd9c5004114200341e0036a1003200341e0026a41086a2007290300370300200320032903e0033703e002200320023602f002200341e0026a4110200341f0026a410410040c0e0b024020022d000120022d000072450d00418df0c2002107412821080c1f0b200141086a2802002107024020012d00044101460d00200141106a2d00002108200141146a2d00002106200141186a2d000021092001411c6a2d0000210420012f0005210220012d00072105200128020c210a20012f0011210b20012d0013210c20012f0015210d20012d0017210e20012f0019210f20012d001b2110200129001d211c0c090b200341f0026a200741067610bb0120032802f00221110240024020032802f8022007413f7122024b0d00410021120c010b201120024105746a2202290018211c20022d0017210420022d0016211020022f0014210f20022d0013210920022d0012210e20022f0010210d20022d000f210620022d000e210c20022f000c210b20022d000b21082002280007210a2002280003210720022d0002210520022f00002102410121120b024020032802f402450d002011102e0b2012450d1d0c080b4101210620022d000120022d0000720d0820012802042102200341e0036a41086a22074200370300200342003703e00341b4f9c000411c200341e0036a1003200341e0026a41086a2007290300370300200320032903e0033703e002200320023602f002200341e0026a4110200341f0026a410410040c0c0b4101210620022d000120022d0000720d0720012802042102200341e0036a41086a22074200370300200342003703e00341a0f9c0004114200341e0036a1003200341e0026a41086a2007290300370300200320032903e0033703e002200320023602f002200341e0026a4110200341f0026a410410040c0b0b410d4101102c000b41134101102c000b41164101102c000b41eff0c2004133200341e8046a4184f4c2001053000b4100210941012106410021020c050b41144101102c000b2003201c3703d802200320043a00d702200320103a00d6022003200f3b01d402200320093a00d3022003200e3a00d2022003200d3b01d002200320063a00cf022003200c3a00ce022003200b3b01cc02200320083a00cb022003200a3600c702200320073600c302200320053a00c202200320023b01c002200341e0036a41086a22024200370300200342003703e00341edf8c000410f200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002200341f0026a200341e0026a10de014100210720032802f402410020032802f00222021b210d4104210b2002410420021b21080240024002400240024002400240200341f0026a41086a2206280200410020021b2205450d002008200541246c22096a21040340200341f0026a41206a200820076a220241206a280200360200200341f0026a41186a200241186a290200370300200341f0026a41106a200241106a2902003703002006200241086a290200370300200320022902003703f002200341f0026a200341c0026a412010f8040d022009200741246a2207470d000b0b410021050240200d0d004100210c0c020b2008102e4104210b4100210c0c010b20034198046a41086a200341f0026a41086a290300221c370300200341f0036a41086a2206201c370300200341f0036a41106a2209200341f0026a41106a290300370300200341f0036a41186a220a200341f0026a41186a290300370300200341f0036a41206a220c200341f0026a41206a280200360200200320032903f002221c370398042003201c3703f00341241029220b450d01200b20032903f003370200200b41206a200c280200360200200b41186a200a290300370200200b41106a2009290300370200200b41086a200629030037020002400240200541246c415c6a2007470d00410121054101210c0c010b200241246a210f2004415c6a2110410121054101210c0340200f210202400340200341f0026a41206a2207200241206a280200360200200341f0026a41186a2206200241186a290200370300200341f0026a41106a2209200241106a290200370300200341f0026a41086a220a200241086a290200370300200320022902003703f002200341f0026a200341c0026a412010f8040d012004200241246a2202470d000c030b0b200341c0046a41206a2007280200220e36020020034198046a41086a200a290300221c37030020034198046a41106a2009290300222037030020034198046a41186a2006290300222a37030020034198046a41206a200e360200200320032903f0022229370398042007200e3602002006202a37030020092020370300200a201c370300200320293703f0020240200c2005470d00200541016a220c2005490d162005410174220e200c200c200e491b220cad42247e221c422088a70d16201ca7220e4100480d160240024020050d00200e1029210b0c010b200b200541246c200e102a210b0b200b450d050b200241246a210f200b200541246c6a220e20032903f002370200200e41206a2007280200360200200e41186a2006290300370200200e41106a2009290300370200200e41086a200a290300370200200541016a210520102002470d000b0b200d450d002008102e0b200341e0036a41086a22024200370300200342003703e00341edf8c000410f200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002200341003602f802200342013703f0022005200341f0026a104702402005450d00200b200541246c6a2104200b210703402007200341f0026a104a200741206a28020021060240024020032802f402220820032802f80222026b4104490d0020032802f00221080c010b200241046a22092002490d1520084101742202200920092002491b22024100480d150240024020080d002002102921080c010b20032802f00220082002102a21080b2008450d05200320023602f402200320083602f00220032802f80221020b2003200241046a3602f802200820026a20063600002004200741246a2207470d000b0b20032802f4022102200341e0026a411020032802f002220720032802f802100402402002450d002007102e0b410021080240200541246c22020d0041012109410021040c040b200241246d220441ffffff3f712004470d12200441057422024100480d122002102922090d0320024101102c000b41244104102c000b200e4104102c000b20024101102c000b02402005450d00200541246c21064100210820092102200b21070340200741086a290000211c200741106a29000021202007290000212a200241186a200741186a290000370000200241106a2020370000200241086a201c3700002002202a370000200841016a2108200241206a2102200741246a21072006415c6a22060d000b0b0240200c450d00200b102e0b200341f0026a41186a200341c0026a41186a290300370300200341f0026a41106a200341c0026a41106a290300370300200341f0026a41086a200341c0026a41086a290300370300200320032903c0023703f0024100210720092008200341e8046a410041202008676b105f41012106200341f0026a41012009200810df012004450d102009102e0c100b418df0c200210741282108410121090c160b200341e0036a41086a22024200370300200342003703e00341d0f9c0004113200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002200341f0026a200341e0026a10e001024020032802f002220c0d0041bbd3c1002107413121080c010b0240024002400240200341f0026a41086a2802002213450d0020032802f402211041bdd4c100210741232108200c290300202054200c41086a2903002229201c542029201c511b0d010c020b4190f9c000410041001038000b200341e0036a41086a22024200370300200342003703e00341edf8c000410f200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002200341f0026a200341e0026a10de010240024020032802f00222040d00410421044100210b410021050c010b200341f8026a280200210520032802f402210b0b2004200541246c6a210920042102410021070240024003400240200920026b41ec004b0d0020092002460d032004200541246c6a2109034020034198046a2002460d032007200220034198046a412010f80422064100476a21072006450d032009200241246a2202470d000c040b0b200220034198046a460d012007200220034198046a412010f80422064100476a21072006450d01200241246a220620034198046a460d012007200620034198046a412010f80422064100476a21072006450d01200241c8006a220620034198046a460d012007200620034198046a412010f80422064100476a21072006450d01200241ec006a220620034198046a460d0120024190016a21022007200620034198046a412010f80422064100476a210720060d000b0b2007202b422088a7490d0041e0d4c100210741362108200b450d012004102e0c010b0240200b450d002004102e0b200341b0026a10c701200341f0026a20034198046a10c50120032802f0024101460d01024020032802b402450d0020032802b002102e0b419ad4c10021070b2010450d01200c102e0c010b20032802b00221260240024002400240024002400240024020032802b80222020d004200212e4200212f0c010b20032802f4022106200241216c2107202641016a2102200341f8026a2802002208410876210941012008411f7174210d20084105764107712204417f73210e20034190036a21054200212e4200212f034002402002417f6a2d00004101470d00200341f0026a200210ca0120032903f0024201520d002003280298032006490d0020052903002130200341f0026a41106a2903002131200329038803213220032903f8022133200341f0016a41bfd9c5004111107d200341c0046a41186a200241186a290000370300200341c0046a41106a200241106a290000370300200341c0046a41086a200241086a290000370300200320022900003703c004200320093602e004200341c0026a200341c0046a10c901420021294200212d0240200420032802c80222084f0d002008200e6a220b20084f0d04203020317c203220337c2229203254ad7c420020032802c002200b4102746a280200200d7122081b212d2029420020081b21290b024020032802c402450d0020032802c002102e0b202d202f7c2029202e7c222e202954ad7c212f0b200241216a21022007415f6a22070d000b0b200c201341306c6a2119200c210202400240024002400240024003400240201920026b4190014b0d00024020022019460d00034041012108200241106a220220034198046a460d04200220034198046a412010f804450d04200241206a22022019470d000b0b41002108202e202085202f201c858450450d0220034198046a41186a290300212a200341a8046a2903002129200341a0046a290300212c200329039804212d200c201c370308200c2020370300200c202d370310200c41186a202c370300200c41206a2029370300200c41286a202a37030020134115490d092013410176221ead42307e221c422088a70d19201ca72202417f4c0d1920020d03410821254108210b0c040b41012108200241106a220720034198046a460d01200720034198046a412010f804450d01200241c0006a220720034198046a460d01200720034198046a412010f804450d01200241f0006a220720034198046a460d01200720034198046a412010f804450d01200241a0016a220720034198046a460d01200241c0016a2102200720034198046a412010f8040d000b0b411410292202450d04200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702f402200320023602f002200341f0036a200341f0026a104a20032802f4022102200341d8016a20032802f002220620032802f802106e200341d8016a41106a290300420020032802d80122071b211c20032903e001420020071b212002402002450d002006102e0b200341f0036a2020202c20202020202c56201c202a56201c202a511b22021b22297d201c202a201c20021b222e7d2020202954ad7d10730240202c20297d222f202a202e7d202c202954ad7d222d84500d00411810292202450d04200241002900ec8c40370000200241106a41002900fc8c40370000200241086a41002900f48c403700002003429880808080033702f402200320023602f002200341f0036a200341f0026a104a20032802f4022102200341c0016a20032802f002220620032802f802106e200341c0016a41106a290300420020032802c00122071b211c20032903c801420020071b212002402002450d002006102e0b200341f0036a2020202f20202020202f56201c202d56201c202d511b22021b222a7d201c202d201c20021b222c7d2020202a54ad7d108c01202c202e7c202a20297c222c202a54ad7c212a0b200341e0036a41086a22024200370300200342003703e00341c28cc0004116200341e0036a1003200341e0026a41086a22062002290300370300200320032903e0033703e002200341a8016a200341e0026a109701200341a8016a41106a290300211c20032903b001212020032802a801210720024200370300200342003703e00341c28cc0004116200341e0036a100320062002290300370300200320032903e0033703e00220034200201c420020071b221c202a7d2020420020071b2220202c54ad7d222a2020202c7d2229202056202a201c56202a201c511b22021b3703f80220034200202920021b3703f002200341e0026a4110200341f0026a411010044196d5c10041acd5c10020081b21074116410f20081b2108410121020c080b200210292225450d012025210b0b200c41506a2128200c41306a211f200c41f07e6a211d41042111410021274100210520132117034020172104410021174101210902402004417f6a2208450d00024002400240024002400240200c200841306c6a2202290300200441306c220e200c6a41a07f6a2207290300222054200241086a290300222a200741086a290300221c54202a201c511b0d002004417e6a210d201d200e6a2102410021174100210703400240200d2007470d00200421090c080b2020200229030022295a2108201c200241086a290300222a512106201c202a5a2109200241506a2102200741016a210720292120202a211c2008200920061b0d000b200741016a21092007417f7320046a21080c010b201d200e6a210202400340024020084101470d00410021080c020b202020022903002229542107201c200241086a290300222a512106201c202a542109200241506a21022008417f6a210820292120202a211c2007200920061b0d000b0b20042008490d01200420134b0d03200420086b22094101762206450d002028200e6a2102200c200841306c6a21070340200341f0026a41286a220d200741286a220e290300370300200341f0026a41206a220f200741206a2212290300370300200341f0026a41186a2214200741186a2215290300370300200341f0026a41106a2216200741106a2217290300370300200341f0026a41086a2218200741086a221a290300370300200320072903003703f002200241086a221b290300211c200241106a22212903002120200241186a2222290300212a200241206a22232903002129200241286a2224290300212c20072002290300370300200e202c370300201220293703002015202a37030020172020370300201a201c3703002024200d2903003703002023200f2903003703002022201429030037030020212016290300370300201b2018290300370300200220032903f002370300200741306a2107200241506a21022006417f6a22060d000b0b024020080d00200821170c050b0240200941094d0d00200821170c050b200420134b0d01200420086b2106201f200841306c6a210d034020042008417f6a2217490d040240200420176b22094102490d00200c200841306c6a2202290300200c201741306c6a2208290300222a5a200241086a22072903002220200841086a220e290300221c5a2020201c511b0d00200341f0026a41186a2212200841286a220f290300370300200341f0026a41106a2214200841206a2215290300370300200341f0026a41086a2216200841186a2218290300370300200320082903103703f00220082002290300370300200e2007290300370300200841106a200241106a2903003703002018200241186a2903003703002015200241206a290300370300200f200241286a29030037030041012107024020094103490d002008290360202a5a200841e8006a2903002220201c5a2020201c511b0d004102210e200d210f0340200f220241506a22072002290300370300200741286a200241286a290300370300200741206a200241206a290300370300200741186a200241186a290300370300200741106a200241106a290300370300200741086a200241086a2903003703002006200e2207460d01200741016a210e200241306a220f290300202a5a200241386a2903002220201c5a2020201c511b450d000b0b2002202a3703002002201c3703082008200741306c6a220241286a2012290300370300200241206a2014290300370300200241186a2016290300370300200220032903f0023703100b2017450d05200d41506a210d200641016a2106201721082009410a4f0d050c000b0b200820041035000b20042008417f6a2217490d010b20042013105e000b201720041035000b02400240024020272005470d00202741016a22022027490d1920274101742207200220022007491b220241ffffffff01712002470d19200241037422074100480d190240024020270d002007102921110c010b201120274103742007102a21110b2011450d01200221270b201120054103746a2202200936020420022017360200200541016a2212210520124102490d010340024002400240024020112012220e417f6a22124103746a2202280200450d00200e41037420116a220941746a2802002206200228020422074d0d0041022105200e41024d0d062011200e417d6a22024103746a2802042208200720066a4d0d0141032105200e41034d0d06200941646a280200200820066a4d0d01200e21050c060b200e4103490d01200228020421072011200e417d6a22024103746a28020421080b20082007490d010b200e417e6a21020b024002400240024002400240200e200241016a22184d0d00200e20024d0d01201120024103746a2214280204221a20142802006a2202201120184103746a22152802002216490d02200220134b0d03201441046a211b200c201641306c6a220d2015280204220f41306c22076a2106200241306c2108200220166b2204200f6b2202200f4f0d0420252006200241306c220710f6041a200b20076a210902400240200f4101480d00200241014e0d010b20062102200b21070c060b202820086a21082006210203402008200241506a2206200941506a22042004290300200629030054200441086a290300221c200641086a290300222054201c2020511b22051b2207290300370300200841086a200741086a290300370300200841106a200741106a290300370300200841186a200741186a290300370300200841206a200741206a290300370300200841286a200741286a2903003703002009200420051b21090240200d2006200220051b2202490d00200b21070c070b200841506a2108200b2107200b2009490d000c060b0b41f484c0002018200e1038000b41f484c0002002200e1038000b201620021035000b20022013105e000b2025200d200710f6041a200b20076a210902400240200f4101480d002004200f4a0d010b200d2102200b21070c010b200c20086a2105200b2107200d210203402002200620072006290300200729030054200641086a290300221c200741086a290300222054201c2020511b22041b2208290300370300200241086a200841086a290300370300200241106a200841106a290300370300200241186a200841186a290300370300200241206a200841206a290300370300200241286a200841286a2903003703002007200741306a20041b2107200241306a2102200641306a200620041b220620054f0d01200920074b0d000b0b20022007200920076b220820084130706b10f6041a201b201a200f6a360200201420163602002015201541086a2018417f73200e6a41037410f7041a20122105201241014d0d020c000b0b20074104102c000b20170d000b02402027450d002011102e0b201e450d052025102e0c050b20024108102c000b41184101102c000b41144101102c000b4190f9c000200b20081038000b20134102490d002013417f6a2108200c201341306c6a21044101210603400240024002400240201320082202417f6a2208490d00201320086b22074102490d03200c200241306c6a2202290300200c200841306c6a2209290300222a5a200241086a22052903002220200941086a220b290300221c5a2020201c511b0d03200341f0026a41186a220d200941286a220e290300370300200341f0026a41106a220f200941206a2211290300370300200341f0026a41086a2212200941186a2214290300370300200320092903103703f00220092002290300370300200b2005290300370300200941106a200241106a2903003703002014200241186a2903003703002011200241206a290300370300200e200241286a2903003703004101210520074103490d022009290360202a5a200941e8006a2903002220201c5a2020201c511b0d02410021052004210703402007220241506a22072002290300370300200741286a200241286a290300370300200741206a200241206a290300370300200741186a200241186a290300370300200741106a200241106a290300370300200741086a200241086a29030037030020062005220b460d02200b417f6a2105200241306a2207290300202a5a200241386a2903002220201c5a2020201c511b0d020c000b0b200820131035000b4102200b6b21050b2002202a3703002002201c3703082009200541306c6a220241286a200d290300370300200241206a200f290300370300200241186a2012290300370300200220032903f0023703100b200441506a21042006417f6a210620080d000b0b200341e0036a41086a22024200370300200342003703e00341d0f9c0004113200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002200341003602f802200342013703f0022013200341f0026a1047200c21020340200241086a290300211c200229030021200240024020032802f402220820032802f80222076b4110490d0020032802f00221080c010b200741106a22062007490d1120084101742207200620062007491b22074100480d110240024020080d002007102921080c010b20032802f00220082007102a21080b2008450d03200320073602f402200320083602f00220032802f80221070b200820076a2208201c370008200820203700002003200741106a3602f802200241106a200341f0026a104a200241306a22022019470d000b20032802f4022102200341e0026a411020032802f002220720032802f802100402402002450d002007102e0b02402010450d00200c102e0b41002102410021070b024020032802b402450d002026102e0b024020020d00202ba7450d160c020b02402010450d00200c102e0b202ba7450d150c010b20074101102c000b200a102e0c130b202ba7450d12200a102e0c120b02400240024002402008410020041b22042005470d0020022005460d010b41f9d1c100210741162108200220054d0d0120034188036a420037030020034180036a4200370300200341f8026a4200370300200342003703f002200620054105746a220a200341f0026a460d00200a200341f0026a412010f8040d010b20034198016a20034198046a4280809aa6eaafe3014200109301200328029801450d01418fd2c1002107411e21080b2009450d122006102e0c120b20034190016a41bfd9c5004111107d200328029001210a200328029401210b411610292207450d01200741002900d7f8403700002007410e6a41002900e5f840370000200741086a41002900dff84037000020034296808080e0023702f402200320073602f00220034198046a200341f0026a104a20032802f402210c20032802f802210720032802f0022108200341f0026a41186a220d4200370300200341f0026a41106a220e4200370300200341f0026a41086a220f4200370300200342003703f00220082007200341f0026a1000200341c0046a41186a200d290300370300200341c0046a41106a200e290300370300200341c0046a41086a200f290300370300200320032903f0023703c004410810292207450d02200720053600042007200b4100200a1b360000200341c0046a41202007410810042007102e0240200c450d002008102e0b0240024020022005460d00200341f0026a41186a220820034198046a41186a290300370300200341f0026a41106a220a20034198046a41106a290300370300200341f0026a41086a220b20034198046a41086a29030037030020032003290398043703f002200220054d0d05200620054105746a220720032903f002370000200741186a2008290300370000200741106a200a290300370000200741086a200b2903003700000c010b200341f0026a41186a220720034198046a41186a290300370300200341f0026a41106a220820034198046a41106a290300370300200341f0026a41086a220a20034198046a41086a29030037030020032003290398043703f002024020092005470d00200541016a22022005490d0c20054101742209200220022009491b220941ffffff3f712009470d0c200941057422024100480d0c0240024020050d002002102921060c010b200620054105742002102a21060b2006450d060b200620054105746a220220032903f002370000200241186a2007290300370000200241106a2008290300370000200241086a200a290300370000200541016a21020b200341e0036a41086a22074200370300200342003703e00341f4f9c0004112200341e0036a1003200341e0026a41086a2007290300370300200320032903e0033703e002200341003602f802200342013703f0022002200341f0026a104702402002450d00200241057421072006210203402002200341f0026a104a200241206a2102200741606a22070d000b0b20032802f4022102200341e0026a411020032802f002220720032802f802100402402002450d002007102e0b02402009450d002006102e0b200341e0036a41086a22024200370300200342003703e00341f6d9c5004116200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002410121062003200441016a3602f002200341e0026a4110200341f0026a410410040b410021070c0b0b41164101102c000b41084101102c000b41e4f9c000200520021038000b20024101102c000b0b024020032802c404450d0020032802c004102e0b024020070d00418dd1c10021070c0b0b2003201c37038803200320093a008703200320043a008603200320053b0184032003200a3a0083032003200b3a0082032003200c3b0180032003200d3a00ff022003200e3a00fe022003200f3b01fc02200320103a00fb02200320123600f702200320113600f302200320023a00f202200320063b01f0020240200341f0026a20034198046a412010f8040d0020034198046a201610e10120034198046a428080e983b1de164200109401200342f0f2bda9c6add9b1f4003703c00220034188016a41b0f3c200410d107d410021072003200328028c0141002003280288011b3602e003200341c0046a20034198046a107c20032802c404210820032802c004210220032802c8042106200341d4046a200341c0026a3602002003200220064105746a3602cc04200320023602c804200320083602c404200320023602c0042003200341e0036a3602d004200341f0036a200341c0046a1044200341c0046a41086a200341f0036a41086a280200360200200320032903f0033703c00420034198046a200341c0046a1090010c0b0b41f4d0c1002107411921080c0a0b0b024020032802f402450d0020032802f002102e0b024020070d0041c7cfc10021070c090b2003201c3703b004200320093a00af04200320043a00ae04200320053b01ac042003200a3a00ab042003200b3a00aa042003200d3b01a8042003200e3a00a7042003200f3a00a604200320103b01a404200320113a00a3042003201336009f042003201236009b04200320023a009a04200320063b019804200341f0026a201e41067610c8014100210702400240201e413f71220220032802f8024f0d0020032802f002200241216c6a22022d00004101470d0020022f00012108200241196a290000211c200241186a2d00002106200241176a2d00002109200241156a2f00002104200241146a2d00002105200241136a2d0000210a200241116a2f0000210b200241106a2d0000210d2002410f6a2d0000210e2002410d6a2f0000210f2002410c6a2d00002110200241086a2800002112200241046a2800002111200241036a2d00002102410121070c010b0b024020032802f402450d0020032802f002102e0b024020070d0041e0d0c1002107411421080c090b2003201c3703d804200320063a00d704200320093a00d604200320043b01d404200320053a00d3042003200a3a00d2042003200b3b01d0042003200d3a00cf042003200e3a00ce042003200f3b01cc04200320103a00cb04200320123600c704200320113600c304200320023a00c204200320083b01c004024020034198046a200341c0026a412010f804450d0041bed0c1002107411221080c090b0240200341c0046a200341f0036a412010f804450d0041d0d0c1002107411021080c090b200341f0026a41186a2213200341f0036a41186a2214290300370300200341f0026a41106a2215200341f0036a41106a2216290300370300200341f0026a41086a2217200341f0036a41086a2218290300370300200320032903f0033703f002410021022003410036029003200341e0036a200341f0026a10c9010240024020032802e80322050d004101210e4100210f0c010b4100210d4100210f4101210e4100211103402005417f4c0d0220032802e403211220032802e00321100240024020051029220a450d00024002400240200541027422020d00410021040c010b201020026a210b410021042010210903402009280200210702400240024002400240412010292202450d00200941046a210920022007411f763a001f200220074101713a000020022007411e764101713a001e20022007411d764101713a001d20022007411c764101713a001c20022007411b764101713a001b20022007411a764101713a001a200220074119764101713a0019200220074118764101713a0018200220074117764101713a0017200220074116764101713a0016200220074115764101713a0015200220074114764101713a0014200220074113764101713a0013200220074112764101713a0012200220074111764101713a0011200220074110764101713a001020022007410f764101713a000f20022007410e764101713a000e20022007410d764101713a000d20022007410c764101713a000c20022007410b764101713a000b20022007410a764101713a000a200220074109764101713a0009200220074108764101713a00082002200741ff017122074107763a0007200220074106764101713a0006200220074105764101713a0005200220074104764101713a0004200220074103764101713a0003200220074102764101713a0002200220074101764101713a00014100210702400340200741206a220841034d0d010240200220076a2208411f6a2d0000450d002007411f6a21060c060b2008411e6a2d00000d042008411d6a2d00000d032007417c6a21072008411c6a2d0000450d000b200741206a21060c040b03402008450d05200220086a21072008417f6a220621082007417f6a2d0000450d000c040b0b41204101102c000b2007411d6a21060c010b2007411e6a21060b200641016a22082006490d000240200520046b2008412020084120491b22074f0d00200420076a22072004490d0a20054101742206200720072006491b22074100480d0a0240024020050d0020071029210a0c010b200a20052007102a210a0b200a450d04200721050b200a20046a2106410021070240034020074120460d01200620076a200220076a2d00004101713a00002008200741016a2207470d000b0b200420076a21040b2002102e2009200b470d000b0b02402012450d002010102e0b0240200f200d6b2004490d00200d20046a21020c030b200d20046a2202200d490d06200f4101742207200220022007491b22074100480d0602400240200f0d0020071029210e0c010b200e200f2007102a210e0b0240200e450d002007210f0c030b20074101102c000b20074101102c000b20054101102c000b200e200d6a200a200410f6041a02402005450d00200a102e0b201320142903003703002015201629030037030020172018290300370300200320032903f0033703f0022003201141016a221136029003200341e0036a200341f0026a10c9012002210d20032802e80322050d000b0b024020032802e403450d0020032802e003102e0b200341e0036a41086a22074200370300200342003703e00341f4f9c0004112200341e0036a1003200341e0026a41086a2007290300370300200320032903e0033703e002200341003602f002200341e0026a4110200341f0026a10082107024020032802f0022208417f460d002007450d00200320083602e403200320073602e003200341f0026a200341e0036a1030024020032802f002220a450d00200341f8026a280200210620032802f402210b02402008450d002007102e0b200641ffffff3f7121070c040b41eff0c2004133200341e8046a4184f4c2001053000b4101210a410021074100210b0c020b1032000b102d000b0240024020072002200220074b1b2208450d004100210720034188036a210620034180036a2109200341f8026a2104200a210203400240200e20076a2d0000450d00200642003703002009420037030020044200370300200342003703f002200341f0026a2002460d002002200341f0026a412010f804450d00200341f0026a200210c5014101210520032802f0024101470d0020032802f402200c4d0d030b200241206a2102200741016a22072008490d000b0b410021050b0240200b450d00200a102e0b0240200f450d00200e102e0b200341c0026a200341f0036a20051b2207201f201e20051b10e101200342f0f2bda9c6add9b1f4003703b002200341f8006a41b0f3c200410d107d2003200328027c410020032802781b3602e002200341f0026a2007107c20032802f402210820032802f002210220032802f802210620034184036a200341b0026a3602002003200220064105746a3602fc02200320023602f802200320083602f402200320023602f0022003200341e0026a36028003200341e0036a200341f0026a1044200341f0026a41086a200341e0036a41086a2202280200360200200320032903e0033703f0022007200341f0026a109001024002402005450d00200341286a200341c0026a428080e983b1de164200109201200341286a41086a290300212a2003290328211c20024200370300200342003703e00341c28cc0004116200341e0036a1003200341e0026a41086a22082002290300370300200320032903e0033703e002200341106a200341e0026a109701200341106a41106a2903002120200329031821292003280210210720024200370300200342003703e00341c28cc0004116200341e0036a100320082002290300370300200320032903e0033703e002200342002020420020071b2220202a7d2029420020071b222a201c54ad7d2229202a201c7d221c202a56202920205620292020511b22021b3703f80220034200201c20021b3703f002200341e0026a4110200341f0026a41101004200341013a00f402200341083a00f002200341f0026a4105722102200341f0026a21080c010b200341e8006a200341c0026a1084012003290368200341e8006a41086a29030084500d04411810292202450d02200241002900ec8c40370000200241106a41002900fc8c40370000200241086a41002900f48c403700002003429880808080033702f402200320023602f002200341f0036a200341f0026a104a20032802f4022102200341d0006a20032802f002220820032802f802106e200341d0006a41106a290300211c200328025021072003290358212002402002450d002008102e0b411410292202450d03201c420020071b222a42002020420020071b221c428080e983b1de16544100202a501b22071b2129201c428080e983b1de1620071b2120200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702f402200320023602f002200341c0026a200341f0026a104a20032802f4022102200341386a20032802f002220820032802f802106e200341386a41106a2903004200200328023822071b212b2003290340420020071b212c02402002450d002008102e0b200341c0026a202c20207c222d202b20297c202d202c54ad7c1073200341f0036a201c20207d202a20297d201c202054ad7d108c0120034185036a200341f0036a41106a2903003700002003418d036a20034188046a290300370000200341083a00f002200341fd026a200341f0036a41086a290300370000200341003a00f402200320032903f0033700f50220034195036a2102200341f0026a21080b200220032903c002370000200241186a200341c0026a41186a290300370000200241106a200341c0026a41106a290300370000200241086a200341c0026a41086a2903003700004100210741c8ecc500410020081072410121060b410121090c060b41184101102c000b41144101102c000b41e98bc0002107412221080c010b41ccc4c2002107411521080b41012106410121090c010b41012109410021062004450d002005102e0b02402001280200417f6a220241014b0d000240024020020e020001000b2009450d01200141086a280200450d012001280204102e0c010b2006450d00200141086a280200450d002001280204102e0b2000200836020420002007360200200341f0046a24000b11002001200028020020002802041093040beb2405087f047e037f027e077f230041a0026b2205240020054180026a41086a22064200370300200542003703800241f4f9c000411220054180026a100320054198016a41086a2006290300370300200520052903800237039801410021062005410036026820054198016a4110200541e8006a100821070240024020052802682208417f460d002007450d0020052008360284022005200736028002200541e8006a20054180026a1030024020052802682206450d00200541f0006a2802002109200528026c210a2008450d022007102e0c020b41eff0c2004133200541d0016a4184f4c2001053000b0b20054180026a41086a2208420037030020054200370380024114210741fcf8c000411420054180026a100320054198016a41086a2008290300370300200520052903800237039801200a410020061b210b2006410120061b210c02400240024020054198016a411041c8ecc500410041001005417f460d0041bbd5c100210a412e21070c010b200541e0006a41bfd9c5004111107d41e9d5c100210a2005280264410020052802601b2003470d0002402009410020061b22060d0041fdd5c100210a41c10021070c010b02402006200241086a28020022084f0d0041bed6c100210a413c21070c010b200541d0006a2001108401200541d0006a41086a290300210d2005290350210e200541e8006a200110ca0102400240024002400240024002400240024002400240024020052903684201510d00411410292206450d03200641002900d88c40370000200641106a41002800e88c40360000200641086a41002900e08c4037000020054294808080c002370284022005200636028002200120054180026a104a2005280284022106200541386a2005280280022207200528028802106e200541386a41106a290300210f200529034021102005280238210902402006450d002007102e0b419ed7c100210a413421072010428180e983b1de16544100200f501b0d0c2009450d0c20054180026a2004410676220a10c8014100210602402005280288022004413f7122074d0d0041014102200528028002200741216c6a2d00001b21060b0240200528028402450d00200528028002102e0b20064102490d0120054198016a200a10c80120054180026a41186a2204200141186a29000037030020054180026a41106a2211200141106a29000037030020054180026a41086a2212200141086a290000370300200520012900003703800220052802a001221320074d0d042005280298012209200741216c6a220641013a00002006200529038002370001200641096a2012290300370000200641116a2011290300370000200641196a2004290300370000410e10292206450d05200641066a41002900f6fa40370000200641002900f0fa403700002006410e411c102a2206450d062006200a36000e20054180026a41186a2207420037030020054180026a41106a220a420037030020054180026a41086a2204420037030020054200370380022006411220054180026a1000200541e0016a41186a2007290300370300200541e0016a41106a200a290300370300200541e0016a41086a200429030037030020052005290380023703e00120054120360284022005200541e0016a360280022009201320054180026a10bf012006102e200528029c01450d022009102e0c020b200541f8006a29030021102005290370210f200541e0016a200441067610c801410021062004413f71220720052802e8014f0d0720052802e001200741216c6a220a2d00004101470d07200541d2016a200a41036a2d00003a0000200541b8016a41086a200a41146a290000370300200541c5016a200a41196a2900003700002005200a2f00013b01d0012005200a410c6a2900003703b801200a41086a2800002107200a41046a280000210a410121060c080b200541306a41d0d9c5004114107d200541b8016a2005280234410020052802301b220a10c801024020052802c00122060d0020054180026a2001428080d287e2bc2d42004108107a02402005280280024101470d002005280288022107200528028402210a20052802bc01450d0c20052802b801102e0c0c0b20054180026a41106a2903002114200529038802210f20054180026a41086a22074200370300200542003703800241c28cc000411620054180026a100320054198016a41086a22042007290300370300200520052903800237039801200541186a20054198016a109701200541186a41106a2903002110200529032021152005280218210920074200370300200542003703800241c28cc000411620054180026a100320042007290300370300200520052903800237039801200542002010420020091b221020147d2015420020091b2214200f54ad7d22152014200f7d220f201456201520105620152010511b22071b3703880220054200200f20071b3703800220054198016a411020054180026a41101004200d200e428080aef89dc3527c220f200e54ad7c427f7c210d200f210e0b200541e0016a41186a2207200141186a290000370300200541e0016a41106a2209200141106a290000370300200541e0016a41086a2204200141086a290000370300200520012900003703e0010240200641c000460d0020054180026a41186a200729030037030020054180026a41106a200929030037030020054180026a41086a2004290300370300200520052903e001370380020240024020052802bc012006460d0020052802b80121070c010b200641016a22072006490d0b20064101742209200720072009491b2209ad42217e220f422088a70d0b200fa722044100480d0b0240024020060d002004102921070c010b20052802b801200641216c2004102a21070b2007450d07200520093602bc01200520073602b8010b2007200641216c6a220741013a00002007200529038002370001200741096a20054180026a41086a2209290300370000200741116a20054180026a41106a290300370000200741196a20054198026a2903003700002005200641016a3602c0012006413f470d0020094200370300200542003703800241d0d9c500411420054180026a100320054198016a41086a20092903003703002005200529038002370398012005200a41016a3602800220054198016a411020054180026a410410040b20054180026a41086a200541b8016a41086a280200360200200520052903b80137038002200a20054180026a10e2010b4200210f200541106a2001428080e983b1de16420010930102402005280210220a450d00200528021421070c0a0b200541086a41e4d9c5004112107d20052802082106200528020c210720054180026a41086a220a4200370300200542003703800241e4d9c500411220054180026a100320054198016a41086a200a2903003703002005200529038002370398012005200741016a410120061b3602800220054198016a411020054180026a41041004420021100c070b41144101102c000b41e4f9c000200720131038000b410e4101102c000b411c4101102c000b20044101102c000b0b024020052802e401450d0020052802e001102e0b0240024020060d00410121064113210741fad6c100210a0c010b200541b4016a41026a200541d0016a41026a2d00003a0000200541e0016a41086a200541b8016a41086a290300370300200541e0016a410d6a200541b8016a410d6a290000370000200520052f01d0013b01b401200520052903b8013703e001410021060b200541b0016a41026a2209200541b4016a41026a2d00003a000020054198016a41086a2204200541e0016a41086a29030037030020054198016a41106a200541e0016a41106a290300370300200520052f01b4013b01b001200520052903e0013703980120060d0220054193026a200429030037000020054198026a200541a5016a290000370000200520052f01b0013b01800220052007360087022005200a36008302200520052903980137008b02200520092d00003a00820220054180026a2001460d0020054180026a2001412010f804450d00418dd7c100210a411121070c020b200542f0f2bda9c6add9b1f4003703d801200541d8016a2001200e200d417f410e109101200541e8006a41186a200d3703002005200e370378200520103703702005200f3703682005200336028c012005200336028801024002400240411310292206450d0020064100290086fa403700002006410f6a4100280095fa40360000200641086a410029008efa4037000020054293808080b002370284022005200636028002200120054180026a104a2005280284022107200528028802210a200528028002210620054180026a41186a2203420037030020054180026a41106a2209420037030020054180026a41086a2204420037030020054200370380022006200a20054180026a1000200541e0016a41186a2003290300370300200541e0016a41106a2009290300370300200541e0016a41086a200429030037030020052005290380023703e00120054120360284022005200541e0016a36028002200541e8006a20054180026a10cb0102402007450d002006102e0b200228020421042002280200210a024002400240200841057622160d0041042117410421180c010b2016410274220610292217450d01201721180b2008450d020240024020160d00410410292217450d0141012116201721180b201841003602002008417f6a21034101211341002107410021060240034002400240024002400240024002400240201320074d0d00201820074102746a22022002280200200a20066a2d00002006411f71746a360200024020032006460d00200641016a2206411f710d0820162013470d07201641016a22022016490d1020164101742209200220022009491b220241ffffffff03712002470d102002410274220941004e0d060c100b02402004450d00200a102e0b410021190340200541e8006a41186a200141186a290000370300200541e8006a41106a200141106a290000370300200541e8006a41086a200141086a2900003703002005201936028801200520012900003703682013410820134108491b221a410274221110292206450d0220062018201110f6042112411310292206450d03200641002900ddfa403700002006410f6a41002800ecfa40360000200641086a41002900e5fa4037000020054293808080b002370284022005200636028002200541e8006a20054180026a104a200528028801210202400240200528028402220720052802880222066b4104490d0020052802800221070c010b200641046a220a2006490d1120074101742206200a200a2006491b22064100480d110240024020070d002006102921070c010b20052802800220072006102a21070b2007450d052005200636028402200520073602800220052802880221060b2013201a6b2113201820116a21182005200641046a36028802200720066a2002360000200528028402211b2005280288022106200528028002211c20054180026a41186a2207420037030020054180026a41106a2202420037030020054180026a41086a220a42003703002005420037038002201c200620054180026a1000200541e0016a41186a2007290300370300200541e0016a41106a2002290300370300200541e0016a41086a200a29030037030020052005290380023703e0014100210620054100360288022005420137038002201a20054180026a1047410020052802880222036b210220052802840221080340200320066a210a201220066a280200210902400240200820026a4104490d0020052802800221070c010b200a41046a2207200a490d1220084101742204200720072004491b22044100480d120240024020080d002004102921070c010b20052802800220082004102a21070b2007450d0720052004360284022005200736028002200421080b2005200a41046a36028802200720036a20066a20093600002002417c6a21022011200641046a2206470d000b200541e0016a41202007200320066a100402402008450d002007102e0b0240201b450d00201c102e0b0240201a450d002012102e0b201941016a211920130d000b2016450d0e2017102e0c0e0b41e4f9c000200720131038000b20114104102c000b41134101102c000b20064101102c000b20044101102c000b0240024020160d002009102921170c010b201720164102742009102a21170b2017450d0320172118200221160b201820134102746a4100360200200741016a2107201341016a21130b200820064b0d000b4190f9c000200620081038000b20094104102c000b41044104102c000b20064104102c000b41134101102c000b2004450d00200a102e0b4100210a0240200b450d00200c102e0b0c020b102d000b0240200b450d00200c102e0b200241046a280200450d002002280200102e0b200020073602042000200a360200200541a0026a24000bcb0201047f230041d0006b220324002003410036022820012002200341286a1008210402400240024020032802282205417f460d0020040d010b200041003a00000c010b41002101200341003a00480340024020052001470d000240200141ff0171450d00200341003a00480b41eff0c2004133200341286a4184f4c2001053000b200341286a20016a200420016a2d00003a00002003200141016a22023a00482002210120024120470d000b200341086a41186a2201200341286a41186a290300370300200341086a41106a2202200341286a41106a290300370300200341086a41086a2206200341286a41086a2903003703002003200329032837030802402005450d002004102e0b20002003290308370001200041013a0000200041196a2001290300370000200041116a2002290300370000200041096a20062903003700000b200341d0006a24000bef0101047f230041206b220224002002410036021020014110200241106a10082101024002400240024020022802102203417f460d0020010d010b200041003602080c010b200220013602082002200336020c20034104490d012002200141046a36020820022003417c6a220436020c20044104490d01200128000021042002200341786a36020c2002200141086a36020820012800042103200241106a200241086a103020022802102205450d012000200229021437020c2000200536020820002003360204200020043602002001102e0b200241206a24000f0b41eff0c2004133200241106a4184f4c2001053000bfa05020e7f037e23004180016b220224002002410036025820014110200241d8006a1008210302400240024002400240024020022802582204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a103120022802080d042002280214220541246e220641246c2201417f4c0d01200228020c21070240024020010d00410421080c010b200110292208450d030b02402007450d00410021090340200241003a00782009220a41016a2109410021010240024002400240034020052001460d01200241d8006a20016a2002280210220b2d00003a00002002200b41016a3602102002200141016a220c3a0078200c2101200c4120470d000b200241386a41086a220d200241d8006a41086a290300370300200241386a41106a220e200241d8006a41106a290300370300200241386a41186a220f200241d8006a41186a2903003703002002200229035837033820022005200c6b220136021420014104490d01200241186a41086a220c200d290300370300200241186a41106a220d200e290300370300200241186a41186a220e200f290300370300200220022903383703182002200b41056a36021020022001417c6a2205360214200b280001210b2006200a470d030240200a4101742201200920092001491b2206ad42247e2210422088a70d002010a7220141004e0d030b102d000b20024100360214200141ff0171450d00200241003a00780b2006450d082008102e0c080b02400240200a0d002001102921080c010b2008200a41246c2001102a21080b2008450d060b2008200a41246c6a22012002290318370200200c2903002110200d2903002111200e29030021122001200b360220200141186a2012370200200141106a2011370200200141086a201037020020092007470d000b0b2008450d042000200636020420002008360200200041086a20073602002004450d002003102e0b20024180016a24000f0b1032000b20014104102c000b20014104102c000b41eff0c2004133200241d8006a4184f4c2001053000bae0f030b7f077e057f230022042105200441c0016b41607122042400024002400240024002400240200141ffffff3f712001470d0020014105742206417f4c0d000240024020060d00410121070c010b200610292207450d020b410021084100210602402001450d0020014105742109416020006b210a2007210620002108034020062008290000370000200641186a200841186a290000370000200641106a200841106a290000370000200641086a200841086a290000370000200641206a2106200841206a2108200941606a22090d000b200020014105746a200a6a41057641016a2106200121080b20042006360218200420083602142004200736021020072006200441206a410041202006676b105f200441a0016a41086a22064200370300200442003703a00141a9c9c200411d200441a0016a100320044180016a41086a2006290300370300200420042903a00137038001200441003602a00120044180016a4110200441a0016a100821080240024020042802a0012206417f460d002004200636024420042008360240200441a0016a200441c0006a103020042802a001220b450d04200441a8016a280200210920042802a401210c2006450d012008102e0c010b4101210b410021094100210c0b2009410574220a450d05200441a0016a411472210d200441a0016a410872210e200b21060340200641086a290000210f200641106a290000211020062900002111200441206a41186a200641186a290000370300200441206a41106a2010370300200441206a41086a200f37030020042011370320200441c0006a200441206a108d03200441003602a80120042903582111200420042903b801221237035820042903502113200420042903b001221437035020042903402115200420042903a0013703402004290348210f200420042903a80122103703482014422088a721002010422088a721012012a721072010a721080240200fa72209450d00200420153703a0012004200f3703a801200420133703b001200420113703b801200420092013a74105746a36028c0120042009360288012004200f422088a73602840120042009360280012004200441106a36029001200441f0006a20044180016a1042200e41086a200441f0006a41086a2216280200360200200e200429037037020020042013422088a722092011422088a74105746a36028c01200420093602880120042011a73602840120042009360280012004200441106a36029001200441f0006a20044180016a1042200d41086a2016280200360200200d200429037037020020042903a801210f20042903a001211320042903b801211020042903b001211102402008450d0002402001450d002008102e0b2007450d002000102e0b200420133703402004200f370348200f422088a72101200420113703502011422088a7210020042010370358200fa721082010a721070b0240024020080d00411a10292208450d06200841186a41002f00dec9423b0000200841106a41002900d6c942370000200841086a41002900cec942370000200841002900c6c9423700002004429a808080a0033702a401200420083602a001200441206a200441a0016a104620042802a401210920042802a801210120042802a0012108200441a0016a41186a22074200370300200441a0016a41106a22004200370300200441a0016a41086a22164200370300200442003703a00120082001200441a0016a100020044180016a41186a200729030037030020044180016a41106a200029030037030020044180016a41086a2016290300370300200420042903a0013703800120044180016a412010062009450d012008102e0c010b411a10292209450d06200941186a41002f00dec9423b0000200941106a41002900d6c942370000200941086a41002900cec942370000200941002900c6c9423700002004429a808080a0033702a401200420093602a001200441206a200441a0016a104620042802a401211620042802a801211720042802a0012109200441a0016a41186a22184200370300200441a0016a41106a22194200370300200441a0016a41086a221a4200370300200442003703a00120092017200441a0016a100020044180016a41186a201829030037030020044180016a41106a201929030037030020044180016a41086a201a290300370300200420042903a00137038001200441203602a401200420044180016a3602a001200441c0006a200441a0016a108e0302402016450d002009102e0b02402001450d002008102e0b2007450d002000102e0b200641206a2106200a41606a220a0d000c060b0b1032000b20064101102c000b41eff0c2004133200441206a4184f4c2001053000b411a4101102c000b411a4101102c000b0240200c450d00200b102e0b200441003602a801200442013703a0012003200441a0016a104702402003450d002003410574210603402002200441a0016a104a200241206a2102200641606a22060d000b0b20042802a401210820042802a801210920042802a0012106200441a0016a41086a22024200370300200442003703a00141edc1c200411b200441a0016a100320044180016a41086a2002290300370300200420042903a0013703800120044180016a411020062009100402402008450d002006102e0b02402004280214450d002004280210102e0b200524000bd505040a7f027e057f017e230041e0006b220224002002410036023820014110200241386a1008210302400240024002400240024002400240024020022802382204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a103120022802080d072002280214220541306e220641306c2201417f4c0d01200228020c21070240024020010d00410821080c010b200110292208450d030b02402007450d004100210903402005220a4110490d05200941016a210b20022002280210220541106a360210200541086a290000210c2005290000210d41002101200241003a0058200a41706a210e03400240200e2001470d0020024100360214200141ff0171450d0a200241003a00580c0a0b200241386a20016a200520016a220f41106a2d00003a00002002200f41116a3602102002200141016a220f3a0058200f2101200f4120470d000b200241186a41186a2210200241386a41186a290300370300200241186a41106a2211200241386a41106a290300370300200241186a41086a2212200241386a41086a29030037030020022002290338370318024020062009470d0020094101742201200b200b2001491b2206ad42307e2213422088a70d082013a722014100480d080240024020090d002001102921080c010b2008200941306c2001102a21080b2008450d070b200e200f6b21052008200941306c6a2201200c3703082001200d37030020012002290318370310200141186a2012290300370300200141206a2011290300370300200141286a2010290300370300200b2109200b2007470d000b2002200a200f6b41706a3602140b2008450d072000200636020420002008360200200041086a20073602002004450d002003102e0b200241e0006a24000f0b1032000b20014108102c000b2002200a3602140c020b20014108102c000b102d000b2006450d002008102e0b41eff0c2004133200241386a4184f4c2001053000be009010d7f23004190016b22022400200241086a2001410676220310c80102400240024002400240200228021022042001413f7122014d0d002002280208200141216c6a220141003a000020012002290028370001200141096a200241286a41086a2205290000370000200141116a200241286a41106a2206290000370000200141196a200241286a41186a22072900003700002005200241086a41086a280200360200200220022903083703282003200241286a10e201200241e4d9c5004112107d2002280200210120022802042103200542003703002002420037032841e4d9c5004112200241286a1003200241f0006a41086a220820052903003703002002200229032837037020022003417f6a417f20011b360228200241f0006a4110200241286a410410042007200041186a22092900003703002006200041106a220a2900003703002005200041086a220b2900003703002002410036024820022000290000370328200241186a200241286a10c90102402002280220450d00410121030340200720092900003703002006200a2900003703002005200b2900003703002002200029000037032820022003417f6a360248411310292201450d03200141002900ddfa403700002001410f6a41002800ecfa40360000200141086a41002900e5fa4037000020024293808080b00237027420022001360270200241286a200241f0006a104a2002280248210c0240024020022802742204200228027822016b4104490d00200228027021040c010b200141046a220d2001490d0620044101742201200d200d2001491b22014100480d060240024020040d002001102921040c010b200228027020042001102a21040b2004450d052002200136027420022004360270200228027821010b2002200141046a360278200420016a200c360000200228027421042002280278210c20022802702101200241f0006a41186a220d4200370300200241f0006a41106a220e420037030020084200370300200242003703702001200c200241f0006a1000200241d0006a41186a200d290300370300200241d0006a41106a200e290300370300200241d0006a41086a200829030037030020022002290370370350200241d0006a4120100602402004450d002001102e0b0240200228021c450d002002280218102e0b200720092900003703002006200a2900003703002005200b2900003703002002200029000037032820022003360248200341016a2103200241186a200241286a10c90120022802200d000b0b0240200228021c450d002002280218102e0b411310292201450d0420014100290086fa403700002001410f6a4100280095fa40360000200141086a410029008efa4037000020024293808080b00237022c200220013602282000200241286a104a200228022c21032002280230210420022802282101200241f0006a41186a22004200370300200241f0006a41106a22054200370300200241f0006a41086a220642003703002002420037037020012004200241f0006a1000200241d0006a41186a2000290300370300200241d0006a41106a2005290300370300200241d0006a41086a200629030037030020022002290370370350200241d0006a4120100602402003450d002001102e0b20024190016a24000f0b41e4f9c000200120041038000b41134101102c000b20014101102c000b102d000b41134101102c000b8b0201047f230041c0006b2202240002400240410e10292203450d00200341066a41002900f6fa40370000200341002900f0fa403700002003410e411c102a2203450d012003200036000e200241206a41186a22004200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034112200241206a1000200241186a2000290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002002412036022420022002360220200128020022002001280208200241206a10bf012003102e0240200141046a280200450d002000102e0b200241c0006a24000f0b410e4101102c000b411c4101102c000ba108010a7f230041a0016b2202240041002103024020012802102204450d0020012802082205200128020c460d00200128021421062001200541246a3602082002413c6a41026a2207200541036a2d00003a0000200241206a41086a2208200541146a290000370300200241206a410d6a2209200541196a290000370000200220052f00013b013c20022005410c6a29000037032020052d0000220a4102460d00200541086a280000210b200541046a280000210520012004417f6a360210200241026a20072d00003a0000200241e0006a41086a2008290300370300200241e0006a410d6a2009290000370000200220022f013c3b010020022002290320370360024002400240200a4101460d002002419c016a41026a200241026a2d00003a000020024180016a41086a200241e0006a41086a29030037030020024180016a410d6a200241e0006a410d6a290000370000200220022f01003b019c0120022002290360370380010c010b200241c0006a200541067610bb01200228024021040240024020022802482005413f7122014b0d00410021010c010b2002419c016a41026a200420014105746a220141026a2d00003a000020024188016a200141136a2900003703002002418d016a200141186a290000370000200220012f00003b019c012002200129000b370380012001280007210b20012800032105410121010b02402002280244450d002004102e0b20010d00410121014115210b41ccc4c20021050c010b200241fc006a41026a2002419c016a41026a2d00003a0000200241e0006a41086a20024180016a41086a290300370300200241e0006a410d6a20024180016a410d6a290000370000200220022f019c013b017c2002200229038001370360410021010b200241dc006a41026a2204200241fc006a41026a2d00003a0000200241c0006a41086a2207200241e0006a41086a290300370300200241c0006a41106a200241e0006a41106a290300370300200220022f017c3b015c200220022903603703400240024020010d002002419c016a41026a20042d00003a000020024180016a41086a200729030037030020024180016a410d6a200241c0006a410d6a290000370000200220022f015c3b019c012002200229034037038001410121010c010b2006200b36020420062005360200410021010b2002411c6a41026a22042002419c016a41026a2d00003a0000200241086a220720024180016a41086a2903003703002002410d6a220820024180016a410d6a290000370000200220022f019c013b011c20022002290380013703002001450d00200020022f011c3b0001200041086a200b360000200041046a20053600002000410c6a2002290300370000200041036a20042d00003a0000200041146a2007290300370000200041196a2008290000370000410121030b200020033a0000200241a0016a24000ba70605057f017e067f017e027f23004190026b22022400200241086a200110310240024002400240024020022802080d00200228020c210320024200370214200241e08dc00036021002402003450d00200241b0016a4102722104200241106a41086a2105410021060340200241286a2001107e02400240024020022d00284101460d002002290029210720022001103120022802000d00200128020420022802042208490d002008417f4c0d07024002400240024020080d00410121090c010b200810342209450d0120012802042008490d0220092001280200200810f6041a2001280204220a2008490d0b2001200a20086b3602042001200128020020086a3602000b200220073703202002280210220b41e08dc000460d032002280214210c0c040b20084101102c000b2009102e0b200228021821082002280214210a2002280210210d20004100360200200d200a200810e5010c050b2004410041da0010f5041a200241286a410041840110f5041a41e4011029220b450d074100210c200b4100360200200b41046a200241b0016a41dc0010f6041a200b41e0006a200241286a41840110f6041a200241003602142002200b3602100b200641016a21062008ad220e422086200e84210e024002400340200b41086a210a200b2f0106220f41037421084100210d024003402008450d01200241206a200a410810f8042210450d03200841786a2108200d41016a210d200a41086a210a2010417f4a0d000b200d417f6a210f0b0240200c450d00200c417f6a210c200b200f4102746a41e4016a280200210b0c010b0b2002200737023c200220053602382002200f3602342002200b36022c200241003602282002200241106a3602302002200e3702b401200220093602b001200241286a200241b0016a10e6010c010b200b200d410c6c6a220841e4006a220a280200210d200a200e370200200841e0006a220a2802002108200a20093602002008450d00200d450d002008102e0b20062003470d000b0b20022903102107200041086a2002280218360200200020073702000c010b200041003602000b20024190026a24000f0b1032000b2008200a1035000b41e4014104102c000bd90303027f017e027f02402001450d00034020002802e40121002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d0020002001410c6c6a220441e4006a2902002105200441e0006a2802002104200141016a21010c010b02400240200028020022010d002003ad210541002106410021010c010b20003301044220862003ad842105410121060b2000102e2005a72103024002402005422088a7220720012f01064f0d00200121040c010b034002400240200128020022040d002003ad2105410021040c010b200641016a210620013301044220862003ad8421050b2001102e2005a72103200421012005422088a7220720042f01064f0d000b0b200741027420046a41e8016a280200210020042007410c6c6a220141e4006a2902002105200141e0006a280200210402402006417f6a2201450d00034020002802e40121002001417f6a22010d000b0b410021010b2004450d012002417f6a210202402005a7450d002004102e0b20020d000b0b0240200041e08dc000460d00200028020021012000102e2001450d00200128020021042001102e2004450d00024020042802002201450d0003402004102e2001210420012802002200210120000d000b0b2004102e0b0be71207027f017e057f027e017f017e0a7f230041b0036b2202240020002802102203200328020041016a36020020002902142104200028020c2103200028020821052000280200210620002802042100200241f0016a41086a2207200141086a280200360200200220012902003703f001024002400240024020002f01062201410b490d00200241d0026a410272410041da0010f5041a200241386a410041840110f5041a0240024041e40110292208450d0020084100360200200841046a200241d0026a41dc0010f6041a200841e0006a200241386a41840110f6042107200241386a41086a2209200041b0016a280200360200200220002902a8013703382000413c6a330000210a2000413e6a310000210b20002d003f210c2000350038210d200841086a200041c0006a20002f010641796a220141037410f604210e2007200041b4016a2001410c6c10f6042107200041063b0106200820013b0106200241d0026a41086a2009280200360200200220022903383703d002200d200a200b4210868442208684210a0240024020034107490d002003410374200e6a41506a200e200341796a22094103746a220e200141ffff037120096b41037410f7041a200e20043700002003410c6c20076a220341b87f6a200341ac7f6a2203200841066a22012f010020096b410c6c10f7041a200341086a200241f0016a41086a280200360200200320022903f0013702000c010b200041086a20034103746a220741086a2007200041066a22012f010020036b41037410f7041a20072004370000200041e0006a2003410c6c6a2207410c6a200720012f010020036b410c6c10f7041a200741086a200241f0016a41086a280200360200200720022903f0013702000b200120012f010041016a3b0100200241286a41086a220f200241d0026a41086a22102802002203360200200241086a221120033602002002200c3a0017200220022903d00222043703282002200a3e02102002200a4230883c00162002200a4220883d011420022004370300200229031021042000280200220c450d0320002f01042112200241d0026a410272211303402002200641016a22063602202002200c360224200f201128020036020020022002290300370328201241ffff03712109024002400240200c2f01062200410b490d002013410041da0010f5041a200241f0016a200241d0026a41dc0010f6041a200241386a410041b40110f5041a41940210292207450d0520074100360200200741046a200241f0016a41dc0010f6041a200741e0006a200241386a41b40110f6042103200c41386a290000210a200241386a41086a2214200c41b0016a2802003602002002200c41a8016a290200370338200741086a200c41c0006a200c2f0106220141796a220041037410f60421152003200c41b4016a2000410c6c10f6042116200741e4016a200c4180026a2001417a6a220e41027410f6042117200c41063b0106200720003b01060240200e450d00410021002017210303402003280200220120003b010420012007360200200341046a2103200e200041016a2200470d000b0b20102014280200220036020020022002290338220b3703d002201420003602002002200b370338201241ffff037122034107490d0120152009417a6a22034103746a2015200941796a22004103746a220120072f010620006b41037410f7041a200120043700002009410c6c20166a220141b87f6a200141ac7f6a220120072f0106220e20006b410c6c10f7041a200141086a200f280200360200200120022903283702002007200e41016a22013b01062009410274221220176a416c6a201720034102746a220e200141ffff0371220920036b41027410f7041a200e200836020020092003490d02200720126a41cc016a2103034020032802002201200041016a22003b010420012007360200200341046a210320002009490d000c030b0b200c41086a2201200941016a22034103746a200120094103746a2201200020096b220741037410f7041a20012004370000200c2009410c6c6a220141ec006a200141e0006a220e2007410c6c10f7041a200141e8006a200241286a41086a280200360200200e2002290328370200200c200041016a22003b01062009410274200c41e4016a22016a41086a200120034102746a2201200041ffff0371220720036b41027410f7041a20012008360200201241ffff037120074f0d07200c2003417f6a22004102746a41e8016a2103034020032802002201200041016a22003b01042001200c360200200341046a210320002007490d000c080b0b200c41086a2200200941016a220e4103746a200020094103746a2200200c2f0106220120096b221241037410f7041a20002004370000200c41e0006a2009410c6c6a2200410c6a20002012410c6c10f7041a200041086a200f28020036020020002002290328370200200c200141016a22003b010620094102742217200c41e4016a22016a41086a2001200e4102746a2212200041ffff03712201200e6b41027410f7041a20122008360200200320014f0d00200c20176a41e8016a2100034020002802002203200941016a22093b01042003200c360200200041046a210020012009470d000b0b200241106a41086a2014280200220036020020112000360200200220022903382204370310200220043703000240200c28020022000d0020072108200a21040c050b200c2f010421122000210c200a2104200721080c000b0b41e4014104102c000b4194024104102c000b200020034103746a220941106a200941086a2209200120036b41037410f7041a2009200437000020002003410c6c6a220141ec006a200141e0006a220920002f010620036b410c6c10f7041a200141e8006a2007280200360200200920022903f001370200200020002f010641016a3b01060c010b200241d0026a410272410041da0010f5041a200241f0016a200241d0026a41dc0010f6041a200241386a410041b40110f5041a41940210292200450d0120004100360200200041046a200241f0016a41dc0010f6041a200041e0006a200241386a41b40110f60421012000200528020022033602e401200520003602002005200528020441016a360204200341003b010420032000360200200120002f01062203410c6c6a22012002290300370200200020034103746a41086a2004370000200141086a200241086a280200360200200041e4016a200341016a22034102746a2008360200200020033b0106200820033b0104200820003602000b200241b0036a24000f0b4194024104102c000bc70102037f027e230041306b220324000240411410292204450d00200441002900d88c40370000200441106a41002800e88c40360000200441086a41002900e08c4037000020034294808080c002370224200320043602202002200341206a104a20032802242104200341086a200328022022052003280228106e200341086a41106a2903004200200328020822021b21062003290310420020021b210702402004450d002005102e0b2000200737030020002006370308200341306a24000f0b41144101102c000bef0101057f230041c0006b220524000240024020030d00200041003602000c010b2003280208210620032802002103200541206a41186a22074200370300200541206a41106a22084200370300200541206a41086a220942003703002005420037032020044120200541206a1000200541186a2007290300370300200541106a2008290300370300200541086a200929030037030020052005290320370300200541003602202003200620054120200541206a10012104024020052802202203417f460d002000200336020420002004360200200041086a20033602000c010b200041003602000b200541c0006a24000baf0201027f23004190016b220324002003200210af010240024020032d000022024102470d00200041003a00000c010b200341e0006a200341286a290300370300200341e8006a200341306a290300370300200341d8006a41186a200341386a290300370300200341d8006a41206a200341c0006a290300370300200341d8006a41286a200341c8006a290300370300200341d8006a41306a200341d0006a2802003602002003200341206a29030037035802402002450d00200041003a00000c010b2003411c6a2802002102200341186a28020021042000200329026c370001200041013a0000200041196a20034184016a290200370000200041116a200341fc006a290200370000200041096a200341d8006a411c6a2902003700002002450d002004102e0b20034190016a24000b970201067f230041c0006b220224000240411710292203450d00200341002900b0a5433700002003410f6a41002900bfa543370000200341086a41002900b8a54337000020024297808080f002370224200220033602202001200241206a104a200228022421012002280228210420022802202103200241206a41186a22054200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032004200241206a1000200241186a2005290300370300200241106a2006290300370300200241086a2007290300370300200220022903203703002002412041c8ecc500410041001005210402402001450d002003102e0b200241c0006a24002004417f470f0b41174101102c000b870102017f037e230041e0006b22032400200341086a200210af010240024020032d000822024102470d00420021040c010b2002410173ad2104200341186a2903002105200341106a290300210620020d00200341246a280200450d00200341206a280200102e0b2000200637030820002004370300200041106a2005370300200341e0006a24000bb6220a057f047e0c7f047e027f027e037f027e0b7f017e23004190056b22022400200128020821032001280200210402400240200128020422050d00200421010c010b2005210620042101034020012802880b21012006417f6a22060d000b0340200420042f01064102746a41880b6a28020021042005417f6a22050d000b0b2002418c016a20042f0106360200200241f0006a41186a410036020020024184016a20043602002002200336029001200241003602800142002107200242003703782002200136027420024100360270200241d8016a200241f0006a10ed010240024020022903f80122084202520d00420021094200210a0c010b2002418c026a210b200241d8016a412c6a210c200241d8016a410472210d200241d8016a41086a2103200241b8036a412c6a210e200241b5026a210f200241a0026a211020024188026a21114187a5c30041ffa4c3006b20024188046a6b20024188046a41206a6a410f6a211242002107420021094200210a0340200241b8016a41086a22052003290300370300200241b8016a41106a2206200241d8016a41106a2204290300370300200241b8016a41186a2213200241d8016a41186a220129030037030020024198016a41086a2214200f41086a29000037030020024198016a41106a2215200f41106a29000037030020024198016a41186a2216200f41186a290000370300200220022903d8013703b8012002200f2900003703980120102903002117201129030021182002290398022119200229038002211a20022d00b402211b20022802b002211c20022903a802211d200229039002211e200241d8026a41186a221f2013290300370300200241d8026a41106a22202006290300370300200241d8026a41086a22062005290300370300200220022903b8013703d802200241f8026a41186a22052016290300370300200241f8026a41106a22132015290300370300200241f8026a41086a2216201429030037030020022002290398013703f802024002400240024002400240024002400240024002400240024020084201520d00200241d8016a200241d8026a201a2018106f20022d00f0012114200241d8006a200a2007200920022903d80120022903e001200429030010a501200241d8006a41106a2903002109200229036021072002290358210a20140d010b0240201b41ff017122154101460d00201e4201510d00201c450d090b200241d8016a200241d8026a10af010240024020022d00d8012214417f6a221b41014b0d000240201b0e020002000b20140d0220022802f401450d0220022802f001102e0c020b20024198036a41086a2214200b41086a29020037030020024198036a41106a221b200b41106a29020037030020024198036a41186a2221200b41186a2902003703002002200b290200370398032004290300212220022903e00121232002280288022124200228028002212520022802fc01212620022802f801212720022802f401212820022802f001212920022802ac02212a0240200228028402222b4102470d0020150d030c020b2027417f4c0d050240024020270d00410121060c010b202710292206450d0520062029202710f6041a0b200e200229039803370200200e41086a2014290300370200200e41106a201b290300370200200e41186a2021290300370200200220233703b803200220243602e003200220253602d803200220263602d403200220273602d003200220273602cc03200220063602c803200220223703c0032002202b410146222c3602dc032027212d2027211b2025212e202321182022212f202621140c030b024020140d0020022802f401450d0020022802f001102e0b4102212b20150d010b201da7210402400240201d422088a722050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b2002201c3602f801200241003602f001200241003602e801200242003703e001200220013602dc01200241003602d801200220043602ec01200220042f01063602f401200241d8016a10ee010c0a0b200241c8006a4197a1c5004117108101200228024821142002290350210820034200370300200242003703d8014197a1c5004117200241d8016a100320024188046a41086a221b2003290300370300200220022903d801370388042002200842017c420120141b22083703d80120024188046a4110200241d8016a41081004412010292214450d05201420022903d802370000201441186a201f290300370000201441106a2020290300370000201441086a20062903003700002014412041c000102a2214450d0420142008370020200142003703002004420037030020034200370300200242003703d80120144128200241d8016a100020024188046a41186a200129030037030020024188046a41106a2004290300370300201b2003290300370300200220022903d80137038804413710292206450d03200642bac6a1cbc68dd9aff300370000200642f4dec98bf6ac999de400370008200641e5cc85ab073600102006413a3a0016200641ece8013b00142006200229038804370017200620022f0190043b001f2006200228019204360021200620022f0196043b0025200620022d0098043a0027200620022d0099043a0028200620022d009a043a0029200620022d009b043a002a200620022d009c043a002b200620022d009d043a002c200620022d009e043a002d200620022d009f043a002e200620022d00a0043a002f200620022d00a1043a0030200620022d00a2043a0031200620022d00a3043a0032200620022d00a4043a0033200620022d00a5043a0034200620022d00a6043a0035200620022d00a7043a00362014102e200241c0006a41b0f3c200410d107d2002280244211b2002280240211f200e20022903f80237000041082114200e41086a200241f8026a41086a290300370000200e41106a2013290300370000200e41186a2005290300370000427f21182002427f3703c0032002427f3703b803200241083602d403200220123602d0034137212d200241373602cc03200220063602c8034100212c200241003602dc032002201b4100201f1b222e3602d8032012211b427f212f0b0240201e4201520d00200220193703b803200220173703c003201921182017212f0b02402015450d00200e20022903f802370000200e41186a2005290300370000200e41106a2013290300370000200e41086a20162903003700000b0240201c450d00200241386a41b0f3c200410d107d4101212c200241013602dc032002200228023c410020022802381b3602e0030b201da7210502400240201d422088a722150d00200521130c010b2015211620052113034020132802ec0321132016417f6a22160d000b0340200520052f01064102746a41ec036a28020021052015417f6a22150d000b0b20052f010621152002201c3602a804200220153602a404200241003602a0042002200536029c04200241003602980420024200370390042002201336028c042002410036028804200241d8016a20024188046a10ef0120022802d8014101470d070340200241b0046a41186a200d41186a290200221d370300200241b0046a41106a200d41106a2902002208370300200241b0046a41086a200d41086a290200221e3703002002200d290200221a3703b00420022802fc01210520022802800221202002280284022113200241d0046a41186a201d370300200241d0046a41106a2008370300200241d0046a41086a201e3703002002201a3703d004200142003703002004420037030020034200370300200242003703d801200241d0046a4120200241d8016a1000200241f0046a41186a22162001290300370300200241f0046a41106a221c2004290300370300200241f0046a41086a221f2003290300370300200220022903d8013703f004200241003602d8012006201b200241f0046a4120200241d8016a10012121024020022802d8012215417f460d00201420156b21142015450d002021102e0b024002402005450d00200142003703002004420037030020034200370300200242003703d801200241d0046a4120200241d8016a100020162001290300370300201c2004290300370300201f2003290300370300200220022903d8013703f0042006201b200241f0046a412020052013100b201420136a21142020450d012005102e0c010b200142003703002004420037030020034200370300200242003703d801200241d0046a4120200241d8016a100020162001290300370300201c2004290300370300201f2003290300370300200220022903d8013703f0042006201b200241f0046a412010020b200241d8016a20024188046a10ef0120022802d8014101470d070c000b0b20274101102c000b1032000b41374101102c000b41c0004101102c000b41204101102c000b201da7210402400240201d422088a722050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b200241003602f801200241003602f001200241003602e801200242003703e001200220013602dc01200241003602d801200220043602ec01200220042f01063602f401200241d8016a10ee010c020b200220143602d4030b20024188046a10ee0120024188046a41186a220420024198036a41186a29030037030020024188046a41106a220120024198036a41106a29030037030020024188046a41086a220520024198036a41086a29030037030020022002290398033703880402400240202b4102460d00200c200229038804370200200c41086a2005290300370200200c41106a2001290300370200200c41186a2004290300370200200220233703d80120022024360280022002202b3602fc01200220253602f801200220263602f401200220283602ec01200220293602e8012002202a3602a402200220223703e001200220273602f0014101210402402027201b470d000240024020292006460d0020292006202710f8040d0220262014470d020c010b20262014470d010b200c200e412010f8040d0020232018852022202f858450450d002025202e470d00202b202c470d00202b410146202420022802e003477121040b02402028450d002029102e0b20044102460d002004450d010b2003200241b8036a41d00010f6041a200241003a00d801200241d8026a200241d8016a10f0010c010b202d450d002006102e0b200241d8016a200241f0006a10ed0120022903f80122084202520d000b0b200241f0006a105402400240200a500d00200241d8016a41086a22044200370300200242003703d80141c28cc0004116200241d8016a1003200241b8036a41086a22052004290300370300200220022903d8013703b803200241206a200241b8036a109701200241306a290300211d200229032821082002280220210120044200370300200242003703d80141c28cc0004116200241d8016a100320052004290300370300200220022903d8013703b80320024200201d420020011b221d20097d2008420020011b2208200754ad7d221e200820077d221a200856201e201d56201e201d511b22041b3703e00120024200201a20041b3703d801200241d8016a2104200241b8036a21010c010b02402007200984500d004198d8c1001058000b200241d8016a41086a22044200370300200242003703d80141c28cc0004116200241d8016a1003200241b8036a41086a22052004290300370300200220022903d8013703b803200241086a200241b8036a109701200241186a290300211d200229031021082002280208210120044200370300200242003703d80141c28cc0004116200241d8016a100320052004290300370300200220022903d8013703b8032002201d420020011b3703e00120022008420020011b3703d801200241d8016a2104200241b8036a21010b2001411020044110100420024190056a24000bf90503087f017e017f23004180026b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2203200128020422052f01064f0d01200241186a2206200520034105746a220741206a290000370300200241106a2208200741186a290000370300200241086a2209200741106a2900003703002002200741086a290000370300200241206a2005200341e0006c6a41e8026a41e00010f6041a2001200341016a36020c200120043602082001200536020420024180016a41186a200629030037030020024180016a41106a200829030037030020024180016a41086a2009290300370300200220022903003703800120024180016a41206a200241206a41e00010f6041a200020024180016a41800110f6041a0c020b200042023703200c010b2001280200210702400240200528020022030d002004ad210a410021030c010b200741016a210720053301044220862004ad84210a0b2005102e200aa7210402400240200a422088a7220620032f01064f0d00200321050c010b034002400240200328020022050d002004ad210a410021050c010b200741016a210720033301044220862004ad84210a0b2003102e200aa7210420052103200a422088a7220620052f01064f0d000b0b200241186a2208200520064105746a220341206a290000370300200241106a2209200341186a290000370300200241086a220b200341106a2900003703002002200341086a290000370300200241206a2005200641e0006c6a41e8026a41e00010f6041a200641027420056a418c0b6a280200210302402007417f6a2205450d00034020032802880b21032005417f6a22050d000b0b2001410036020c20012004360208200120033602042001410036020020024180016a41186a200829030037030020024180016a41106a200929030037030020024180016a41086a200b290300370300200220022903003703800120024180016a41206a200241206a41e00010f6041a200020024180016a41800110f6041a0b20024180026a24000bb00101037f230041306b220124002001200010ef01024020012802004101470d000340024020012802242202450d002001280228450d002002102e0b2001200010ef0120012802004101460d000b0b02402000280204220241e08dc000460d00200228020021032002102e2003450d00200328020021002003102e2000450d00024020002802002202450d0003402000102e2002210020022802002203210220030d000b0b2000102e0b200141306a24000bdd0605057f047e017f017e047f23004190016b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2203200128020422052f01064f0d01200241e0006a41186a200520034105746a220641206a2900002207370300200241e0006a41106a200641186a2900002208370300200241e0006a41086a200641106a29000022093703002002200641086a290000220a370360200241306a41086a20052003410c6c6a220641f0026a280200220b360200200641e8026a290200210c2001200341016a36020c20012004360208200120053602042002200c3703302000200a3702042000410c6a2009370200200041146a20083702002000411c6a2007370200200041246a200c3702002000412c6a200b360200200041013602000c020b200041003602000c010b2001280200210602400240200528020022030d002004ad210c410021030c010b200641016a210620053301044220862004ad84210c0b2005102e200ca7210402400240200c422088a7220b20032f01064f0d00200321050c010b034002400240200328020022050d002004ad210c410021050c010b200641016a210620033301044220862004ad84210c0b2003102e200ca7210420052103200c422088a7220b20052f01064f0d000b0b200241306a41186a220d2005200b4105746a220341206a290000370300200241306a41106a220e200341186a290000370300200241306a41086a220f200341106a2900003703002002200341086a290000370330200241d0006a41086a22102005200b410c6c6a220341f0026a2802003602002002200341e8026a290200370350200b41027420056a41f0036a280200210302402006417f6a2205450d00034020032802ec0321032005417f6a22050d000b0b2001410036020c200120043602082001200336020420014100360200200241e0006a41186a200d290300220c370300200241e0006a41106a200e2903002207370300200241e0006a41086a200f290300220837030020024188016a201028020022033602002000200229033022093702042000410c6a2008370200200041146a20073702002000411c6a200c370200200041246a2002290350220c3702002000412c6a2003360200200220093703602002200c37038001200041013602000b20024190016a24000bb80201067f230041c0006b220224000240411710292203450d00200341002900b0a5433700002003410f6a41002900bfa543370000200341086a41002900b8a54337000020024297808080f002370224200220033602202000200241206a104a200228022421002002280228210420022802202103200241206a41186a22054200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032004200241206a1000200241186a2005290300370300200241106a2006290300370300200241086a20072903003703002002200229032037030020024120360224200220023602202001200241206a10d50302402000450d002003102e0b024020012d00000d002001411c6a280200450d00200141186a280200102e0b200241c0006a24000f0b41174101102c000bcc0202097f027e230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a28020021060240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d0120022008412010f804220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a220541e8026a280200450d00200541f8026a290300210c200541f0026a290300210d0c010b200341086a20012802102002200141146a28020028021c110300200341106a290300210c200128020021042003290308210d0b20012004417f6a3602002000200c3703082000200d370300200341206a24000f0b41e3d7c1004118200341186a41fcd7c1001053000b9f0501097f230041206b22052400024002400240200128020041016a220641004c0d0020012006360200200141086a2802002107200141046a220821060340200628020022092f0106220a410574210b410021064100210c0240024002400340200b2006460d0102402002200920066a41086a412010f804220d0d00410021060c030b200641206a2106200c41016a210c200d417f4a0d000b200c417f6a210a0b20070d014101210641002107200a210c0b200541186a200c360200200541146a2008360200200541086a41086a20093602002005200736020c2005200636020820060d032009200c41e0006c6a2206419c036a280200210720064198036a2208210602400340200628020022092f0106220a410574210b410021064100210c02400240024002400340200b2006460d0102402004200920066a41086a412010f804220d0d00410021060c030b200641206a2106200c41016a210c200d417f4a0d000b200c417f6a210a0b20070d014101210641002107200a210c0b200541186a200c360200200541086a410c6a2008360200200541106a20093602002005200736020c2005200636020820060d0702400240200941e8026a2206200c410c6c6a280200220d0d004100210c0c010b2006200c410c6c6a2802082206417f4c0d02024020060d004101210c0c010b20061029220c450d04200c200d200610f6041a0b200020063602042000200c360200200041086a20063602000c080b2007417f6a21072009200a4102746a41ec036a21060c010b0b1032000b20064101102c000b2007417f6a21072009200a4102746a41880b6a21060c000b0b41e3d7c1004118200541086a41fcd7c1001053000b20002001280210200220032004200141146a28020028020c1105000b20012001280200417f6a360200200541206a24000b930301097f230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a280200210602400240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d0120022008412010f804220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b200341086a22082007200a41e0006c6a220541ad036a290000370300200341106a220a200541b5036a290000370300200341186a220b200541bd036a2900003703002003200541a5036a290000370300200541a4036a2d00004101460d010b200020012802102002200141146a280200280210110300200128020021040c010b200041013a000020002003290300370001200041096a2008290300370000200041116a200a290300370000200041196a200b2903003700000b20012004417f6a360200200341206a24000f0b41e3d7c1004118200341fcd7c1001053000bdd0202097f037e230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a28020021060240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d0120022008412010f804220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a22054180036a290300220ca7450d0020054190036a290300210d20054188036a290300210e0c010b200320012802102002200141146a280200280214110300200341106a290300210d200128020021042003290308210e2003290300210c0b20012004417f6a360200200041106a200d3703002000200e3703082000200c370300200341206a24000f0b41e3d7c1004118200341186a41fcd7c1001053000bc31e03087f037e127f23004180076b22042400200441e0006a41186a200241186a290000370300200441e0006a41106a200241106a290000370300200441e0006a41086a200241086a290000370300200420022900003703600240024002400240024002400240024002402001280200220541e08dc000460d00200128020421060c010b41002106200441e8026a410041e00210f5041a200441c0016a410041840110f5041a41ec0310292205450d01200541003b010620054100360200200541086a200441e8026a41e00210f6041a200541e8026a200441c0016a41840110f6041a20014100360204200120053602000b02400340200541086a2107200541066a210820052f0106220941057421024100210a0240024003402002450d01200441e0006a2007412010f804220b450d02200241606a2102200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200520094102746a41ec036a28020021050c010b0b200441e8026a41086a22022005200a410c6c6a220741f0026a220a2802003602002004200741e8026a22072902003703e80220072003290200370200200a200341086a280200360200200441c0016a41086a20022802002202360200200420042903e802220c3703c0012000410c6a20023602002000200c370204200041013602000c060b200441086a41186a220b200441e0006a41186a2202290300370300200441086a41106a200441e0006a41106a2207290300220c370300200441086a41086a200441e0006a41086a220a290300220d37030020042004290360220e3703082001200128020841016a3602082007200c370300200a200d3703002002200b2903003703002004200e370360200441d8026a41086a2206200341086a280200360200200420032902003703d802024020082f01002203410b490d00200441e8026a410041e00210f5041a200441c0016a410041840110f5041a41ec031029220f450d02200f41003b0106200f4100360200200f41086a200441e8026a41e00210f6042107200f41e8026a200441c0016a41840110f604210a200441e8026a41086a220b200541b8036a280200360200200420052900db013703a8012004200541e0016a2900003700ad01200420052902b0033703e802200420052f00c8013b01bc012004200541ca016a2d00003a00be01200541cb016a2800002110200541cf016a2800002111200541d3016a2800002112200541d7016a28000021132007200541e8016a20052f010641796a220241057410f6042107200a200541bc036a2002410c6c10f604210a200541063b0106200f20023b0106200420042f01bc013b01a401200420042d00be013a00a601200420042903a8013703c001200420042900ad013700c501200441286a41086a200b280200360200200420042903e8023703280240024020094107490d00200941057420076a41c07e6a2007200941796a220b4105746a2207200241ffff0371200b6b41057410f7041a200741186a200441e0006a41186a290300370000200741106a200441e0006a41106a290300370000200741086a200441e0006a41086a290300370000200720042903603700002009410c6c200a6a220241b87f6a200241ac7f6a2202200f41066a22082f0100200b6b410c6c10f7041a200241086a200441d8026a41086a280200360200200220042903d8023702000c010b200541086a20094105746a220241206a200220082f010020096b41057410f7041a200241186a200441e0006a41186a290300370000200241106a200441e0006a41106a290300370000200241086a200441e0006a41086a29030037000020022004290360370000200541e8026a2009410c6c6a2202410c6a200220082f010020096b410c6c10f7041a200241086a200441d8026a41086a280200360200200220042903d8023702000b200820082f010041016a3b010020044198016a41026a220220042d00a6013a0000200441c8026a41086a2214200441286a41086a280200360200200420042f01a4013b019801200420042903c001370350200420042900c501370055200420042903283703c8022004413c6a41026a221520022d00003a0000200420042f0198013b013c2004200429005537002d20042004290350370328200441c0006a41086a22162014280200360200200420042903c80237034020052802002206450d0420052f01042103200441e8026a4102722117034020044194016a41026a221820152d00003a0000200420042f013c3b019401200420042903283703602004200429002d37006520044198016a41086a221920162802003602002004200429034037039801200341ffff0371210502400240024020062f01062202410b490d002017410041960410f5041a419c041029220b450d07200b4100360200200b41046a200441e8026a41980410f6041a200420062f00c8013b01bc012004200641ca016a2d00003a00be012004200641db016a2900003703a8012004200641e0016a2900003700ad01200641cb016a280000211a200641cf016a280000211b200641d3016a280000211c200641d7016a280000211d200441e8026a41086a221e200641b8036a2802003602002004200641b0036a2902003703e802200b41086a200641e8016a20062f0106220741796a220241057410f604211f200b41e8026a200641bc036a2002410c6c10f6042120200b41ec036a20064188046a2007417a6a220941027410f6042108200641063b0106200b20023b010602402009450d00410021022008210703402007280200220a20023b0104200a200b360200200741046a21072009200241016a2202470d000b0b200441d8026a41086a2202201e280200360200200420042d00be0122073a00a601200420042f01bc01220a3b01a401200420042903a8013703c001200420042900ad013700c501200420042903e8023703d802200441c4026a41026a220920073a00002004200a3b01c402200420042903c0013703e802200420042900c5013700ed0220142002280200360200200420042903d8023703c802200341ffff037122074107490d01201f2005417a6a220a4105746a201f200541796a22024105746a2207200b2f010620026b41057410f7041a200741186a20042900653700002007201336000f2007201236000b2007201136000720072010360003200741026a20182d00003a0000200720042f0194013b0000200720042903603700132005410c6c20206a220741b87f6a200741ac7f6a2207200b2f0106220320026b410c6c10f7041a200741086a20192802003602002007200429039801370200200b200341016a22073b01062005410274221020086a416c6a2008200a4102746a2203200741ffff03712205200a6b41027410f7041a2003200f3602002005200a490d02200b20106a41d4036a210703402007280200220a200241016a22023b0104200a200b360200200741046a210720022005490d000c030b0b200641086a2207200541016a220a4105746a200720054105746a2207200220056b41057410f7041a200741186a20042900653700002007201336000f2007201236000b2007201136000720072010360003200741026a20044194016a41026a2d00003a0000200720042f0194013b00002007200429036037001320062005410c6c6a220241f4026a200241e8026a220720062f0106220b20056b410c6c10f7041a200241f0026a20044198016a41086a28020036020020072004290398013702002006200b41016a22023b01062005410274200641ec036a22076a41086a2007200a4102746a2207200241ffff0371220b200a6b41027410f7041a2007200f360200200341ffff0371200b4f0d082006200a417f6a22024102746a41f0036a210703402007280200220a200241016a22023b0104200a2006360200200741046a21072002200b490d000c090b0b200641086a2202200541016a22034105746a200220054105746a220220062f010620056b41057410f7041a200241186a20042900653700002002201336000f2002201236000b2002201136000720022010360003200241026a20182d00003a0000200220042f0194013b000020022004290360370013200641e8026a2005410c6c6a2202410c6a200220062f0106220a20056b410c6c10f7041a200241086a201928020036020020022004290398013702002006200a41016a22023b010620054102742210200641ec036a220a6a41086a200a20034102746a2208200241ffff0371220a20036b41027410f7041a2008200f3602002007200a4f0d00200620106a41f0036a2102034020022802002207200541016a22053b010420072006360200200241046a2102200a2005470d000b0b20044190016a41026a220220092d00003a000020044180016a41086a22072014280200360200200420042f01c402220a3b019001200420042903e802370350200420042900ed02370055200420042903c80237038001201520022d00003a00002004200a3b013c2004200429005537002d200420042903503703282016200728020036020020042004290380013703400240200628020022020d00201a2110201d2113201c2112201b2111200b210f0c060b20062f01042103201a2110201d2113201c2112201b211120022106200b210f0c000b0b200520094105746a220b41286a200b41086a2201200320096b41057410f7041a200b41206a2002290300370000200b41186a2007290300370000200b41106a200a2903003700002001200429036037000020052009410c6c6a220241f4026a200241e8026a220720052f010620096b410c6c10f7041a200241f0026a2006280200360200200720042903d802370200200520052f010641016a3b01060c040b41ec034104102c000b41ec034104102c000b419c044104102c000b200441e8026a410272410041960410f5041a419c0410292202450d0220024100360200200241046a200441e8026a41980410f6041a2002200128020022073602ec03200120023602002001200128020441016a360204200741003b010420072002360200200220022f0106220a4105746a220741086a20042f013c3b00002007410a6a2004413c6a41026a2d00003a0000200741176a2013360000200741136a20123600002007410f6a20113600002007410b6a20103600002007411b6a2004290328370000200741206a200429002d3700002002200a410c6c6a220741f0026a200441c0006a41086a280200360200200741e8026a2004290340370200200241ec036a200a41016a22074102746a200f360200200220073b0106200f20073b0104200f20023602000b200041003602000b20044180076a24000f0b419c044104102c000bd40201057f230041c0006b22022400024002400240411b10292203450d00200341176a41002800a7d945360000200341106a41002900a0d945370000200341086a4100290098d94537000020034100290090d9453700002003411b4136102a2204450d012004200136001b200241206a41186a22034200370300200241206a41106a22014200370300200241206a41086a22054200370300200242003703202004411f200241206a1000200241186a22062003290300370300200241106a2001290300370300200241086a200529030037030020022002290320370300412010292203450d0220032002290300370000200042a0808080800437020420002003360200200341186a2006290300370000200341106a200241106a290300370000200341086a200241086a2903003700002004102e200241c0006a24000f0b411b4101102c000b41364101102c000b41204101102c000bad6d04147f027e0d7f027e230041c0046b22042400200441b0036a20012002200310b603200441b0036a41086a280200210520042802b40321060240024020042802b0034101470d002000200636020420004101360200200041086a20053602000c010b200441c4036a2802002207412c6c2108200441c8036a2802002109200441c0036a280200210a200441bc036a280200210b4100210c4100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004102470d000b200441d8006a200b200d6a41586a10b7032004280258210c200428025c21010b4100210e20014100200c1b210f2007412c6c2108200c41c8ecc500200c1b21104100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004108470d000b200441d0006a200b200d6a41586a10b7032004280250210e200428025421010b4100211120014100200e1b21122007412c6c2108200e41c8ecc500200e1b210c4100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004104470d000b200441c8006a200b200d6a41586a10b70320042802482111200428024c21010b4100210e2001410020111b21132007412c6c2108201141c8ecc50020111b21114100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004103470d000b200441c0006a200b200d6a41586a10b7032004280240210e200428024421010b41002102024020014100200e1b2201450d00200141286c2108200e41c8ecc500200e1b41186a2101410021020340200220012d0000456a2102200141286a2101200841586a22080d000b0b0240024020120d00411e2101200041b7a4c5003602040c010b200c201241146c6a2112410021144100211502400240034041d5a4c500210841382101200c41086a280200417c6a220e41024b0d01200c280200210d024002400240200e0e03000401000b41012115200d41ada4c500460d01200d28000041e3c2b1e306460d010c030b41012114200d41b1a4c500460d00200d41b1a4c500410610f8040d020b0240200c410c6a280200450d0041132101200041d3a5c5003602040c040b0240200c41106a280200220120026b220d20014d0d00412a2101200041e6a5c5003602040c040b41ada5c5002108412621012013200d4d0d012011200d4102746a220d450d01418da5c500210841202101200f200d280200220d4d0d012010200d4104746a220d450d014190a6c5002108411f2101200d2802080d01200d2d000d220d41077141044b0d010240200d0e050002020200000b200c41146a220c2012470d000b20142015714101710d01411c411e201441017122021b2101200041afa6c50041b7a4c50020021b3602040c020b200020083602040c010b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004106470d000b200441386a200b200d6a41586a10b703200428023c450d00200041fba1c500360204411f21010c010b2007412c6c21082003280268210c410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004105470d000b200441306a200b200d6a41586a220110b7030240200428023441014d0d00411821012000419aa2c5003602040c020b200441286a200110b703200428022c450d0020042802282201450d002001280200200c4d0d0041222101200041b2a2c5003602040c010b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004107470d000b200441206a200b200d6a41586a10b7032004280220220120042802244104746a2108034020012008460d012001450d012001410c6a2102200141106a210120022d0000410271450d000b41322101200041bea3c5003602040c010b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d0000410b470d000b200b200d6a220141606a2802002202450d00200141586a280200220d200241186c6a210c0340200d220241186a210d2002280208410374210120022802002102024003402001450d01200141786a210120022d00042108200241086a21022008410271450d000b413121012000418da3c5003602040c030b200d200c470d000b0b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004102470d000b200441186a200b200d6a41586a10b703200428021c2201450d002004280218220220014104746a211103402002450d01200241106a210e200420022d000d22083a00b0032002280200220120022802086a210c410021024100200441b0036a20084104461b210d024003400240024002400240200241ff01710e03000102000b2001200c460d014100210220012108200141016a21010c020b2001200c460d034101210220012108200141016a21010c010b200d450d0241022102200d21084100210d0b20082d0000410271450d000b41392101200041d4a2c5003602040c030b200e2102200e2011470d000b0b2007412c6c21084100210c4100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004102470d000b200441106a200b200d6a41586a10b7032004280210210c200428021421010b4100210e20014100200c1b21102007412c6c2108200c41c8ecc500200c1b21124100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004103470d000b200441086a200b200d6a41586a10b7032004280208210e200428020c21010b200e41c8ecc500200e1b220220014100200e1b41286c6a210d4100211302400240024003400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402002200d460d00412d210141ca9bc300210820022802084103470d1402402002280200220c418ac5c500460d00200c418ac5c500410310f8040d150b200241286a21114115210c41c39ac300210e4114210141b69bc300210802400240024020022d00180e040017011e000b4136210c418d9ac300210e2010200228021c22014d0d1d201220014104746a220f450d1d2002280214210c200228020c210220092d00700d01200c410b470d014138210141fe9ac3002108200241de9ec500460d16200241de9ec500410b10f804450d160c190b412f210141969cc300210820022802144106470d150240200228020c220c41879ac300460d00200c41879ac300410610f8040d160b02402013450d00411f2101200041f79bc3003602040c1e0b2002411c6a2113201121020c190b4126210141d89ac3002108200c417d6a220c41134b0d140240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200c0e14003030300e043006330b0a110113101a30300c18000b2002418dc5c500460d2f2002418dc5c500410310f804450d2f418dc5c5002002410310f8040d2f41011029220e450d1c200e41003a00000240200f2d000c41e000470d00200f2802084101470d00200f280200211441002102034020024101460d03200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c370b200241bc9cc500460d0141bc9cc5002002410f10f804450d010240200241cb9cc500460d0041cb9cc5002002410f10f8040d2f0b410110292214450d1d201441003a0000200f2d000c41e000470d30200f2802084101470d30200f280200211541002102034020024101460d04201420026a210c201520026a210e200241016a2102200e2d0000200c2d0000460d000c310b0b200f2d000d2101200e102e2011210220014104460d310c330b41041029220e450d1a200e41003600000240200f2d000c41e000470d00200f2802084104470d00200f280200211441002102034020024104460d28200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c340b0240200241da9cc500460d00200229000042e5f0d1fbb5ac98b6ec00520d2c0b410710292214450d1b20144100360003201441013a0002201441003b0000200f2d000c41e000470d2c200f2802084107470d2c200f280200211541002102034020024107460d03201420026a210c201520026a210e200241016a2102200e2d0000200c2d0000460d000c2d0b0b200f2d000d220c4104460d2c2014102e20112102200c41fb0171450d2e0c2a0b200241e29cc500460d0141e29cc5002002410a10f804450d01200241ec9cc500460d0241ec9cc5002002410a10f804450d020240200241f69cc500460d0041f69cc5002002410a10f8040d070b4126210c41d89ac300210e200f2d000c41e000470d30200f2802080d3020112102200f2d000d4104460d2d0c300b200f2d000d220c4104460d292014102e20112102200c41fb0171450d2c0c280b410710292214450d1820144100360003201441013a0002201441003b00000240200f2d000c41e000470d00200f2802084107470d00200f2802002115410021020340024020024107470d00200f2d000d220c4104460d022014102e20112102200c41fb0171450d2e0c2a0b201420026a210c201520026a210e200241016a2102200e2d0000200c2d0000460d000b0b2014102e200041d89ac3003602040c2f0b41021029220e450d18200e41003b00000240200f2d000c41e000470d00200f2802084102470d00200f280200211441002102034020024102460d23200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c2e0b02402002418b9dc500460d00418b9dc5002002410d10f8040d260b4126210c41d89ac300210e200f2d000c41e000470d2c200f2802080d2c20112102200f2d000d4104460d290c2c0b0240200241989dc500460d0041989dc5002002410c10f8040d250b4126210c41d89ac300210e200f2d000c41e000470d2b200f2802080d2b20112102200f2d000d4104460d280c2b0b0240200241af9dc500460d0041af9dc5002002411510f8040d240b4126210c41d89ac300210e200f2d000c41e000470d2a200f2802080d2a20112102200f2d000d4104460d270c2a0b0240200241c49dc500460d0041c49dc5002002410a10f8040d230b41021029220e450d15200e41003b00000240200f2d000c41e000470d00200f2802084102470d00200f280200211441002102034020024102460d03200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c2a0b0240200241ce9dc500460d0041ce9dc5002002410710f8040d220b4126210c41d89ac300210e200f2d000c41e000470d28200f2802080d2820112102200f2d000d4104460d250c280b200f2d000d2101200e102e2011210220014104460d240c260b200241d59dc500460d0141d59dc5002002411110f804450d01200241949ec500460d0641949ec5002002411110f804450d060240200241a59ec500460d0041a59ec5002002411110f8040d200b41041029220e450d17200e41003600000240200f2d000c41e000470d00200f2802084104470d00200f280200211441002102034020024104460d0a200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c270b0240200241e69dc500460d0041e69dc5002002410e10f8040d1f0b41081029220e450d13200e42003700000240200f2d000c41e000470d00200f2802084108470d00200f280200211441002102034020024108460d04200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c260b41021029220e450d11200e41003b00000240200f2d000c41e000470d00200f2802084102470d00200f280200211441002102034020024102460d1b200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c250b200241f49dc500460d0141f49dc5002002411010f804450d01200241849ec500460d0241849ec5002002411010f804450d020240200241e99ec500460d0041e99ec5002002411010f8040d1d0b4126210c41d89ac300210e200f2d000c41e000470d23200f2802080d2320112102200f2d000d4104460d200c230b200f2d000d2101200e102e2011210220014104460d1f0c210b4126210c41d89ac300210e200f2d000c41e000470d21200f2802080d21200f2d000d22014104460d2120112102200141fb0171450d1e0c1f0b41031029220e450d0f200e41003a0002200e41003b00000240200f2d000c41e000470d00200f2802084103470d00200f280200211441002102034020024103460d18200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c210b41021029220e450d0f200e41003b00000240200f2d000c41e000470d00200f2802084102470d00200f280200211441002102034020024102460d18200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c200b0240200241b69ec500460d0041b69ec5002002411610f8040d180b410210292214450d10201441003b00000240200f2d000c41e000470d00200f2802084102470d00200f280200211541002102034020024102460d04201420026a210c201520026a210e200241016a2102200e2d0000200c2d0000460d000b0b2014102e0c170b200f2d000d2101200e102e2011210220014104460d1a0c1c0b0240200241cc9ec500460d0041cc9ec5002002411210f8040d160b4126210c41d89ac300210e200f2d000c41e000470d1c200f2802080d1c20112102200f2d000d4104460d190c1c0b200f2d000d21012014102e2011210220014104460d180c1a0b024020130d0041002116410021170c130b024020132802040d00200041c59cc300360204413221010c1c0b024020132802002216201341086a28020022174d0d00200041f79cc30036020441c90021010c1c0b201720032802644d0d12200041c09dc30036020441c10021010c1b0b41014101102c000b41044101102c000b41014101102c000b41074101102c000b41074101102c000b41024101102c000b41024101102c000b41024101102c000b41084101102c000b41034101102c000b41024101102c000b41044101102c000b41024101102c000b200f2d000d2101200e102e2011210220014104460d090c0b0b200f2d000d2101200e102e2011210220014104460d080c0a0b200f2d000d2101200e102e2011210220014104460d070c090b200f2d000d2101200e102e2011210220014104460d060c080b200f2d000d2101200e102e2011210220014104460d050c070b20092903082118200441b8036a22024200370300200441e08dc0003602b4032009290310211920042018a7417f2018428080808010541b3602c00320042019a7417f2019428080808010541b3602b003200441b0036a4104722201410d10b8032001410c10b8032001410710b8032001410f10b803200441b0036a410c6a220128020021132002280200211120042802c003211a20042802b403210c20042802b003211b200441c0036a220820073602002001200a3602002004200b3602b803200420053602b403200420063602b003200441e0006a200441b0036a10b903024002400240410110292201450d00200141003a0000200420042f01b003220d3b01a002200841e0083b01002002428180808010370300200420013602b403200441013602b0032004200d3b01c203200441e0006a200441b0036a10ba03210b0240410310292202450d00200241026a41002d008cc5453a0000200241002f008ac5453b00000240410310292208450d00200841026a41002d008fc5453a0000200841002f008dc5453b000002400240024002400240024002400240200441f4006a280200220d200441e0006a41106a2802002201470d00200141016a220d2001490d0120014101742207200d200d2007491b220dad42287e2218422088a70d012018a722074100480d010240024020010d002007102921010c010b200428026c200141286c2007102a21010b2001450d072004200d3602702004200136026c2004280274210d0b200428026c200d41286c6a220141003a00182001200836020c2001428380808030370204200120023602002001411c6a200b360200200141106a4283808080303702002004200428027441016a360274200441b0036a200441e0006a418c0110f6041a200441f0016a200441b0036a10bb03200441f0016a41106a2802002210412c6c210120042802f801220741586a210202400340410021082001450d01200141546a2101200241286a210d2002412c6a220b2102200d2d00004103470d000b200b41086a2802002201450d00200141286c2102200b28020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b2010412c6c2101200741586a21022008417f6a210d02400340410021082001450d01200141546a2101200241286a210b2002412c6a220e2102200b2d00004103470d000b200e41086a2802002201450d00200141286c2102200e28020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b2010412c6c2101200741606a2102024003404100210e024020010d00410021010c020b200141546a2101200241206a210b2002412c6a220f2102200b2d00004104470d000b200f28020021010b02400240024002402010450d00200120086a211c20072010412c6c6a211d4100211e4100210f0340024020072d000041786a220141034b0d00024002400240024020010e0403010200030b200728020c2201450d032007280204220b200141186c6a211f0340200f21200240200b22212802144104742202450d00202128020c21010340024020012d0000410b470d00200141046a2208280200220b200d490d002008200b41016a3602000b200141106a2101200241706a22020d000b0b02400240024002400240024002400240024002400240410810292201450d002001428080808010370200410410292222450d012021410c6a21082022410036020020212802142223450d0241002102410121062023210b41012110410121124101210f024003402002200b4f0d01200241016a210a02400240024002400240024002400240200828020020024104746a2d0000220b417e6a220241044b0d0020020e050101010302010b200b10bc032124200c210b201121250340200b410c6a210e200b41086a2126200b2f010621054100210202400240034020052002460d01202620026a2114200e41086a210e200241016a210202404100417f410120142d00002214202441ff017122154b1b20142015461b41016a0e03000301000b0b2002417f6a21050b024020250d00201b210b0c070b2025417f6a2125200b20054102746a41ec006a280200210b0c010b0b201b210b200e2802000e0404100304040b200b10bc032124200c210b2011212502400340200b410c6a210e200b41086a2126200b2f010621054100210202400240034020052002460d01202620026a2114200e41086a210e200241016a210202404100417f410120142d00002214202441ff017122154b1b20142015461b41016a0e03000301000b0b2002417f6a21050b024020250d00201b210b0c030b2025417f6a2125200b20054102746a41ec006a280200210b0c010b0b201b210b0240200e2802000e0401110001010b200e41046a280200210b0b200f417f6a2202200f4f0d0f2002200f4b0d0f2010202220024102746a28020022024d0d0f200120024103746a220e2802042202200b6a220b2002490d0f200e200b3602040240024020062010460d00200621050c010b200641016a22022006490d1e2006410174220b20022002200b491b220541ffffffff01712005470d1e200541037422024100480d1e0240024020060d002002102921010c010b200120064103742002102a21010b2001450d0c0b200120104103746a220241013602042002200a360200024002402012200f460d00201221140c010b201241016a22022012490d1e2012410174220b20022002200b491b221441ffffffff03712014470d1e201441027422024100480d1e0240024020120d002002102921220c010b202220124102742002102a21220b2022450d0d0b201041016a21022022200f4102746a2010360200200f41016a210f0c050b200f450d0e200f417f6a210f0c030b200f450d0d0240024020062010460d00200621050c010b200641016a22022006490d1c2006410174220b20022002200b491b220541ffffffff01712005470d1c200541037422024100480d1c0240024020060d002002102921010c010b200120064103742002102a21010b2001450d0c0b200120104103746a220241013602042002200a360200024002402012200f417f6a220b460d00201221140c010b20124101742202200f200f2002491b221441ffffffff03712014470d1c201441027422024100480d1c0240024020120d002002102921220c010b202220124102742002102a21220b2022450d0d0b201041016a21022022200b4102746a20103602000c030b200e41046a280200210b0b200f417f6a2202200f4f0d0b2002200f4b0d0b2010202220024102746a28020022024d0d0b200120024103746a220e2802042202200b6a220b2002490d0b200e200b3602040b2006210520102102201221140b200a2023460d0a2021280214210b200521062002211020142112200a21020c000b0b4190c5c5002002200b1038000b41084104102c000b41044104102c000b200141086a210e41012114410121050c060b20024104102c000b20024104102c000b20024104102c000b20024104102c000b02402006450d002001102e0b4101211e024020120d002020210f0c080b2022102e2020210f0c070b2002450d01200120024103746a210e0b2001210f410121020340200129020021182004412d3a00b003200420184220883e02b403200820022018a76a220b417f6a200441b0036a10bd032004410b3a00b0032004200d3602b4032008200b200441b0036a10bd03200241026a2102200e200141086a2201470d000b200f21010b02402005450d002001102e0b02402014450d002022102e0b202141186a210b02400240201a450d0020212802142202450d00202128020c210120024104742102410021080340024020012d0000412c470d002001410b3a0000200141046a201c360200200841016a21080b200141106a2101200241706a22020d000b4101210f20080d010b2020210f0b200b201f470d000c040b0b20072802042201200d490d022007200141016a3602040c020b200728020c2201450d012007280204220b2001411c6c6a210e0340200b2201411c6a210b024020012802182202450d0020012802102101200241027421020340024020012802002208200d490d002001200841016a3602000b200141046a21012002417c6a22020d000b0b200b200e460d020c000b0b200728020c2201450d00200141146c2102200728020441106a2101034002402001417c6a2802000d0020012802002208200d490d002001200841016a3602000b200141146a21012002416c6a22020d000b0b2007412c6a2207201d470d000b201e4101710d02200f4101710d01200428028002210e20042802f80121070b200441fc016a280200210620042802f401210f20042802f0012110410021050c020b200441b0036a41106a200441f0016a41106a280200360200200441b0036a41086a200441f0016a41086a290300370300200420042903f0013703b003200441a0026a200441b0036a10b903411010292202450d07200241063a0000410110292201450d06200141003a000041011029220b450d05200b20012d00003a00002001102e411010292208450d04200841063a000041f00010292201450d03200141063a00602001412c3b01502001200d3602442001410b3a0040200141d8003a00302001201a3602242001412d3a0020200141003602142001410f3a0010200141003602042001410f3a0000024020082d00004109470d00200828020841ffffffff0371450d002008280204102e0b2008102e024020022d00004109470d00200228020841ffffffff0371450d002002280204102e0b2002102e200441d4036a4287808080f000370200200441d0036a2001360200200441cc036a4100360200200441b0036a410c6a4281808080800c370200200441b8036a4101360200200441003602dc03200442043702c4032004200b3602b403200441013602b003200441a0026a200441b0036a10be03200441b0036a200441a0026a418c0110f6041a20044188026a200441b0036a10bb0320044188026a410c6a280200210620044198026a280200210e2004280288022110200428028c02210f2004280290022107410021050c010b200441fc016a280200210620042802f80121070240200428028002220e450d00200e412c6c2102200721010340200110bf032001412c6a2101200241546a22020d000b0b41012105411a210f41f0a3c500211002402006450d002007102e0b0b02402011450d000340200c28026c210c2011417f6a22110d000b0b4100210841002101024003402013450d01024002402001200c2f01064f0d00200c20014103746a41146a2902002118200141016a21010c010b02400240200c28020022010d002008ad21184100210d410021010c010b200c3301044220862008ad8421184101210d0b200c102e2018a72108024002402018422088a7220b20012f01064f0d00200121020c010b034002400240200128020022020d002008ad2118410021020c010b200d41016a210d20013301044220862008ad8421180b2001102e2018a72108200221012018422088a7220b20022f01064f0d000b0b200b41027420026a41f0006a280200210c2002200b4103746a41146a29020021180240200d417f6a2201450d000340200c28026c210c2001417f6a22010d000b0b410021010b2013417f6a21132018a74103470d000b0b0240200c41e08dc000460d00200c2802002101200c102e2001450d00200128020021022001102e2002450d00024020022802002201450d0003402002102e2001210220012802002208210120080d000b0b2002102e0b02402005450d002000201036020420004101360200200041086a200f3602000c160b200441a0026a41106a200e360200200441a0026a410c6a2006360200200420073602a8022004200f3602a402200420103602a002200441b0036a200441a0026a200928026010c003024020042802b0034101470d000240200441b0036a41086a280200450d0020042802b403102e0b2000418aa4c50036020420004101360200200041086a41233602000c160b200441c4036a2802002102200441b0036a41106a2802002105200441b0036a410c6a2802002110200441b8036a280200210d20042802b4032108200328025821062004410036029002200442013703880202400240410410292201450d002004410436028c022004200428029002220b41046a3602900220042001360288022001200b6a200836000002400240200428028c02220820042802900222016b4104490d0020042802880221080c010b200141046a220b2001490d0320084101742201200b200b2001491b22014100480d030240024020080d002001102921080c010b20042802880220082001102a21080b2008450d022004200136028c02200420083602880220042802900221010b2004200141046a36029002200820016a200d36000020102002412c6c22016a210d024020020d00201021010c0e0b200141546a2103200441b0036a4101722102200441b0036a41276a210b200441b0036a41206a210c200441b0036a41186a2107200441b0036a41106a210e200441b0036a41086a211120102101034020012d00002108200b200141286a280000360000200c200141216a2900003703002007200141196a290000370300200e200141116a2900003703002011200141096a2900003703002004200141016a2900003703b00302402008410f470d002001412c6a21010c0f0b200441a0026a41276a2213200b280000360000200441a0026a41206a220f200c290300370300200441a0026a41186a20072903002218370300200441a0026a41106a200e2903002219370300200441a0026a41086a20112903002227370300200420042903b00322283703a00220022028370000200241086a2027370000200241106a2019370000200241186a2018370000200241206a200f290300370000200241276a2013280000360000200420083a00b003200441e0006a200441b0036a20044188026a10c10320042d00602208411a470d0d200341546a21032001412c6a2201200d470d000b200d21010c0d0b41044101102c000b20014101102c000b102d000b41f0004108102c000b41104108102c000b41014101102c000b41014101102c000b41104108102c000b20074104102c000b41034101102c000b41034101102c000b41014101102c000b200428026421122004280268210602402003450d002001412c6a2101200441b0036a4101722102200441b0036a41276a210c200441b0036a41206a2107200441b0036a41186a210e200441b0036a41106a2111200441b0036a41086a2103034020012d0000210b200c200141286a2800003600002007200141216a290000370300200e200141196a2900003703002011200141116a2900003703002003200141096a2900003703002004200141016a2900003703b003200b410f460d01200441a0026a41276a2213200c280000360000200441a0026a41206a220f2007290300370300200441a0026a41186a200e2903002218370300200441a0026a41106a20112903002219370300200441a0026a41086a20032903002227370300200420042903b00322283703a00220022028370000200241086a2027370000200241106a2019370000200241186a2018370000200241206a200f290300370000200241276a20132800003600002004200b3a00b003200441b0036a10bf032001412c6a2201200d470d000b0b02402005450d002010102e0b0240200428028c02450d00200428028802102e0b024020084105470d002006450d002012102e0b200041cba6c50036020420004101360200200041086a41253602000c0a0b02402001200d460d00200441b0036a4101722102200441b0036a41276a210b200441b0036a41206a210c200441b0036a41186a2107200441b0036a41106a210e200441b0036a41086a2111034020012d00002108200b200141286a280000360000200c200141216a2900003703002007200141196a290000370300200e200141116a2900003703002011200141096a2900003703002004200141016a2900003703b0032008410f460d01200441a0026a41276a2203200b280000360000200441a0026a41206a2213200c290300370300200441a0026a41186a20072903002218370300200441a0026a41106a200e2903002219370300200441a0026a41086a20112903002227370300200420042903b00322283703a00220022028370000200241086a2027370000200241106a2019370000200241186a2018370000200241206a2013290300370000200241276a2003280000360000200420083a00b003200441b0036a10bf032001412c6a2201200d470d000b0b02402005450d002010102e0b2004280288022101200429028c0221182000411c6a41003a0000200041146a2018370200200041106a20013602002000410c6a2017360200200041086a2016360200200020063602042000411d6a20042f00f0013b0000200041003602002000411f6a200441f2016a2d00003a00000c090b200020083602040c070b2014102e200041d89ac3003602040c060b2014102e200041d89ac3003602040c050b02400240200241809dc500460d0041809dc5002002410b10f8040d010b4126210c41d89ac300210e200f2d000c41e000470d04200f2802080d0420112102200f2d000d4104460d010c040b02400240200241a49dc500460d0041a49dc5002002410b10f8040d010b4126210c41d89ac300210e200f2d000c41e000470d04200f2802080d0420112102200f2d000d4104460d010c040b0240200241de9ec500460d0041de9ec5002002410b10f8040d020b0240024041021029220c450d00200c41003b00000240200f2d000c41e000470d00200f2802084102470d00200f280200210e41002101034020014102460d03200c20016a2102200e20016a2108200141016a210120082d000020022d0000460d000b0b200c102e0c030b41024101102c000b200f2d000d2101200c102e2011210220014104460d000c020b0b41262101200041d89ac3003602040c020b4126210c41d89ac300210e0b200c21012000200e3602040b20004101360200200041086a200136020002402007450d00200b2007412c6c6a2107200b210c0340200c220d412c6a210c02400240200d2d00002201410d4b0d00024002400240024002400240024002400240024002400240024020010e0e0001020304050607080e090a0b0c000b200d41086a280200450d0d200d41046a280200102e0c0d0b0240200d41086a280200450d00200d41046a280200102e0b200d41146a280200450d0c200d41106a280200102e0c0c0b0240200d410c6a2802002202450d00200d41046a28020021012002410474210203400240200141046a280200450d002001280200102e0b200141106a2101200241706a22020d000b0b200d41086a280200450d0b200d280204102e0c0b0b0240200d410c6a2802002202450d00200d41046a2802002101200241286c210203400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200241586a22020d000b0b200d41086a280200450d0a200d280204102e0c0a0b200d41086a280200450d09200d41046a280200102e0c090b200d41086a280200450d08200d41046a280200102e0c080b200d41086a280200450d07200d41046a280200102e0c070b0240200d410c6a2802002201450d00200d41046a280200220820014104746a21000340024020082802082202450d0020082802002101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b200841106a21010240200841046a280200450d002008280200102e0b2001210820012000470d000b0b200d41086a280200450d06200d280204102e0c060b0240200d410c6a2802002202450d00200d41046a2802002101200241146c210203400240200141046a280200450d002001280200102e0b200141146a21012002416c6a22020d000b0b200d41086a280200450d05200d280204102e0c050b0240200d410c6a2802002201450d00200d41046a28020022082001411c6c6a2100034002402008410c6a2802002202450d0020082802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b0240200841086a280200450d002008280204102e0b2008411c6a21010240200841146a280200450d002008280210102e0b2001210820012000470d000b0b200d41086a280200450d04200d280204102e0c040b0240200d410c6a2802002201450d00200d41046a2802002208200141186c6a210003400240200841046a280200450d002008280200102e0b0240200841146a2802002202450d00200828020c2101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b200841186a21010240200841106a280200450d00200828020c102e0b2001210820012000470d000b0b200d41086a280200450d03200d280204102e0c030b0240200d410c6a2802002201450d00200d41046a28020022082001411c6c6a2100034002402008410c6a2802002202450d0020082802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b0240200841086a280200450d002008280204102e0b2008411c6a21010240200841146a280200450d002008280210102e0b2001210820012000470d000b0b200d41086a280200450d02200d280204102e0c020b0240200d41046a2d0000220141024b0d0002400240024020010e03000102000b200d410c6a280200450d04200d41086a280200102e0c040b0240200d41146a2802002202450d00200d410c6a28020021012002410c6c21020340024020012802002208450d00200141046a280200450d002008102e0b2001410c6a2101200241746a22020d000b0b200d41106a280200450d03200d28020c102e0c030b0240200d41146a2802002201450d00200d410c6a280200220e20014104746a21110340200e220041106a210e024020002802042201450d0002402000410c6a2802002202450d002002410c6c21020340024020012802002208450d00200141046a280200450d002008102e0b2001410c6a2101200241746a22020d000b0b200041086a280200450d002000280204102e0b200e2011470d000b0b200d41106a280200450d02200d28020c102e0c020b200d410c6a280200450d01200d41086a280200102e0c010b0240200d41086a280200450d00200d41046a280200102e0b0240200d41146a2802002201450d00200d41186a280200450d002001102e0b200d41246a280200450d00200d41206a280200102e0b200c2007470d000b0b200a450d00200b102e0b200441c0046a24000b9e0301067f230041106b220224002002410036020820024201370300200020021066200041046a20021066200041086a2002106620002d0018210302400240024002400240200228020420022802082204460d00200228020021050c010b200441016a22052004490d0320044101742206200520052006491b22064100480d030240024020040d002006102921050c010b200228020020042006102a21050b2005450d0120022006360204200220053602000b2002200441016a360208200520046a20033a0000200028020c2106200041146a2802002204200210470240024020022802042203200228020822056b2004490d00200228020021000c010b200520046a22002005490d0320034101742207200020002007491b22074100480d030240024020030d002007102921000c010b200228020020032007102a21000b2000450d022002200736020420022000360200200721030b200020056a2006200410f6041a200128020020012802042000200520046a100402402003450d002000102e0b200241106a24000f0b20064101102c000b20074101102c000b102d000b9c2104057f027e027f027e230041c0036b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541104b0d1220050e110102030405060708090a0b0c0d0e0f1011010b200041123a00000c170b200241b0016a200110b8010240024020022d00b0014113460d00200241b8026a200241b0016a41880110f6041a418801102922040d014188014108102c000b200041123a00000c170b2004200241b8026a41880110f6042104200241086a2001106502402002290308a7450d00200041123a00002004102f2004102e0c170b200241086a41106a290300210720022903102108200041013a0000200020022f0090013b0001200041086a2008370300200041046a2004360200200041186a2002290358370300200041106a2007370300200041036a20024192016a2d00003a0000200041206a200241d8006a41086a290300370300200041286a200241d8006a41106a2903003703000c160b200241206a2001103102402002280220450d00200041123a00000c160b20022802242101200041023a0000200020022f00b0013b0001200041046a2001360200200041086a20022903b802370300200041036a200241b0016a41026a2d00003a0000200041106a200241b8026a41086a290300370300200041186a200241b8026a41106a290300370300200041206a200241b8026a41186a290300370300200041286a200241b8026a41206a2903003703000c150b200241286a2001103120022802280d1320012802042204450d13200228022c2106200128020022032d0000210520012004417f6a3602042001200341016a360200200541ff0071220141064b0d13200041033a0000200041046a2006360200200041026a20013a0000200020054107763a0001200041086a20022903b802370300200041106a200241b8026a41086a290300370300200041186a200241b8026a41106a290300370300200041206a200241b8026a41186a290300370300200041286a200241b8026a41206a2903003703000c140b200241306a2001103120022802300d1120012802042204450d1120022802342106200128020022032d0000210520012004417f6a3602042001200341016a360200200541ff0071220141064b0d11200041043a0000200041046a2006360200200041026a20013a0000200020054107763a0001200041086a20022903b802370300200041106a200241b8026a41086a290300370300200041186a200241b8026a41106a290300370300200041206a200241b8026a41186a290300370300200041286a200241b8026a41206a2903003703000c130b0240200641034b0d00200041123a00000c130b2004280001210520012003417b6a3602042001200441056a360200200041053a0000200020022f00b0013b0001200041046a2005360200200041086a20022903b802370300200041036a200241b2016a2d00003a0000200041106a200241b8026a41086a290300370300200041186a200241b8026a41106a290300370300200041206a200241b8026a41186a290300370300200041286a200241b8026a41206a2903003703000c120b200241b0016a200110b8010240024020022d00b0014113460d00200241b8026a200241b0016a41880110f6041a418801102922010d014188014108102c000b200041123a00000c120b2001200241b8026a41880110f6042101200041063a0000200020022f0090013b0001200041036a20024192016a2d00003a0000200041046a2001360200200041086a2002290358370300200041106a200241d8006a41086a290300370300200041186a200241d8006a41106a290300370300200041206a200241d8006a41186a290300370300200041286a200241d8006a41206a2903003703000c110b200241b0016a200110b8010240024020022d00b0014113460d00200241b8026a200241b0016a41880110f6041a418801102922010d014188014108102c000b200041123a00000c110b2001200241b8026a41880110f6042101200041073a0000200020022f0090013b0001200041036a20024192016a2d00003a0000200041046a2001360200200041086a2002290358370300200041106a200241d8006a41086a290300370300200041186a200241d8006a41106a290300370300200041206a200241d8006a41186a290300370300200041286a200241d8006a41206a2903003703000c100b200241b0016a200110b8010240024020022d00b0014113460d00200241b8026a200241b0016a41880110f6041a418801102922010d014188014108102c000b200041123a00000c100b2001200241b8026a41880110f6042101200041083a0000200020022f0090013b0001200041036a20024192016a2d00003a0000200041046a2001360200200041086a2002290358370300200041106a200241d8006a41086a290300370300200041186a200241d8006a41106a290300370300200041206a200241d8006a41186a290300370300200041286a200241d8006a41206a2903003703000c0f0b41002105200241003a00d8022003417f6a2109417e21060340024020092005470d00200541ff0171450d0d200241003a00d8020c0d0b200241b8026a20056a200420056a220a41016a2d00003a00002001200320066a3602042001200a41026a3602002002200541016a220a3a00d8022006417f6a2106200a2105200a4120470d000b200241d8006a41086a200241b8026a41086a290300370300200241d8006a41106a200241b8026a41106a290300370300200241d8006a41186a200241b8026a41186a290300370300200220022903b802370358200a417f7320036a4104490d0b2004200a6a220441016a280000210620012003200a6b2203417b6a22053602042001200441056a220a36020020054104490d0b20024190016a41086a200241d8006a41086a290300220737030020024190016a41106a200241d8006a41106a290300220837030020024190016a41186a200241d8006a41186a290300220b370300200a28000021052001200341776a3602042001200441096a36020020022002290358220c37039001200041093a00002000200c370001200041096a2007370000200041116a2008370000200041196a200b370000200041286a2005360200200041246a2006360200200041216a20022f0082013b0000200041236a20024184016a2d00003a00000c0e0b41002105200241003a00d8022003417f6a210a2003417e6a210303400240200a2005470d000240200541ff0171450d00200241003a00d8020b200041123a00000c0f0b200241b8026a20056a200420056a220641016a2d00003a0000200120033602042001200641026a3602002002200541016a22063a00d8022003417f6a21032006210520064120470d000b200241d8006a41086a200241b8026a41086a2903002207370300200241d8006a41106a200241b8026a41106a2903002208370300200241d8006a41186a200241b8026a41186a290300220b370300200220022903b802220c3703582000410a3a00002000200c370001200041096a2007370000200041116a2008370000200041196a200b370000200041216a200229009001370000200041286a20024197016a2900003700000c0d0b200241386a2001103102402002280238450d00200041123a00000c0d0b200228023c21012000410b3a0000200020022f00b0013b0001200041046a2001360200200041086a20022903b802370300200041036a200241b2016a2d00003a0000200041106a200241b8026a41086a290300370300200041186a200241b8026a41106a290300370300200041206a200241b8026a41186a290300370300200041286a200241b8026a41206a2903003703000c0c0b200241d0006a2001103120022802500d0720022802542104200241c8006a2001103120022802480d07200228024c2105200241c0006a2001103120022802400d07200228024421012000410c3a0000200020022f00b0013b00012000410c6a2001360200200041086a2005360200200041046a2004360200200041106a20022903b802370300200041036a200241b2016a2d00003a0000200041186a200241b8026a41086a290300370300200041206a200241b8026a41106a290300370300200041286a200241b8026a41186a2903003703000c0b0b41002105200241003a00d8022003417f6a210a2003417e6a210303400240200a2005470d000240200541ff0171450d00200241003a00d8020b200041123a00000c0c0b200241b8026a20056a200420056a220641016a2d00003a0000200120033602042001200641026a3602002002200541016a22063a00d8022003417f6a21032006210520064120470d000b200241d8006a41086a200241b8026a41086a2903002207370300200241d8006a41106a200241b8026a41106a2903002208370300200241d8006a41186a200241b8026a41186a290300220b370300200220022903b802220c3703582000410d3a00002000200c370001200041096a2007370000200041116a2008370000200041196a200b370000200041216a200229009001370000200041286a20024197016a2900003700000c0a0b2000410e3a00000c090b41002105200241003a00d8022003417f6a210a2003417e6a210303400240200a2005470d000240200541ff0171450d00200241003a00d8020b200041123a00000c0a0b200241b8026a20056a200420056a220641016a2d00003a0000200120033602042001200641026a3602002002200541016a22063a00d8022003417f6a21032006210520064120470d000b200241d8006a41086a200241b8026a41086a2903002207370300200241d8006a41106a200241b8026a41106a2903002208370300200241d8006a41186a200241b8026a41186a290300220b370300200220022903b802220c3703582000410f3a00002000200c370001200041096a2007370000200041116a2008370000200041196a200b370000200041216a200229009001370000200041286a20024197016a2900003700000c080b41002105200241003a00d8022003417f6a21092003417e6a21060340024020092005470d00200541ff0171450d04200241003a00d8020c040b200241b8026a20056a200420056a220a41016a2d00003a0000200120063602042001200a41026a3602002002200541016a220a3a00d8022006417f6a2106200a2105200a4120470d000b200241d8006a41086a200241b8026a41086a290300370300200241d8006a41106a200241b8026a41106a290300370300200241d8006a41186a200241b8026a41186a290300370300200220022903b8023703582003417f6a200a460d022004200a6a220541016a2d00002104200120063602042001200541026a360200200441064b0d0220024190016a41186a200241d8006a41186a290300220737030020024190016a41106a200241d8006a41106a290300220837030020024190016a41086a200241d8006a41086a290300220b37030020022002290358220c37039001200041103a00002000200c370001200041096a200b370000200041116a2008370000200041196a2007370000200041216a20043a0000200041226a200229018201370100200041286a20024182016a41066a2901003701000c070b200041113a00000c060b200041123a00000c050b200041123a00000c040b200041123a00000c030b200041123a00000c020b200041123a00000c010b200041123a00000b200241c0036a24000b800902067f047e230041d0026b220224000240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541034b0d0820050e0401020304010b200041053a00000c0c0b200241206a2001103020022802200d03200041053a00000c0b0b200241c0006a200110b80120022d00404113470d03200041053a00000c0a0b2002200110312002280200450d030c080b41002105200241003a00e8012003417f6a21062003417e6a21030340024020062005470d00200541ff0171450d08200241003a00e8010c080b200241c8016a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00e8012003417f6a21032007210520074120470d000b200241c0006a41186a200241c8016a41186a290300370300200241c0006a41106a200241c8016a41106a290300370300200241c0006a41086a200241c8016a41086a290300370300200220022903c801370340200241086a2001103120022802080d0620012802042205450d06200228020c2103200128020022072d0000210420012005417f6a3602042001200741016a360200200241206a41086a200241c0006a41086a2903002208370300200241206a41106a200241c0006a41106a2903002209370300200241206a41186a200241c0006a41186a290300220a37030020022002290340220b370320200041043a00002000200b370001200041096a2008370000200041116a2009370000200041196a200a370000200041246a2003360200200041216a20043a00000c080b200241cb006a200241206a41086a28020036000020022002290320370043200041013a000020002002290040370001200041086a200241c7006a290000370000200041106a20022902c801370200200041186a200241c8016a41086a290200370200200041206a200241c8016a41106a2902003702000c070b200241c8016a200241c0006a41880110f6041a41880110292205450d022005200241c8016a41880110f6042105200041023a0000200020022f00103b0001200041036a200241106a41026a2d00003a0000200041046a2005360200200041086a2002290220370200200041106a200241206a41086a290200370200200041186a200241206a41106a290200370200200041206a200241206a41186a2902003702000c060b20022802042105200241c0006a200110b80120022d00404113460d04200241c8016a200241c0006a41880110f6041a41880110292201450d022001200241c8016a41880110f6042101200041033a0000200020022f00103b0001200041036a200241126a2d00003a0000200041086a2001360200200041046a20053602002000410c6a2002290220370200200041146a200241206a41086a2902003702002000411c6a200241306a290200370200200041246a200241386a2802003602000c050b200041053a00000c040b4188014108102c000b4188014108102c000b200041053a00000c010b200041053a00000b200241d0026a24000bd50603057f0b7e057f230041106b21020240200128020422034104490d0020012802002204280000210520012003417c6a22063602042001200441046a36020020064108490d00200429000421072001200341746a220636020420012004410c6a36020020064108490d00200429000c210820012003416c6a22063602042001200441146a36020020064108490d00200429001421092001200341646a220636020420012004411c6a36020020064108490d00200429001c210a20012003415c6a22063602042001200441246a36020020064108490d002004290024210b2001200341546a220636020420012004412c6a36020020064108490d00200429002c210c20012003414c6a22063602042001200441346a36020020064108490d002004290034210d2001200341446a220636020420012004413c6a36020020064108490d00200429003c210e2001200341bc7f6a22063602042001200441c4006a36020020064108490d002004290044210f2001200341b47f6a22063602042001200441cc006a36020020064108490d00200429004c21102001200341ac7f6a22063602042001200441d4006a36020020064108490d00200429005421112001200341a47f6a22063602042001200441dc006a36020020064104490d00200428005c21122001200341a07f6a22063602042001200441e0006a36020020064104490d002004280060211320012003419c7f6a22063602042001200441e4006a36020020064104490d00200428006421142001200341987f6a22063602042001200441e8006a36020020064104490d00200428006821152001200341947f6a22063602042001200441ec006a22043602002006450d0020042d000021162001200341937f6a22063602042001200441016a36020020064104490d00200020163a00702000201536026820002014360264200020133602602000201236025c2000200536025820002011370350200020103703482000200f3703402000200e3703382000200d3703302000200c3703282000200b3703202000200a3703182000200937031020002008370308200020073703002004280001210620012003418f7f6a3602042001200441056a3602002000200636026c200041f4006a2002410c6a280000360000200020022800093600710f0b200041023a00700bfb0101077f230041106b220124002001410036020820014201370300200110fc0120012802042102200128020021030240024002400240200041046a2802002204200041086a28020022056b20012802082206490d00200028020021040c010b200520066a22072005490d0220044101742205200720072005491b22054100480d020240024020040d002005102921040c010b200028020020042005102a21040b2004450d0120002004360200200041046a2005360200200041086a28020021050b200041086a200520066a360200200420056a2003200610f6041a02402002450d002003102e0b200141106a24000f0b20054101102c000b102d000bdf0701037f024002400240024002400240024020002d0000417f6a220241034b0d00024002400240024020020e0400010203000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0a20024101742204200320032004491b22044100480d0a0240024020020d002004102921030c010b200128020020022004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41003a0000200028020421022000410c6a2802002200200110472000450d0320004105742100034020022001104a200241206a2102200041606a22000d000c040b0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0920024101742204200320032004491b22044100480d090240024020020d002004102921030c010b200128020020022004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a00002000280204200110bc010f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0820024101742204200320032004491b22044100480d080240024020020d002004102921030c010b200128020020022004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41023a0000200041046a200110662000280208200110bc010f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0720024101742204200320032004491b22044100480d070240024020020d002004102921030c010b200128020020022004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a0000200041016a20011046200041246a2001106602400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d0720024101742204200320032004491b22044100480d070240024020020d002004102921030c010b200128020020022004102a21030b2003450d0620012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20002d00213a00000b0f0b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b102d000bf71802047f017e20002802582102024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2802002203200141086a28020022046b4104490d00200128020021030c010b200441046a22052004490d1320034101742204200520052004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0120012003360200200141046a2004360200200141086a28020021040b200141086a2205200441046a360200200320046a20023600002000290300210602400240200141046a2802002203200528020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0220012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290308210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0320012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290310210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0420012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290318210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290320210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0620012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290328210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0720012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290330210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0820012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290338210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0920012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290340210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0a20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290348210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0b20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290350210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0c20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a2006370000200028025c210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0d20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280260210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0e20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280264210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0f20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280268210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d1020012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a200536000002400240200141046a28020020022802002204460d00200128020021030c010b200441016a22032004490d1320044101742202200320032002491b22024100480d130240024020040d002002102921030c010b200128020020042002102a21030b2003450d1120012003360200200141046a2002360200200141086a28020021040b200141086a2202200441016a360200200320046a20002d00703a0000200028026c210302400240200141046a2802002204200228020022006b4104490d00200128020021040c010b200041046a22022000490d1320044101742200200220022000491b22004100480d130240024020040d002000102921040c010b200128020020042000102a21040b2004450d1220012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a20033600000f0b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20024101102c000b20004101102c000b102d000bb70201057f230041106b2203240020034100360208200342013703002001200310470240024002402001450d00200141b0016c2104034020004188016a28020021050240024020032802042206200328020822016b4104490d00200328020021060c010b200141046a22072001490d0420064101742201200720072001491b22014100480d040240024020060d002001102921060c010b200328020020062001102a21060b2006450d032003200136020420032006360200200328020821010b2003200141046a360208200620016a20053600002000200310bc012000418c016a2003104a200041b0016a2100200441d07e6a22040d000b0b2003280204210020022802002002280204200328020022012003280208100402402000450d002001102e0b200341106a24000f0b20014101102c000b102d000b8d0403057f017e077f02400240024002402001410c6a2802002202417f4c0d00200128020021030240024020020d00410121040c010b20012802042105200210292204450d0220042005200210f6041a0b200141186a2802002206ad420c7e2207422088a70d002007a72205417f4c0d00200128021021080240024020050d00410421090c010b200510292209450d030b0240024020060d004100210a0c010b20082006410c6c6a210b4100210a2009210c0340200841086a2802002205417f4c0d022008280200210d0240024020050d004101210e0c010b20051029220e450d060b200e200d200510f604210d200c41086a2005360200200c41046a2005360200200c200d360200200c410c6a210c200a41016a210a2008410c6a2208200b470d000b0b20002004360204200020033602002000200129021c37021c200041186a200a360200200041146a2006360200200041106a20093602002000410c6a2002360200200041086a2002360200200020012902243702242000412c6a2001412c6a290200370200200041346a200141346a2902003702002000413c6a2001413c6a290200370200200041c4006a200141c4006a290200370200200041cc006a200141cc006a290200370200200041d4006a200141d4006a290200370200200041dc006a200141dc006a2902003702000f0b1032000b20024101102c000b20054104102c000b20054101102c000bb90804087f067e017f047e230041e0026b22022400200241386a2001280200200128020428020c1100000240024020022903384201520d0020024198026a4101722103200241386a41086a2104200241ab016a21050340200241a8016a41186a2206200441186a290000370300200241a8016a41106a2207200441106a290000370300200241a8016a41086a2208200441086a290000370300200220042900003703a80120024198026a200241a8016a108202024002400240024020022d0098024101460d00200241003602e8010c010b200241c0026a41186a200341186a290000370300200241c0026a41106a200341106a290000370300200241c0026a41086a200341086a290000370300200220032900003703c002200241c8016a200241c0026a10830220022802e80122090d010b4200210a4200210b0c010b200241c8016a41186a290300210b20022903d801210a20022802ec01450d002009102e0b20024198026a41086a2008290300220c37030020024198026a41106a2007290300220d37030020024198026a41186a2006290300220e370300200220022903a801220f37039802200241c8016a41086a2207200c370300200241c8016a41106a2209200d370300200241c8016a41186a2210200e3703002002200f3703c801200241c0026a41086a22064200370300200242003703c00241c28cc0004116200241c0026a100320082006290300370300200220022903c0023703a801200241206a200241a8016a109701200241106a2002290328200241206a41106a290300427f420010fc042002200a200b20022903104200200228022022081b220c4201200c420156200241106a41086a290300420020081b220c420052200c501b22081b200c420020081b10fc04024002402002290300220c50450d00410221080c010b200241c0026a41186a2010290300370300200241c0026a41106a200929030037030020062007290300370300200220022903c8013703c002200220022800a8013602a001200220052800003600a3014200211141002108200c2112200a2113200b21140b20024180016a41086a200629030037030020024180016a41106a200241c0026a41106a29030037030020024180016a41186a200241c0026a41186a290300370300200220022903c00237038001200220022802a001360278200220022800a30136007b024020084102460d002000201237031020004200370308200042003703002000200229038001370320200020083a004020002002280278360041200041186a2011370300200041d0006a2014370300200041c8006a2013370300200041c4006a200228007b360000200041286a20024188016a290300370300200041306a20024190016a290300370300200041386a20024180016a41186a2903003703000c030b200241386a2001280200200128020428020c11000020022903384201510d000b0b200041023a00400b200241e0026a24000be70201067f230041d0006b220224000240410e10292203450d00200341002900d9e743370000200341066a41002900dfe7433700002002428e808080e00137020c200220033602082001200241086a104a200228020c21042002280210210520022802082103200241086a41186a22014200370300200241086a41106a22064200370300200241086a41086a220742003703002002420037030820032005200241086a1000200241306a41186a2001290300370300200241306a41106a2006290300370300200241306a41086a200729030037030020022002290308370330200241086a200241306a412010dc010240024020022d00084101460d00200041003a00000c010b20002002290308370000200041206a200241086a41206a2d00003a0000200041186a2001290300370000200041106a2006290300370000200041086a20072903003700000b02402004450d002003102e0b200241d0006a24000f0b410e4101102c000b9b0201067f230041f0006b220224000240410e10292203450d00200341002900b1e843370000200341066a41002900b7e8433700002002428e808080e0013702042002200336020020012002104a200228020421012002280208210420022802002103200241186a22054200370300200241106a22064200370300200241086a22074200370300200242003703002003200420021000200241d0006a41186a2005290300370300200241d0006a41106a2006290300370300200241d0006a41086a2007290300370300200220022903003703502002200241d0006a10ae030240024020022802200d00200041003602200c010b2000200241d00010f6041a0b02402001450d002003102e0b200241f0006a24000f0b410e4101102c000b91880103037f027e037f024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00002202410e4b0d0002400240024002400240024002400240024002400240024002400240024020020e0f000102030405060708090a0b0c0d0e000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5b20024101742204200320032004491b22044100480d5b0240024020020d002004102921030c010b200128020020022004102a21030b2003450d1020012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a0000200141046a280200210320042802002102024020002d00014101460d000240024020032002460d00200128020021000c010b200241016a22002002490d5c20024101742203200020002003491b22034100480d5c0240024020020d002003102921000c010b200128020020022003102a21000b2000450d1220012000360200200141046a2003360200200141086a28020021020b200141086a200241016a360200200020026a41003a00000f0b0240024020032002460d00200128020021000c010b200241016a22002002490d5b20024101742203200020002003491b22034100480d5b0240024020020d002003102921000c010b200128020020022003102a21000b2000450d1220012000360200200141046a2003360200200141086a28020021020b200141086a200241016a360200200020026a41013a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5a20024101742204200320032004491b22044100480d5a0240024020020d002004102921030c010b200128020020022004102a21030b2003450d1220012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d5a20024101742204200320032004491b22044100480d5a0240024020020d002004102921030c010b200128020020022004102a21030b2003450d1320012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a0000200041086a2001104a2000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d5a20024101742200200420042000491b22004100480d5a0240024020020d002000102921020c010b200128020020022000102a21020b2002450d1420012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5920024101742204200320032004491b22044100480d590240024020020d002004102921030c010b200128020020022004102a21030b2003450d1420012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41023a000020002d0008220241024b0d0c02400240024020020e03000102000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5b20024101742204200320032004491b22044100480d5b0240024020020d002004102921030c010b200128020020022004102a21030b2003450d1720012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a0000200041096a2001104a200041386a29030021052000290330210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d5b20024101742200200320032000491b22004100480d5b0240024020020d002000102921020c010b200128020020022000102a21020b2002450d1820012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5a20024101742204200320032004491b22044100480d5a0240024020020d002004102921030c010b200128020020022004102a21030b2003450d1820012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041096a2001104a0f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5920024101742204200320032004491b22044100480d590240024020020d002004102921030c010b200128020020022004102a21030b2003450d1820012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a0000200041096a2001104a200041296a2001104a200041d8006a29030021052000290350210602400240200141046a2802002203200428020022026b4110490d00200128020021030c010b200241106a22042002490d5920034101742202200420042002491b22024100480d590240024020030d002002102921030c010b200128020020032002102a21030b2003450d1920012003360200200141046a2002360200200141086a28020021020b200141086a2204200241106a360200200320026a2202200537000820022006370000200041e8006a29030021052000290360210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d5920024101742200200320032000491b22004100480d590240024020020d002000102921020c010b200128020020022000102a21020b2002450d1a20012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5820024101742204200320032004491b22044100480d580240024020020d002004102921030c010b200128020020022004102a21030b2003450d1a20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41033a000020002d0008220241024b0d0b02400240024020020e03000102000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5a20024101742204200320032004491b22044100480d5a0240024020020d002004102921030c010b200128020020022004102a21030b2003450d1d20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a0000200041186a29030021052000290310210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d5a20024101742200200320032000491b22004100480d5a0240024020020d002000102921020c010b200128020020022000102a21020b2002450d1e20012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5920024101742204200320032004491b22044100480d590240024020020d002004102921030c010b200128020020022004102a21030b2003450d1e20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a0000200041096a2001104a200028022c210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d5920024101742200200420042000491b22004100480d590240024020020d002000102921020c010b200128020020022000102a21020b2002450d1f20012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5820024101742204200320032004491b22044100480d580240024020020d002004102921030c010b200128020020022004102a21030b2003450d1f20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a0000200041096a2001104a200041386a29030021052000290330210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d5820024101742200200320032000491b22004100480d580240024020020d002000102921020c010b200128020020022000102a21020b2002450d2020012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5720024101742204200320032004491b22044100480d570240024020020d002004102921030c010b200128020020022004102a21030b2003450d2020012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d5720024101742204200320032004491b22044100480d570240024020020d002004102921030c010b200128020020022004102a21030b2003450d2120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a00002000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d5720024101742200200420042000491b22004100480d570240024020020d002000102921020c010b200128020020022000102a21020b2002450d2220012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a2207280200200141086a22032802002202460d00200128020021040c010b200241016a22042002490d5620024101742208200420042008491b22084100480d560240024020020d002008102921040c010b200128020020022008102a21040b2004450d2220012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41053a000020002d00082202410a4b0d090240024002400240024002400240024002400240024020020e0b000102030405060708090a000b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d6020024101742208200420042008491b22084100480d600240024020020d002008102921040c010b200128020020022008102a21040b2004450d2d20012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41003a0000200028020c21080240024020072802002204200328020022026b4104490d00200128020021040c010b200241046a22092002490d6020044101742202200920092002491b22024100480d600240024020040d002002102921040c010b200128020020042002102a21040b2004450d2e20012004360200200141046a2002360200200141086a28020021020b2003200241046a360200200420026a2008360000200041186a2903002105200029031021060240024020072802002202200328020022006b4110490d00200128020021020c010b200041106a22042000490d6020024101742200200420042000491b22004100480d600240024020020d002000102921020c010b200128020020022000102a21020b2002450d2f20012002360200200141046a2000360200200141086a28020021000b2003200041106a360200200220006a22012005370008200120063700000f0b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5f20024101742208200420042008491b22084100480d5f0240024020020d002008102921040c010b200128020020022008102a21040b2004450d2f20012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41013a0000200028020c21080240024020072802002204200328020022026b4104490d00200128020021040c010b200241046a22092002490d5f20044101742202200920092002491b22024100480d5f0240024020040d002002102921040c010b200128020020042002102a21040b2004450d3020012004360200200141046a2002360200200141086a28020021020b2003200241046a360200200420026a2008360000200041286a2903002105200029032021060240024020072802002204200328020022026b4110490d00200128020021030c010b200241106a22032002490d5f20044101742202200320032002491b22024100480d5f0240024020040d002002102921030c010b200128020020042002102a21030b2003450d3120012003360200200141046a2002360200200141086a28020021020b200141086a200241106a360200200320026a220220053700082002200637000020002802102102200041186a2802002200200110472000450d1220004105742100034020022001104a200241206a2102200041606a22000d000c130b0b02400240200728020020032802002200460d00200128020021020c010b200041016a22022000490d5e20004101742204200220022004491b22044100480d5e0240024020000d002004102921020c010b200128020020002004102a21020b2002450d3120012002360200200141046a2004360200200141086a28020021000b2003200041016a360200200220006a41023a00000f0b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5d20024101742208200420042008491b22084100480d5d0240024020020d002008102921040c010b200128020020022008102a21040b2004450d3120012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41033a0000200028020c21080240024020072802002204200328020022026b4104490d00200128020021040c010b200241046a22092002490d5d20044101742202200920092002491b22024100480d5d0240024020040d002002102921040c010b200128020020042002102a21040b2004450d3220012004360200200141046a2002360200200141086a28020021020b2003200241046a360200200420026a200836000020002d0009220041024b0d1002400240024020000e03000102000b02400240200728020020032802002200460d00200128020021020c010b200041016a22022000490d5f20004101742204200220022004491b22044100480d5f0240024020000d002004102921020c010b200128020020002004102a21020b2002450d3520012002360200200141046a2004360200200141086a28020021000b2003200041016a360200200220006a41003a00000f0b02400240200728020020032802002200460d00200128020021020c010b200041016a22022000490d5e20004101742204200220022004491b22044100480d5e0240024020000d002004102921020c010b200128020020002004102a21020b2002450d3520012002360200200141046a2004360200200141086a28020021000b2003200041016a360200200220006a41013a00000f0b02400240200728020020032802002200460d00200128020021020c010b200041016a22022000490d5d20004101742204200220022004491b22044100480d5d0240024020000d002004102921020c010b200128020020002004102a21020b2002450d3520012002360200200141046a2004360200200141086a28020021000b2003200041016a360200200220006a41023a00000f0b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5c20024101742208200420042008491b22084100480d5c0240024020020d002008102921040c010b200128020020022008102a21040b2004450d3520012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41043a0000200028020c21040240024020072802002202200328020022006b4104490d00200128020021020c010b200041046a22072000490d5c20024101742200200720072000491b22004100480d5c0240024020020d002000102921020c010b200128020020022000102a21020b2002450d3620012002360200200141046a2000360200200141086a28020021000b2003200041046a360200200220006a20043600000f0b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5b20024101742208200420042008491b22084100480d5b0240024020020d002008102921040c010b200128020020022008102a21040b2004450d3620012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41053a0000200028020c21040240024020072802002202200328020022006b4104490d00200128020021020c010b200041046a22072000490d5b20024101742200200720072000491b22004100480d5b0240024020020d002000102921020c010b200128020020022000102a21020b2002450d3720012002360200200141046a2000360200200141086a28020021000b2003200041046a360200200220006a20043600000f0b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5a20024101742208200420042008491b22084100480d5a0240024020020d002008102921040c010b200128020020022008102a21040b2004450d3720012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41063a0000200028020c21040240024020072802002202200328020022006b4104490d00200128020021020c010b200041046a22072000490d5a20024101742200200720072000491b22004100480d5a0240024020020d002000102921020c010b200128020020022000102a21020b2002450d3820012002360200200141046a2000360200200141086a28020021000b2003200041046a360200200220006a20043600000f0b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5920024101742208200420042008491b22084100480d590240024020020d002008102921040c010b200128020020022008102a21040b2004450d3820012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41073a0000200028020c21080240024020072802002204200328020022026b4104490d00200128020021040c010b200241046a22092002490d5920044101742202200920092002491b22024100480d590240024020040d002002102921040c010b200128020020042002102a21040b2004450d3920012004360200200141046a2002360200200141086a28020021020b2003200241046a360200200420026a200836000002400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5920024101742207200420042007491b22074100480d590240024020020d002007102921040c010b200128020020022007102a21040b2004450d3a20012004360200200141046a2007360200200141086a28020021020b2003200241016a360200200420026a20002d00093a00000f0b02400240200728020020032802002202460d00200128020021030c010b200241016a22032002490d5820024101742204200320032004491b22044100480d580240024020020d002004102921030c010b200128020020022004102a21030b2003450d3a20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41083a0000200041096a2001104a200041296a2001104a0f0b02400240200728020020032802002202460d00200128020021030c010b200241016a22032002490d5720024101742204200320032004491b22044100480d570240024020020d002004102921030c010b200128020020022004102a21030b2003450d3a20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41093a0000200041096a2001104a0f0b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5620024101742207200420042007491b22074100480d560240024020020d002007102921040c010b200128020020022007102a21040b2004450d3a20012004360200200141046a2007360200200141086a28020021020b200141086a2207200241016a360200200420026a410a3a0000200041096a2001104a200041296a20011046200028024c210402400240200141046a2802002202200728020022006b4104490d00200128020021020c010b200041046a22072000490d5620024101742200200720072000491b22004100480d560240024020020d002000102921020c010b200128020020022000102a21020b2002450d3b20012002360200200141046a2000360200200141086a28020021000b2003200041046a360200200220006a20043600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5520024101742204200320032004491b22044100480d550240024020020d002004102921030c010b200128020020022004102a21030b2003450d3b20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41063a0000200041046a20011085020f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5420024101742204200320032004491b22044100480d540240024020020d002004102921030c010b200128020020022004102a21030b2003450d3b20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41073a0000200041046a20011085020f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5320024101742204200320032004491b22044100480d530240024020020d002004102921030c010b200128020020022004102a21030b2003450d3b20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41083a0000024002400240024020002d00040e0400010203000b02400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d5620024101742204200320032004491b22044100480d560240024020020d002004102921030c010b200128020020022004102a21030b2003450d3f20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41003a0000200041056a2001104a200041256a2001104a0f0b02400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d5520024101742204200320032004491b22044100480d550240024020020d002004102921030c010b200128020020022004102a21030b2003450d3f20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041056a2001104a0f0b02400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d5420024101742204200320032004491b22044100480d540240024020020d002004102921030c010b200128020020022004102a21030b2003450d3f20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a00002000280208210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d5420024101742200200420042000491b22004100480d540240024020020d002000102921020c010b200128020020022000102a21020b2002450d4020012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d5320024101742204200320032004491b22044100480d530240024020020d002004102921030c010b200128020020022004102a21030b2003450d4020012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41033a000020002802082102200041106a28020022032001104702402003450d0020034105742103034020022001104a200241206a2102200341606a22030d000b0b200028021421022000411c6a2802002200200110472000450d0620004105742100034020022001104a200241206a2102200041606a22000d000c070b0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5220024101742204200320032004491b22044100480d520240024020020d002004102921030c010b200128020020022004102a21030b2003450d4020012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41093a000020002d0001220041044b0d050240024002400240024020000e050001020304000b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d5620004101742203200220022003491b22034100480d560240024020000d002003102921020c010b200128020020002003102a21020b2002450d4520012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41003a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d5520004101742203200220022003491b22034100480d550240024020000d002003102921020c010b200128020020002003102a21020b2002450d4520012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41013a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d5420004101742203200220022003491b22034100480d540240024020000d002003102921020c010b200128020020002003102a21020b2002450d4520012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41023a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d5320004101742203200220022003491b22034100480d530240024020000d002003102921020c010b200128020020002003102a21020b2002450d4520012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41033a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d5220004101742203200220022003491b22034100480d520240024020000d002003102921020c010b200128020020002003102a21020b2002450d4520012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41043a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5120024101742204200320032004491b22044100480d510240024020020d002004102921030c010b200128020020022004102a21030b2003450d4520012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a410a3a00002000280204220241024b0d0402400240024020020e03000102000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5320024101742204200320032004491b22044100480d530240024020020d002004102921030c010b200128020020022004102a21030b2003450d4820012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a000020002802082102200041106a2802002200200110472000450d062002200041286c6a2109200141046a2107034020022001104a200241206a29030021050240024020072802002203200428020022006b4108490d00200128020021030c010b200041086a22082000490d5420034101742200200820082000491b22004100480d540240024020030d002000102921030c010b200128020020032000102a21030b2003450d4a2001200336020020072000360200200428020021000b2004200041086a360200200320006a20053700002009200241286a2202470d000c070b0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d5220004101742203200220022003491b22034100480d520240024020000d002003102921020c010b200128020020002003102a21020b2002450d4920012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41013a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d5120004101742203200220022003491b22034100480d510240024020000d002003102921020c010b200128020020002003102a21020b2002450d4920012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41023a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5020024101742204200320032004491b22044100480d500240024020020d002004102921030c010b200128020020022004102a21030b2003450d4920012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a410b3a000020002d0008220241044b0d030240024002400240024020020e050001020304000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5420024101742204200320032004491b22044100480d540240024020020d002004102921030c010b200128020020022004102a21030b2003450d4e20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a0000200028020c210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d5420024101742200200420042000491b22004100480d540240024020020d002000102921020c010b200128020020022000102a21020b2002450d4f20012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5320024101742204200320032004491b22044100480d530240024020020d002004102921030c010b200128020020022004102a21030b2003450d4f20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a0000200041186a29030021052000290310210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d5320024101742200200320032000491b22004100480d530240024020020d002000102921020c010b200128020020022000102a21020b2002450d5020012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5220024101742204200320032004491b22044100480d520240024020020d002004102921030c010b200128020020022004102a21030b2003450d5020012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a0000200028022c210702400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d5220034101742202200420042002491b22024100480d520240024020030d002002102921030c010b200128020020032002102a21030b2003450d5120012003360200200141046a2002360200200141086a28020021020b200141086a2204200241046a360200200320026a2007360000200041386a29030021052000290330210602400240200141046a2802002203200428020022026b4110490d00200128020021030c010b200241106a22042002490d6920034101742202200420042002491b22024100480d690240024020030d002002102921030c010b200128020020032002102a21030b2003450d5320012003360200200141046a2002360200200141086a28020021020b200141086a200241106a360200200320026a2202200537000820022006370000200041096a2001104a0f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6820024101742204200320032004491b22044100480d680240024020020d002004102921030c010b200128020020022004102a21030b2003450d5320012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a0000200041186a29030021052000290310210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d6820024101742200200320032000491b22004100480d680240024020020d002000102921020c010b200128020020022000102a21020b2002450d5420012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6720024101742204200320032004491b22044100480d670240024020020d002004102921030c010b200128020020022004102a21030b2003450d5420012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a0000200041186a29030021052000290310210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d6720024101742200200320032000491b22004100480d670240024020020d002000102921020c010b200128020020022000102a21020b2002450d5520012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6620024101742204200320032004491b22044100480d660240024020020d002004102921030c010b200128020020022004102a21030b2003450d5520012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a410c3a000020002d0008220241054b0d0202400240024002400240024020020e06000102030405000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6b20024101742204200320032004491b22044100480d6b0240024020020d002004102921030c010b200128020020022004102a21030b2003450d5b20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a0000200041096a2001104a200041296a2001104a200041d8006a29030021052000290350210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d6b20024101742200200320032000491b22004100480d6b0240024020020d002000102921020c010b200128020020022000102a21020b2002450d5c20012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6a20024101742204200320032004491b22044100480d6a0240024020020d002004102921030c010b200128020020022004102a21030b2003450d5c20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041096a2001104a200041296a2001104a0f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6920024101742204200320032004491b22044100480d690240024020020d002004102921030c010b200128020020022004102a21030b2003450d5c20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41023a0000200041096a200110460f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6820024101742204200320032004491b22044100480d680240024020020d002004102921030c010b200128020020022004102a21030b2003450d5c20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a0000200028020c210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d6820024101742200200420042000491b22004100480d680240024020020d002000102921020c010b200128020020022000102a21020b2002450d5d20012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6720024101742204200320032004491b22044100480d670240024020020d002004102921030c010b200128020020022004102a21030b2003450d5d20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a0000200041096a2001104a02400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d6720024101742204200320032004491b22044100480d670240024020020d002004102921030c010b200128020020022004102a21030b2003450d5e20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20002d00293a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6620024101742204200320032004491b22044100480d660240024020020d002004102921030c010b200128020020022004102a21030b2003450d5e20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41053a0000200041096a2001104a200028022c2107200041346a28020022002001104702400240200141046a2802002203200428020022026b2000490d00200128020021030c010b200220006a22042002490d6620034101742202200420042002491b22024100480d660240024020030d002002102921030c010b200128020020032002102a21030b2003450d5f20012003360200200141046a2002360200200141086a28020021020b200141086a200220006a360200200320026a2007200010f6041a0f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6520024101742204200320032004491b22044100480d650240024020020d002004102921030c010b200128020020022004102a21030b2003450d5f20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a410d3a0000200041026a2103200141046a280200210720042802002102024020002d00014101460d000240024020072002460d00200128020021000c010b200241016a22002002490d6620024101742204200020002004491b22044100480d660240024020020d002004102921000c010b200128020020022004102a21000b2000450d6120012000360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200020026a41003a000002400240200141046a28020020042802002200460d00200128020021020c010b200041016a22022000490d6620004101742204200220022004491b22044100480d660240024020000d002004102921020c010b200128020020002004102a21020b2002450d6220012002360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200220006a20032d00003a00000f0b0240024020072002460d00200128020021000c010b200241016a22002002490d6520024101742204200020002004491b22044100480d650240024020020d002004102921000c010b200128020020022004102a21000b2000450d6220012000360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200020026a41013a000020032001104a0f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6420024101742204200320032004491b22044100480d640240024020020d002004102921030c010b200128020020022004102a21030b2003450d6220012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a410e3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d6420024101742204200320032004491b22044100480d640240024020020d002004102921030c010b200128020020022004102a21030b2003450d6320012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41003a0000200041016a2001104a0b0f0b20044101102c000b20034101102c000b20034101102c000b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20024101102c000b20004101102c000b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20004101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20004101102c000b20084101102c000b20084101102c000b20024101102c000b20004101102c000b20084101102c000b20024101102c000b20024101102c000b20044101102c000b20084101102c000b20024101102c000b20044101102c000b20044101102c000b20044101102c000b20084101102c000b20004101102c000b20084101102c000b20004101102c000b20084101102c000b20004101102c000b20084101102c000b20024101102c000b20074101102c000b20044101102c000b20044101102c000b20074101102c000b20004101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20034101102c000b20034101102c000b20034101102c000b20034101102c000b20034101102c000b20044101102c000b20044101102c000b20004101102c000b20034101102c000b20034101102c000b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20004101102c000b20044101102c000b20024101102c000b102d000b20024101102c000b20044101102c000b20004101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20044101102c000b20024101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b102d000ba41201047f02400240024002400240024002400240024002400240024002400240024020002d0000220241054b0d0002400240024002400240024020020e06000102030405000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1420024101742204200320032004491b22044100480d140240024020020d002004102921030c010b200128020020022004102a21030b2003450d0720012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a0000200041016a2001104a2000280244210502400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d1420034101742202200420042002491b22024100480d140240024020030d002002102921030c010b200128020020032002102a21030b2003450d0820012003360200200141046a2002360200200141086a28020021020b200141086a2204200241046a360200200320026a2005360000200041216a200110462000280248210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d1420024101742200200420042000491b22004100480d140240024020020d002000102921020c010b200128020020022000102a21020b2002450d0920012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1320024101742204200320032004491b22044100480d130240024020020d002004102921030c010b200128020020022004102a21030b2003450d0920012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a0000200041016a2001104a200041216a2001104602400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1320024101742204200320032004491b22044100480d130240024020020d002004102921030c010b200128020020022004102a21030b2003450d0a20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00413a00002000280244210502400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d1320034101742202200420042002491b22024100480d130240024020030d002002102921030c010b200128020020032002102a21030b2003450d0b20012003360200200141046a2002360200200141086a28020021020b200141086a2204200241046a360200200320026a20053600002000280248210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d1320024101742200200420042000491b22004100480d130240024020020d002000102921020c010b200128020020022000102a21020b2002450d0c20012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1220024101742204200320032004491b22044100480d120240024020020d002004102921030c010b200128020020022004102a21030b2003450d0c20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41023a0000200041016a200110460f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004102921030c010b200128020020022004102a21030b2003450d0c20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41033a0000200041016a200110460f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1020024101742204200320032004491b22044100480d100240024020020d002004102921030c010b200128020020022004102a21030b2003450d0c20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a0000200041016a2001104602400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1020024101742204200320032004491b22044100480d100240024020020d002004102921030c010b200128020020022004102a21030b2003450d0d20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20002d00213a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0f20024101742204200320032004491b22044100480d0f0240024020020d002004102921030c010b200128020020022004102a21030b2003450d0d20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41053a0000200041016a2001104602400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d0f20024101742204200320032004491b22044100480d0f0240024020020d002004102921030c010b200128020020022004102a21030b2003450d0e20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20002d00213a00000b0f0b20044101102c000b20024101102c000b20004101102c000b20044101102c000b20044101102c000b20024101102c000b20004101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b102d000b130020004102360204200041e0e2c5003602000b130020004101360204200041c8b5c2003602000b130020004103360204200041dc88c0003602000b130020004103360204200041d0e3c3003602000b130020004101360204200041f0dfc5003602000b13002000410b36020420004188c2c4003602000b13002000410636020420004184bac2003602000b13002000410436020420004194f5c0003602000b130020004105360204200041b09dc2003602000b1300200041033602042000418cdac5003602000b130020004105360204200041e0d4c0003602000b130020004106360204200041b49ec3003602000b130020004102360204200041b0c5c2003602000b130020004101360204200041f8d7c5003602000bcb0501027f4190ce002102410121030240024002400240024002400240024002400240024002400240024002400240024020012d00000e13001010100e010203040506090b0e0e0c0e0d0e000b417f2102200141086a280200417f6a220141054b0d0d4101210320010e060f0d090709090f0b41002103200141086a280200417f6a220141014b0d0d41c0843d2102024020010e020f000f0b4101210341a0c21e21020c0e0b41002103200141086a2d0000417f6a2201410d4b0d0c41a0c21e210202400240024020010e0e101000000101101001020a0a0a0a100b4180b51821020c0f0b41b0e32d21020c0e0b41f093092102410121030c0d0b4100210341f0930921020c0c0b41002103200141086a2d0000417f6a220141104b0d0a41c096b10221020240024002400240024020010e11101000000110101002020a0a0303030404100b41c09a0c21020c0f0b41a0c21e2102410121030c0e0b41c09a0c21020c0d0b41a08d0621020c0c0b41a0c21e21020c0b0b200141046a2d0000417f6a220141034b0d0841a08d0621024101210320010e040a0a01020a0b200141046a2d0000417f6a220141034b0d0741a08d0621024101210320010e0409090001090b41c096b1022102410121030c080b41c09a0c2102410121030c070b41002103200141086a280200417f6a220141094b0d0541a0cb980121020240024020010e0a08080800080102020202080b41d0a5cc0021020c070b4180ade20421020c060b4190ce002102410121030c050b41d086034190ce00200141046a2d0000411d7441808080807e6a411d75417f4a1b2102410021030c040b41002103200141086a280200417f6a220141024b0d0241a0c21e2102024020010e03040000040b41a08d062102410121030c030b41012103200141046a280200417f6a220141014b0d0041c0843d210220010e020200020b410021030b4190ce0021020b200020033a0004200020023602000bbff10108017f017e0f7f027e057f027e0b7f047e230041f0096b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e1300010203251e1d1c1b1a19180f0d0a09080706000b200141106a29030021042001410c6a280200210520022d0001210620022d000021020240024002400240024002400240024002400240200141086a28020022070e0700010203040607000b200341fc086a4101360200200342013702ec08200341cc91c5003602e8082003411c3602a407200341c491c5003602a0072003200341a0076a3602f808200341e8086a41949ec300106a000b41002108418df0c2004100200220067241ff01711b21094128210a4101210b0c380b2004a7210702400240200241ff01710d004101210b200641ff01714101460d010b41b5f0c2002109412a210a4101210b410021082007450d380c370b20070d020c330b4128210a4101210b0240200220067241ff0171450d00418df0c2002109410021080c370b410810292202450d0a2002200437000041a49ec300410a2002410810042002102e4100210841012106410121074101210c4101210d4101210e4101210f41012110410121110c100b2004a721070240200220067241ff0171450d00418df0c20021094128210a4101210b4100210820070d350c360b41ae9ec300410520052004422088a710044101210b2007450d310b2005102e0c300b2004422088a721092004a7210a0240200220067241ff0171450d0002402009450d00200941186c21082005210203400240200241046a280200450d002002280200102e0b0240200241106a280200450d002002410c6a280200102e0b200241186a2102200841686a22080d000b0b418df0c20021094101211241002113200a0d020c2f0b0240200941186c2202450d00200520026a21082005210203402002280200200241086a2802002002410c6a280200200241146a2802001004200241186a22022008470d000b0b02402009450d00200941186c21082005210203400240200241046a280200450d002002280200102e0b0240200241106a280200450d002002410c6a280200102e0b200241186a2102200841686a22080d000b0b41012112200a450d2d2005102e0c2d0b2004422088a721092004a7210a200220067241ff0171450d0102402009450d002009410c6c21082005210203400240200241046a280200450d002002280200102e0b2002410c6a2102200841746a22080d000b0b418df0c20021094100211241012113200a450d2d0b2005102e0c2c0b02402009410c6c2202450d00200520026a21082005210203402002280200200241086a28020010062002410c6a22022008470d000b0b02402009450d002009410c6c21082005210203400240200241046a280200450d002002280200102e0b2002410c6a2102200841746a22080d000b0b41012113200a450d292005102e0c290b418df0c20021094128210a4101210820022d000120022d0000720d0c024020012d0001220241ff01714102470d0041dfddc5004120109c011a410021094101210b0c300b41012108200320024101713a00e808200341c0066a41086a22024200370300200342003703c00641dfddc5004120200341c0066a100320034188086a41086a2002290300370300200320032903c0063703880820034188086a4110200341e8086a41011004410021094101210b0c2f0b41e9efc20021094124210a4101210820022d00000d0b20022d000141ff01714102470d0b200141086a2903002104200341c0066a41086a22024200370300200342003703c00641cde2c5004113200341c0066a100320034188086a41086a2002290300370300200320032903c0063703880820034188086a411041c8ecc500410041001005417f470d01200341186a41c5c1c200410d108101024002402003290320500d002003280218450d00200341086a41c5c1c200410d108101200329031042b8177c42b81720032802081b2004560d010b200341c0066a41086a22024200370300200342003703c00641c5c1c200410d200341c0066a100320034188086a41086a22062002290300370300200320032903c00637038808200320043703e80820034188086a4110200341e8086a4108100441012108200341013a00e80820024200370300200342003703c00641cde2c5004113200341c0066a100320062002290300370300200320032903c0063703880820034188086a4110200341e8086a41011004410021094101210b0c2f0b419cb9c2001058000b2001410c6a2802002108200141086a2802002105200141046a280200211041e9efc20021094124210a20022d00000d2520022d000141ff01714102470d25200341c0066a41086a22024200370300200342003703c00641d49bc5004117200341c0066a100320034188086a41086a2002290300370300200320032903c00637038808200341003602e80820034188086a4110200341e8086a10082102024002400240024020032802e8082206417f460d002002450d002006450d0120022d000021062002102e20064102460d002006410171450d0041e09ac2002109411c210a0c290b200341013a00e808200341c0066a41086a22024200370300200342003703c00641d49bc5004117200341c0066a100320034188086a41086a22062002290300370300200320032903c0063703880820034188086a4110200341e8086a41011004200341306a41b0f3c200410d107d200328023421072003280230210920024200370300200342003703c006419893c2004111200341c0066a100320062002290300370300200320032903c00637038808200341003602e80820034188086a4110200341e8086a100821020240024020032802e8082206417f460d002002450d00200320063602f403200320023602f003200341e8086a200341f0036a103d20032802e808220c450d0420032902ec0821042006450d012002102e0c010b4104210c420021040b02402004a72004422088a72202470d00200241016a22062002490d102002410174220a20062006200a491bad221442c4007e2215422088a70d102015a722064100480d100240024020020d0020061029210c0c010b200c200241c4006c2006102a210c0b200c450d0220044280808080708320148421040b200c200241c4006c6a220241003a000020022007410020091b360204200220032f01ec033b0001200241036a200341ec036a41026a2d00003a0000200220032902e808370208200241106a200341e8086a41086a2216290200370200200241186a200341e8086a41106a2217290200370200200241206a200341e8086a41186a290200370200200241286a200341e8086a41206a290200370200200241306a200341e8086a41286a290200370200200241386a200341e8086a41306a290200370200200241c0006a200341e8086a41386a28020036020020044280808080107c21042010200841f0006c6a210d024020080d00201021070c270b20034188086a417f6a210e200341bb066a2113200341ff066a2112200341c3076a210b200341a0076a41186a211820102107024003402007280204210220072802002108200341e8086a200741086a41e80010f6041a200741f0006a21072002450d28200341f0036a200341e8086a41e80010f6041a200320023602ec08200320083602e8082016200341f0036a41e80010f6041a200341286a41b0f3c200410d107d20032802282108200328022c210620034188086a200341e8086a10960202400240024020032802e80822020d0041929bc20021094110210a0c010b024020022006410020081b22084d0d00411a210a41a29bc20021090c010b200341a0076a2002417f6a10ba010240200341a0076a2017412010f804450d004119210a41bc9bc20021090c010b024020032802e808220941002008417b6a2202200220084b1b4f0d004126210a41d59bc20021090c010b200c210202400240200c2004422088a7220f41c4006c22116a2206200c6b41cd01490d00200c21020340024020022d00004101470d00200241016a2108200e2002460d03200820034188086a412010f804450d030b0240200241c4006a2d00004101470d00200241c5006a2108200b2002460d03200820034188086a412010f804450d030b024020024188016a2d00004101470d0020024189016a210820122002460d03200820034188086a412010f804450d030b0240200241cc016a2d00004101470d00200241cd016a210820132002460d03200820034188086a412010f804450d030b200620024190026a22026b41cc014b0d000b0b024020022006460d000340024020022d00004101470d00200241016a2108200e2002460d03200820034188086a412010f804450d030b2006200241c4006a2202470d000b0b410021080b200341a0076a200910ba01200341a0076a20034188086a412010f8042102200341c0056a41086a2206200341c0066a41086a290300370300200341c0056a41106a200341c0066a41106a290300370300200320032903c0063703c00541fc9ac20021094116210a20080d2920020d010c290b200341c0056a41086a200341c0066a41086a290300370300200341c0056a41106a200341c0066a41106a290300370300200320032903c0063703c0050c280b200341a0066a410e6a2209200341c0056a410e6a290100370100200341a0066a41086a220a2006290300370300200320032903c0053703a00620034188086a200341e8086a10960220184200370300200341a0076a41106a22064200370300200341a0076a41086a22084200370300200342003703a007024041c80010292202450d00200341f8046a1088012002410236022020024101360244200241186a200341f8046a41186a290300370200200241106a200341f8046a41106a290300370200200241086a200341f8046a41086a290300370200200220032903f804370200200220032903a0073700242002412c6a2008290300370000200241346a20062903003700002002413c6a2018290300370000200320023602c00620034282808080203702c406200341c0066a109702200341d8046a41086a220620034188086a41086a290300370300200341d8046a41106a221920034188086a41106a290300370300200341d8046a41186a221a20034188086a41186a2903003703002008200a290300370300200341a0076a410e6a220a200929010037010020032003290388083703d804200320032903a0063703a00702402004a7200f470d00200f41016a2202200f490d13200f4101742209200220022009491bad221442c4007e2215422088a70d132015a722024100480d1302400240200f0d0020021029210c0c010b200c20112002102a210c0b200c450d0320044280808080708320148421040b200c20116a220241013a00002006290300211420192903002115201a290300211b20032903d804211c20024116360028200241fc9ac200360024200241003a0021200241196a201b370000200241116a2015370000200241096a20143700002002201c3700012002413a6a200a290100370000200241346a2008290300370000200220032903a00737002c024020032802f4082208450d0020032802ec082102200841246c210803400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022008415c6a22080d000b0b024020032802f008450d0020032802ec08102e0b20044280808080107c21042007200d470d010c2a0b0b41c8004104102c000b20024104102c000b41eff0c200413320034198056a4184f4c2001053000b20064104102c000b41eff0c200413320034198056a4184f4c2001053000b41d4b8c2001058000b41084101102c000b200341f0036a200141046a220841e40010f6041a4124210a200141246a280200210b200141206a28020021192001411c6a280200210f200141186a2802002111200141146a2802002110200141106a28020021052001410c6a2802002118200141086a280200211a20082802002108200341d8076a200341cc046a290200370300200341d0076a200341c4046a290200370300200341c8076a200341bc046a290200370300200341a0076a41206a200341b4046a290200370300200341a0076a41186a200341ac046a290200370300200341a0076a41106a200341a4046a290200370300200341a0076a41086a2003419c046a29020037030020032003290294043703a00741e9efc20021090240024020022d00000d0020022d000141ff01714102470d00200341c0036a41b8dfc5004114107d41c9dbc1002109411b210a20032802c403410020032802c0031b2019470d0020034188086a201910f6012003200b3602c006200341f8046a41186a22024200370300200341f8046a41106a22064200370300200341f8046a41086a22074200370300200342003703f804200341c0066a4104200341f8046a1000200341e8086a41186a2002290300370300200341e8086a41106a2006290300370300200341e8086a41086a2007290300370300200320032903f8043703e8080240024002400240024002400240024002400240200328028c08220720032802900822066b4120490d00200641206a210920032802880821020c010b200641206a22092006490d1420074101742202200920092002491b220c4100480d140240024020070d00200c102921020c010b2003280288082007200c102a21020b2002450d012003200c36028c082003200236028808200c21070b200220066a220620032903e808370000200641186a200341e8086a41186a290300370000200641106a200341e8086a41106a290300370000200641086a200341e8086a41086a2206290300370000410021132002200941c8ecc500410041001005210902402007450d002002102e0b200341c0066a41086a22024200370300200342003703c0064183d9c500410d200341c0066a100320062002290300370300200320032903c0063703e80820034188086a200341e8086a1098020240024020032802880822120d0041012112410021020c010b20034190086a2802002102200328028c0821130b2009417f470d062012200b4105746a41002002200b4b1b2216450d06200341003602f008200342013703e808410410292202450d0120034284808080c0003702ec08200320023602e808200220083600002005200341e8086a10470240024020032802ec08220820032802f00822026b2005490d0020032802e80821080c010b200220056a22062002490d1420084101742207200620062007491b22064100480d140240024020080d002006102921080c010b20032802e80820082006102a21080b2008450d03200320063602ec08200320083602e8080b2003200220056a3602f008200820026a201a200510f6041a200f200341e8086a10472010200f410c6c6a210e200f450d032010210803402008280200210c200841086a2802002202200341e8086a10470240024020032802ec08220720032802f00822066b2002490d0020032802e80821090c010b200620026a22092006490d152007410174220d20092009200d491b220d4100480d150240024020070d00200d102921090c010b20032802e8082007200d102a21090b2009450d062003200d3602ec08200320093602e808200d21070b2003200620026a220d3602f008200920066a200c200210f6041a2008410c6a2208200e470d000c060b0b200c4101102c000b41044101102c000b20064101102c000b20032802ec08210720032802f008210d0c010b200d4101102c000b024002400240024002400240024002402007200d6b4104490d00200d41046a210820032802e80821020c010b200d41046a2208200d490d1420074101742202200820082002491b22064100480d140240024020070d002006102921020c010b20032802e80820072006102a21020b2002450d01200320063602ec08200320023602e808200621070b200320083602f0082002200d6a201936000002400240200720086b41034d0d00200721060c010b200841046a22062008490d1420074101742209200620062009491b22064100480d140240024020070d002006102921020c010b200220072006102a21020b2002450d02200320063602ec08200320023602e8080b200220086a200b3600002002200841046a200341a0076a2016100c210802402006450d002002102e0b024020080d00200341f1086a201641086a290000370000200341f9086a201641106a29000037000020034181096a201641186a2900003700002003410e3a00e808200320162900003700e90841c8ecc5004100200341e8086a1072200341003602f008200342013703e8082005200341e8086a10470240024020032802ec08220820032802f00822026b2005490d0020032802e80821080c010b200220056a22062002490d1520084101742207200620062007491b22064100480d150240024020080d002006102921080c010b20032802e80820082006102a21080b2008450d04200320063602ec08200320083602e8080b2003200220056a3602f008200820026a201a200510f6041a200f200341e8086a1047200f450d042010210803402008280200210a200841086a2802002202200341e8086a10470240024020032802ec08220920032802f00822066b2002490d0020032802e80821070c010b200620026a22072006490d162009410174220c20072007200c491b220c4100480d160240024020090d00200c102921070c010b20032802e8082009200c102a21070b2007450d072003200c3602ec08200320073602e808200c21090b2003200620026a220c3602f008200720066a200a200210f6041a2008410c6a2208200e470d000c070b0b41e4dbc10021092013450d082012102e0c080b20064101102c000b20064101102c000b20064101102c000b20032802f008210c20032802ec08210920032802e80821070c010b200c4101102c000b20034188086a201910f6012003200b3602c006200341f8046a41186a22024200370300200341f8046a41106a22084200370300200341f8046a41086a22064200370300200342003703f804200341c0066a4104200341f8046a1000200341e8086a41186a2002290300370300200341e8086a41106a2008290300370300200341e8086a41086a2006290300370300200320032903f8043703e80802400240200328028c08220a20032802900822086b4120490d0020032802880821020c010b200841206a22022008490d0e200a4101742206200220022006491b22064100480d0e02400240200a0d002006102921020c010b200328028808200a2006102a21020b2002450d022003200636028c0820032002360288082006210a0b200220086a220620032903e808370000200641186a200341e8086a41186a290300370000200641106a200341e8086a41106a290300370000200641086a200341e8086a41086a2903003700002003200841206a3602ec08200320023602e8082007200c200341e8086a1099020240200a450d002002102e0b2009450d002007102e0b02402013450d002012102e0b02402018450d00201a102e0b0240200f450d00200f410c6c21082010210203400240200241046a280200450d002002280200102e0b2002410c6a2102200841746a22080d000b0b4100210902402011450d002010102e0b0c020b20064101102c000b02402018450d00201a102e0b0240200f450d00200f410c6c21082010210203400240200241046a280200450d002002280200102e0b2002410c6a2102200841746a22080d000b0b2011450d002010102e0b4100211a410121084101210b41012106410121074101210c4101210d4101210e4101210f410121104101211141012118410121190c340b2002411a6a2901002104200241196a2d00002107200241186a2d0000210c200241166a2f0100210d200241156a2d0000210e200241146a2d0000210f200241126a2f01002110200241116a2d00002111200241106a2d000021182002410e6a2f010021192002410d6a2d0000211a2002410c6a2d0000210b2002410a6a2f01002105200241096a2d00002112200241086a2d00002113200241066a2f01002116200241056a2d00002117200241046a2d0000211d200241026a2f0100211e200141086a280200210620022d0001210820022d00002102024002400240024002400240200141046a2802000e03000102000b200341e8086a41146a4101360200200342013702ec08200341cc91c5003602e8082003411c3602a407200341c491c5003602a0072003200341a0076a3602f808200341e8086a41c8e6c200106a000b41b5f0c2002109412a210a200241ff01710d02200841ff01714101470d02200320043703b807200320073a00b7072003200c3a00b6072003200d3b01b4072003200e3a00b3072003200f3a00b207200320103b01b007200320113a00af07200320183a00ae07200320193b01ac072003201a3a00ab072003201d3a00a2072003201e3b01a00720032005410874200b411874722012723600a707200320164108742017722013411874723600a307200341c0066a41086a22024200370300200342003703c00641fae6c2004108200341c0066a100320034188086a41086a2002290300370300200320032903c00637038808200341e8086a20034188086a411010dc010240024020032d00e8084101460d00200341f0036a41186a4200370300200341f0036a41106a4200370300200341f0036a41086a4200370300200342003703f0030c010b200341f0036a41186a20034181096a290000370300200341f0036a41106a200341f9086a290000370300200341f0036a41086a200341f1086a290000370300200320032900e9083703f0030b0240200341a0076a200341f0036a412010f804450d0041d8e6c20021094122210a0c030b200341e8086a200641880110f6041a41002119200341003b01f003200341b8036a200341e8086a200341f0036a1095024101210841012102024020032802b8032207450d00200720032802bc031009410021020b200320023a00ea082003410d3b01e80841c8ecc5004100200341e8086a10722006102e0c010b02400240200241ff01710d00200841ff01714101460d010b41b5f0c2002109412a210a0c030b200141216a2900002114200141206a2d000021092001411f6a2d0000210a2001411d6a2f0000211f2001411c6a2d000021202001411b6a2d00002121200141196a2f00002122200141186a2d00002123200141176a2d00002124200141156a2f00002125200141146a2d00002126200141106a28020021272001410c6a2802002108200320043703b807200320073a00b7072003200c3a00b6072003200d3b01b4072003200e3a00b3072003200f3a00b207200320103b01b007200320113a00af07200320183a00ae07200320193b01ac072003201a3a00ab072003201d3a00a2072003201e3b01a00720032005410874201272200b411874723600a707200320164108742017722013411874723600a307200341c0066a41086a22024200370300200342003703c00641fae6c2004108200341c0066a100320034188086a41086a2002290300370300200320032903c00637038808200341e8086a20034188086a411010dc010240024020032d00e8084101460d00200341f0036a41186a4200370300200341f0036a41106a4200370300200341f0036a41086a4200370300200342003703f0030c010b200341f0036a41186a20034181096a290000370300200341f0036a41106a200341f9086a290000370300200341f0036a41086a200341f1086a290000370300200320032900e9083703f0030b0240200341a0076a200341f0036a412010f804450d004182e7c20021094131210a0c030b02400240200641ff01714101460d0020064118762107200641087621020c010b200341e8086a200841067610bb0120032802e80821060240024020032802f0082008413f7122024b0d004100210c0c010b200620024105746a2202290018211420022d0017210920022d0016210a20022f0014211f20022d0013212020022d0012212120022f0010212220022d000f212320022d000e212420022f000c212520022d000b2126200228000721272002280003210820022d0002210720022f000021024101210c0b024020032802ec08450d002006102e0b200c0d0041ccc4c20021094115210a0c030b200341c0066a41086a22064200370300200342003703c00641fae6c2004108200341c0066a100320034188086a41086a2006290300370300200320032903c00637038808200341e8086a20034188086a411010dc010240024020032d00e8084101460d0020034190056a4200370300200341f8046a41106a4200370300200341f8046a41086a4200370300200342003703f8040c010b20034190056a20034181096a290000370300200341f8046a41106a200341f9086a290000370300200341f8046a41086a200341f1086a290000370300200320032900e9083703f8040b200341d8046a41086a200341f8046a41086a2903002204370300200341d8046a41106a200341f8046a41106a2903002215370300200341d8046a41186a200341f8046a41186a290300221b370300200320032903f804221c3703d804200341f2086a2004370100200341fa086a201537010020034182096a201b3701002003418d023b01e8082003201c3701ea084100211941c8ecc5004100200341e8086a10722003201437038009200320093a00ff082003200a3a00fe082003201f3b01fc08200320203a00fb08200320213a00fa08200320223b01f808200320233a00f708200320243a00f608200320253b01f408200320263a00f308200320273600ef08200320083600eb08200320073a00ea08200320023b01e808200341c0066a41086a22024200370300200342003703c00641fae6c2004108200341c0066a100320034188086a41086a2002290300370300200320032903c00637038808200341103602f403200320034188086a3602f003200341e8086a200341f0036a109a02410121080b4101210b41012106410121074101210c4101210d4101210e4101210f4101211041012111410121180c290b2006102f2006102e0b41002119410121084101210b41012106410121074101210c4101210d4101210e4101210f4101211041012111410121184101211a0c330b200341e8086a200141086a41800110f6041a200341f0036a41206a200241206a290200370300200341f0036a41186a200241186a290200370300200341f0036a41106a200241106a290200370300200341f0036a41086a200241086a290200370300200320022902003703f003200341b0036a200341e8086a200341f0036a109b0220032802b403210a20032802b003210941002118410121084101210b41012106410121074101210c4101210d4101210e4101210f41012110410121110c310b200341d0036a41086a2209200141206a290300370300200341d0036a410d6a220d200141256a2900003700002003200141186a2903003703d003200241086a2802002107200241046a280200210c410e210a2001410c6a280200210820022d00002106024002400240024002400240024002400240024002400240024002400240024002400240200141086a2802000e0400010203000b200341e8086a41146a4101360200200342013702ec08200341cc91c5003602e8082003411c3602a407200341c491c5003602a0072003200341a0076a3602f808200341e8086a41d0f4c000106a000b200141386a2903002115200141306a29030021042002411a6a2901002114200241196a2d00002110200241186a2d00002111200241166a2f01002118200241156a2d00002119200241146a2d0000211a200241126a2f0100210b200241116a2d00002105200241106a2d000021122002410e6a2f010021132002410d6a2d000021162002410c6a2d00002117200241026a2f0100211d200141146a280200210f200141106a280200210e20022d0001210220034198056a41086a200929030037030020034198056a410d6a200d290000370000200320084118763a00b605200320084108763b01b405200320032903d0033703980541b5f0c2002109412a210a200641ff01710d27200241ff01714101470d272003201437038804200320103a008704200320113a008604200320183b018404200320193a0083042003201a3a0082042003200b3b018004200320053a00ff03200320123a00fe03200320133b01fc03200320163a00fb032003200c3a00f2032003201d3b01f00320032007411076410874200741087641ff0171722017411874723600f7032003200c411076410874200c41087641ff0171722007411874723600f303200341ec036a41026a220220032d00b6053a0000200320032f01b4053b01ec03200341e8086a41086a220620034198056a41086a290300370300200341e8086a410d6a220720034198056a410d6a29000037000020032003290398053703e8080240200841ff01714101460d00200341f8046a41026a20022d00003a0000200341a0066a41086a2006290300370300200341a0066a410d6a2007290000370000200320032f01ec033b01f804200320032903e8083703a0060c0f0b20034188086a200e41067610bb01200328028808210802400240200328029008200e413f7122024b0d00410021020c010b200341f8046a41026a200820024105746a220241026a2d00003a0000200341a8066a200241136a290000370300200341ad066a200241186a290000370000200320022f00003b01f8042003200229000b3703a0062002280007210f2002280003210e410121020b0240200328028c08450d002008102e0b20020d0e410121024115210f41ccc4c200210e0c0f0b41bbb7c2002109200641ff01714101470d2620074102490d26200c41ff01710d26411210292202450d03200241106a41002f00ffda403b0000200241086a41002900f7da40370000200241002900efda40370000200241124124102a2202450d0420022008360012200341f8046a41186a22084200370300200341f8046a41106a22064200370300200341f8046a41086a22074200370300200342003703f80420024116200341f8046a1000200341d8046a41186a2008290300370300200341d8046a41106a2006290300370300200341d8046a41086a2007290300370300200320032903f8043703d804200341e8086a200341d8046a10ae01024020032903e80842015222080d00200341d8046a412010060b20032802f0082106200341a0076a200341f4086a41dc0010f6041a024020080d0020034188086a200341a0076a41dc0010f6041a2002102e200341c0066a20034188086a41dc0010f6041a200320063602f003200341f0036a410472200341c0066a41dc0010f6041a200341a0036a20034190046a20032903800420034188046a290300109201200341a0036a41086a290300211520032903a0032104200341c0066a41086a22024200370300200342003703c00641c28cc0004116200341c0066a100320034188086a41086a22062002290300370300200320032903c0063703880820034188036a20034188086a10970120034188036a41106a2903002114200329039003211b200328028803210820024200370300200342003703c00641c28cc0004116200341c0066a100320062002290300370300200320032903c00637038808200342002014420020081b221420157d201b420020081b2215200454ad7d221b201520047d2204201556201b201456201b2014511b22021b3703f00820034200200420021b3703e80820034188086a4110200341e8086a411010040c250b2002102e0c010b41bbb7c2002109200641ff01714101470d2520074104490d25200c41ff01710d25411210292202450d04200241106a41002f00ffda403b0000200241086a41002900f7da40370000200241002900efda40370000200241124124102a2202450d0520022008360012200341f8046a41186a22064200370300200341f8046a41106a22074200370300200341f8046a41086a22094200370300200342003703f80420024116200341f8046a1000200341d8046a41186a2006290300370300200341d8046a41106a2007290300370300200341d8046a41086a2009290300370300200320032903f8043703d804200341d8046a412041c8ecc50041004100100521062002102e2006417f470d010b41faf4c00021094119210a410121084101210b0c340b200341c0066a41086a22024200370300200342003703c00641ae98c5004112200341c0066a100320034188086a41086a2002290300370300200320032903c00637038808200341003602e80820034188086a4110200341e8086a1008210620032802e8082207417f460d052006450d05200320073602f403200320063602f003200341e8086a200341f0036a104120032802e808220f450d04200341f0086a280200210220032802ec08210e02402007450d002006102e0b2002200e470d070c060b41124101102c000b41244101102c000b41124101102c000b41244101102c000b41eff0c200413320034198056a4184f4c2001053000b4100210e4104210f0b200e41016a2202200e490d0b200e4101742206200220022006491b220641ffffffff03712006470d0b200641027422024100480d0b02400240200e0d0020021029210f0c010b200f200e4102742002102a210f0b200f450d01200e21022006210e0b200f200241027422076a2008360200200341c0066a41086a22084200370300200342003703c00641ae98c5004112200341c0066a100320034188086a41086a2008290300370300200320032903c00637038808200341003602f008200342013703e808200241016a2208200341e8086a104702400240200820024f0d0020032802f008210a20032802ec08210920032802e80821080c010b410020032802f00822026b2106200741046a210c20032802ec082109200f210703402007280200210d02400240200920066a4104490d0020032802e80821080c010b200241046a22082002490d0d2009410174220a20082008200a491b220a4100480d0d0240024020090d00200a102921080c010b20032802e8082009200a102a21080b2008450d042003200a3602ec08200320083602e808200a21090b200741046a21072003200241046a220a3602f008200820026a200d3600002006417c6a2106200a2102200c417c6a220c0d000b0b20034188086a41102008200a100402402009450d002008102e0b41002109200e450d1a200f102e0c1a0b20024104102c000b200a4101102c000b200341d8046a41026a200341f8046a41026a2d00003a0000200341c0066a41086a200341a0066a41086a290300370300200341c0066a410d6a200341a0066a410d6a290000370000200320032f01f8043b01d804200320032903a0063703c006410021020b200341bc056a41026a2208200341d8046a41026a2d00003a0000200341c0056a41086a2206200341c0066a41086a290300370300200341c0056a41106a200341c0066a41106a290300370300200320032f01d8043b01bc05200320032903c0063703c00502402002450d00200f210a200e2109410121084101210b0c280b200341f0026a2004201542c0843d420010fc04200341e0026a20032903f0022214200341f0026a41086a290300221b42c0fb42427f10fb04200341d0026a2014201b42d08603420010fb04200341b8056a41026a20082d00003a0000200341a0076a41086a2006290300370300200341a0076a410d6a2208200341c0056a410d6a290000370000200320032f01bc053b01b805200320032903c0053703a00720034180036a200341f0036a20032903d002221b200420032903e0027c42148042ffffffff0f837c2214428080e983b1de162014428080e983b1de1656200341d0026a41086a2903002014201b54ad7c22144200522014501b22021b221b2014420020021b22141093010240200328028003450d0041e0f4c0002109411a210a410121084101210b0c280b200341c8026a419898c5004116107d20032802cc02210220032802c8022106200341c0066a41086a22074200370300200342003703c006419898c5004116200341c0066a100320034188086a41086a2007290300370300200320032903c0063703880820032002410020061b220941016a3602e80820034188086a4110200341e8086a41041004200341a0096a200341f0036a41186a29030037030020034198096a200341f0036a41106a29030037030020034190096a200341f0036a41086a290300370300200341aa096a200341ba056a2d00003a0000200341af096a200f360000200341ab096a200e360000200341b3096a20032903a007370000200341bb096a200341a0076a41086a290300370000200341c0096a2008290000370000200320153703f008200320043703e808200320032903f00337038809200320032f01b8053b01a809200341e8086a41186a20143703002003201b3703f8080240024002400240411210292202450d00200241106a41002f00ffda403b0000200241086a41002900f7da40370000200241002900efda40370000200241124124102a2206450d0120062009360012200341f8046a41186a22024200370300200341f8046a41106a22084200370300200341f8046a41086a22074200370300200342003703f80420064116200341f8046a1000200341d8046a41186a2002290300370300200341d8046a41106a2008290300370300200341d8046a41086a2007290300370300200320032903f8043703d8042003410036029008200342013703880820034188096a20034188086a104a200341e8086a41086a290300210420032903e808211402400240200328028c08220820032802900822026b4110490d0020032802880821080c010b200241106a22072002490d0b20084101742202200720072002491b22024100480d0b0240024020080d002002102921080c010b20032802880820082002102a21080b2008450d032003200236028c08200320083602880820032802900821020b200820026a22082004370008200820143700002003200241106a36029008200341a8096a20034188086a104a20034180096a290300210420032903f808211402400240200328028c08220720032802900822086b4110490d0020032802880821020c010b200841106a22022008490d0b20074101742208200220022008491b220a4100480d0b0240024020070d00200a102921020c010b2003280288082007200a102a21020b2002450d042003200a36028c0820032002360288082003280290082108200a21070b200220086a220a2004370008200a2014370000200341d8046a41202002200841106a100402402007450d002002102e0b2006102e200341f4086a200936020041002109200341f0086a41003a00002003410b3a00e80841c8ecc5004100200341e8086a10720c1a0b41124101102c000b41244101102c000b20024101102c000b200a4101102c000b200141086a2802002106200141046a28020021070240024020022d00000d004101210820022d000141ff01714101460d010b41b5f0c2002109412a210a41002111410121082006450d022007102e0c020b200241096a280000210a02402006450d002007102e0b410021114101210b41012106410121074101210c4101210d4101210e4101210f410121100b41012118410121194101211a410021090c2f0b4101210b41012106410121074101210c4101210d4101210e4101210f410121100c2c0b41e9efc20021094124210a4101210820022d00000d0020022d000141ff01714102470d00200141046a2802002102200341c0066a41086a22064200370300200342003703c00641fbd8c0004110200341c0066a100320034188086a41086a2006290300370300200320032903c00637038808024020034188086a411041c8ecc500410041001005417f470d00200341c0026a41b0f3c200410d107d024020032802c402410020032802c0021b2002490d00200341c0066a41086a22064200370300200342003703c00641fbd8c0004110200341c0066a100320034188086a41086a2006290300370300200320032903c00637038808200320023602e80820034188086a4110200341e8086a41041004410021094101210b0c250b41b4dac0001058000b41a0d9c0001058000b4101210b0c220b200341d8046a41026a2209200141076a2d00003a0000200341f0036a41086a220a2001411c6a290200370300200341f0036a41106a220d200141246a290200370300200341f0036a41186a2001412c6a29020037030020034190046a200141346a29020037030020034198046a2001413c6a290200370300200341a0046a200141c4006a2d00003a00002003200141056a2f00003b01d8042003200141146a2902003703f003200141086a28020021062001410c6a2802002107200141106a280200210820022f0001200241036a2d000041107472210e2002410c6a280200210f200241086a2802002110200241046a280200211120022d00002102024002400240024002400240024002400240024002400240024002400240200141046a2d0000220c0e050001020304000b200341e8086a41146a4101360200200342013702ec08200341cc91c5003602e8082003411c3602a407200341c491c5003602a0072003200341a0076a3602f808200341e8086a419cb4c200106a000b200341b7076a200a290300370000200341bf076a200d2d00003a0000200320032f01d8043b01a007200320083600ab07200320073600a707200320063600a307200320032903f0033700af07200320092d00003a00a207024002402002417f6a220841024b0d00024020080e03000102000b2010410174200f4d0d00201141ff0171450d010b2002200e7241ff0171450d0041d7b4c2002109410a210a410021080c130b200341c0066a41086a22024200370300200342003703c00641acb4c200411b200341c0066a1003200341e8086a41086a2002290300370300200320032903c0063703e8082003410036028808200341e8086a411020034188086a100821020240024002402003280288082208417f460d002002450d00200320083602c406200320023602c00620034188086a200341c0066a1030200328028808220a450d06200329028c08210402402008450d002002102e0b2003200a360288082003200437028c082004a7210e41002102024002402004422088a7220f41014b0d0041002109200f0e020301030b200f210803402008410176220920026a220d2002200a200d4105746a200341a0076a412010f8044101481b2102200820096b220841014b0d000b0b0240200a20024105746a200341a0076a412010f8042208450d002008411f7620026a2109200f21020c020b41c7b4c2002109200e450d02200a102e0c020b4100210e200341003602900820034201370388084101210a41002102410021090b200341e8086a41186a200341a0076a41186a290300370300200341e8086a41106a200341a0076a41106a290300370300200341e8086a41086a200341a0076a41086a290300370300200320032903a0073703e80802400240024020022009490d002002200e460d01200e210d0c020b41c0c6c5001058000b200e41016a2208200e490d0f200e410174220d20082008200d491b220d41ffffff3f71200d470d0f200d41057422084100480d0f02400240200e0d0020081029210a0c010b200a200e4105742008102a210a0b200a450d062003200d36028c082003200a360288080b200a20094105746a220841206a2008200220096b41057410f7041a200820032903e808370000200841186a200341e8086a41186a2209290300370000200841106a200341e8086a41106a220a290300370000200841086a200341e8086a41086a22082903003700002003200241016a3602900820034188086a109c022009200341a0076a41186a290300370300200a200341a0076a41106a2903003703002008200341a0076a41086a290300370300200320032903a0073703e8084100210941c8ecc50041002003280288082202200328029008109d02200341093b01e80841c8ecc5004100200341e8086a1072200d450d002002102e0b4110210a410021080c120b200341b7076a200a290300370000200341bf076a200d2d00003a0000200320032f01d8043b01a007200320083600ab07200320073600a707200320063600a307200320032903f0033700af07200320092d00003a00a207024002402002417f6a220841024b0d00024020080e03000102000b2010410174200f4d0d00201141ff0171450d010b2002200e7241ff0171450d0041d7b4c2002109410a210a410021080c120b200341c0066a41086a22024200370300200342003703c00641acb4c200411b200341c0066a1003200341e8086a41086a2002290300370300200320032903c0063703e8082003410036028808200341e8086a411020034188086a100821022003280288082208417f460d052002450d05200320083602c406200320023602c00620034188086a200341c0066a1030200328028808220d450d04200329028c08210402402008450d002002102e0b2003200d360288082003200437028c082004a7210f41002102024002400240024002402004422088a7220e41014b0d00200e0e020201020b200e210803402008410176220920026a220a2002200d200a4105746a200341a0076a412010f8044101481b2102200820096b220841014b0d000b0b200d20024105746a200341a0076a412010f804450d010b41e1b4c2002109200f0d010c120b2002200e4f0d07200d20024105746a2208200841206a2002417f73200e6a41057410f7041a2003200e417f6a22023602900820034188086a109c02200341e8086a41186a200341a0076a41186a290300370300200341e8086a41106a200341a0076a41106a290300370300200341e8086a41086a200341a0076a41086a290300370300200320032903a0073703e808200341e8086a4101200d2002109d0220034189023b01e8084100210941c8ecc5004100200341e8086a1072200f450d110b200d102e0c100b2003419f086a200a290300370000200341a7086a200d2d00003a0000200320032f01d8043b01880820032008360093082003200736008f082003200636008b08200320032903f00337009708200320092d00003a008a08200341a0076a41186a20034199046a290000370300200341a0076a41106a20034191046a290000370300200341a0076a41086a20034189046a29000037030020032003290081043703a007024002402002417f6a220841024b0d00024020080e03000102000b2010410174200f4d0d00201141ff0171450d010b2002200e7241ff0171450d0041d7b4c2002109410a210a410021080c110b0240024020034188086a200341a0076a412010f8040d00410021090c010b200341c0066a41086a22024200370300200342003703c00641acb4c200411b200341c0066a1003200341e8086a41086a2002290300370300200320032903c0063703e808200341003602c006200341e8086a4110200341c0066a1008210220032802c0062208417f460d082002450d08200320083602a406200320023602a006200341c0066a200341a0066a103020032802c006220f450d0720032902c406210402402008450d002002102e0b2003200f3602c005200320043702c4052004a7211141e1b4c2002109410c210a41002102024002402004422088a7221041014b0d0020100e021001100b2010210803402008410176220d20026a220e2002200f200e4105746a20034188086a412010f8044101481b21022008200d6b220841014b0d000b0b200f20024105746a220820034188086a412010f8040d0e200341f8046a41186a2209200341a0076a41186a290300370300200341f8046a41106a220a200341a0076a41106a290300370300200341f8046a41086a220d200341a0076a41086a290300370300200320032903a0073703f804200220104f0d09200820032903f804370000200841186a2009290300370000200841106a200a290300370000200841086a200d2903003700004101210841002102024020104101460d00410021022010210803402008410176220920026a220a2002200f200a4105746a200341a0076a412010f8044101481b2102200820096b220841014b0d000b201021080b0240200f20024105746a200341a0076a412010f8040d0041c7b4c20021094110210a0c0f0b200f2008105d200341c0056a109c02200341e8086a41186a20034188086a41186a290300370300200341e8086a41106a20034188086a41106a290300370300200341e8086a41086a20034188086a41086a29030037030020032003290388083703e808200341e8086a4101200f2010109d0220034189043b01e8084100210941c8ecc5004100200341e8086a10722011450d00200f102e0b0c0e0b024002402002417f6a220941024b0d00024020090e03000102000b2010410174200f4d0d00201141ff0171450d010b2002200e7241ff0171450d00410a210a41d7b4c200210920070d110c120b20062008105d200341c0066a41086a22024200370300200342003703c00641acb4c200411b200341c0066a1003200341e8086a41086a2002290300370300200320032903c0063703e808200341003602a007200341e8086a4110200341a0076a1008210220032802a0072209417f460d092002450d092003200936028c082003200236028808200341a0076a20034188086a103020032802a007220a450d08200341a8076a280200210d20032802a407210e02402009450d002002102e0b20062008200a200d109e02200e450d0b200a102e0c0b0b41eff0c200413320034198056a4184f4c2001053000b20084101102c000b41eff0c200413320034198056a4184f4c2001053000b2003410036029008200342013703880841e1b4c20021090c0a0b418080c0001058000b41eff0c200413320034198056a4184f4c2001053000b200341003602c805200342013703c005410c210a41e1b4c2002109410021080c080b41f0b4c200200220101038000b41eff0c200413320034198056a4184f4c2001053000b2006200841014100109e020c010b102d000b200341c0066a41086a22024200370300200342003703c00641acb4c200411b200341c0066a100320034188086a41086a2002290300370300200320032903c00637038808200341003602f008200342013703e8082008200341e8086a104702402008450d00200841057421082006210203402002200341e8086a104a200241206a2102200841606a22080d000b0b20032802ec08210220034188086a411020032802e808220820032802f008100402402002450d002008102e0b02402007450d002006102e0b20034189063b01e8084100210941c8ecc5004100200341e8086a1072410121080c030b2011450d00200f102e410021080c020b410021080c010b410c210a410021080b0240200c417f6a220241034b0d00024020020e0403030300030b200820074572450d010c020b200c4104490d012007450d010b2006102e0b41002110410121084101210b41012106410121074101210c4101210d4101210e4101210f0c200b200341e8086a41386a200141c0006a290300370300200341e8086a41306a200141386a290300370300200341e8086a41286a200141306a290300370300200341e8086a41206a200141286a290300370300200341e8086a41186a200141206a290300370300200341e8086a41106a200141186a290300370300200341e8086a41086a200141106a2903003703002003200141086a2903003703e808200341f0036a41206a200241206a290200370300200341f0036a41186a200241186a290200370300200341f0036a41106a200241106a290200370300200341f0036a41086a200241086a290200370300200320022902003703f003200341b8026a200341e8086a200341f0036a10d90120032802bc02210a20032802b80221094100210f410121084101210b41012106410121074101210c4101210d4101210e0c1e0b200341f0036a41206a200141246a290200370300200341f0036a41186a2001411c6a290200370300200341f0036a41106a200141146a290200370300200341f0036a41086a2001410c6a2902003703002003200141046a2902003703f003200341e8086a41206a200241206a290200370300200341e8086a41186a200241186a290200370300200341e8086a41106a200241106a290200370300200341e8086a41086a200241086a290200370300200320022902003703e808200341b0026a200341f0036a200341e8086a109f0220032802b402210a20032802b00221094100210e410121084101210b41012106410121074101210c4101210d0c1c0b200341f0036a41206a200141246a290200370300200341f0036a41186a2001411c6a290200370300200341f0036a41106a200141146a290200370300200341f0036a41086a2001410c6a2902003703002003200141046a2902003703f003200341e8086a41206a200241206a290200370300200341e8086a41186a200241186a290200370300200341e8086a41106a200241106a290200370300200341e8086a41086a200241086a290200370300200320022902003703e808200341a8026a200341f0036a200341e8086a10a00220032802ac02210a20032802a80221094100210d410121084101210b41012106410121074101210c0c1a0b200341e8086a41286a200141306a290300370300200341e8086a41206a200141286a290300370300200341e8086a41186a200141206a290300370300200341e8086a41106a200141186a290300370300200341e8086a41086a200141106a2903003703002003200141086a2903003703e808200341f0036a41206a200241206a290200370300200341f0036a41186a200241186a290200370300200341f0036a41106a200241106a290200370300200341f0036a41086a200241086a290200370300200320022902003703f003200341a0026a200341e8086a200341f0036a10a10220032802a402210a20032802a00221094100210c410121084101210b41012106410121070c180b200141086a280200211a200141046a280200210b200341e8086a2001410c6a41e40010f6041a2002411a6a2901002104200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002118200241106a2d000021192002410e6a2f010021052002410d6a2d000021122002410c6a2d000021132002410a6a2f01002116200241096a2d00002117200241086a2d0000211d200241066a2f0100211e200241056a2d0000211f200241046a2d00002120200241026a2f0100212120022d0001210a20022d00002107200341c0056a200341e8086a41046a41e00010f6041a4101210241b5f0c200210941002108412a2106024002402007450d00410021070c010b41002107200a41ff01714101470d00201e410874201f72201d411874722109410021022017210620162108201321070b200841ffff0371410874200641ff017172200741187472210a0240024020020d00200320043703a0082003200c3a009f082003200d3a009e082003200e3b019c082003200f3a009b08200320103a009a08200320113b019808200320183a009708200320193a009608200320053b019408200320123a0093082003200a36008f082003200936008b08200320203a008a08200320213b018808200341f0036a20034188086a10830202400240024002402003280290042202450d00200341a0076a41106a200341a8046a290300370300200341a0076a41086a200341a0046a290300370300200341a0076a41186a200341b0046a290300370300200341c0076a200341b8046a280200360200200341f8046a41086a2208200341ac076a290200370300200341f8046a41106a2206200341b4076a290200370300200341f8046a41186a2207200341bc076a290200370300200320034198046a2903003703a007200320032902a4073703f8040240200328029404450d002002102e0b200341a0066a41086a2008290300370300200341a0066a41106a2006290300370300200341a0066a41186a2007290300370300200320032903f8043703a006200341c0066a200341c0056a41e00010f6041a200341f8046a200341a0066a107720032802f80421022003280280052108200341003602f00320022008200341f0036a1008210820032802f0032206417f460d022008450d02200320063602dc04200320083602d804200341f0036a200341d8046a107820032d00f0034101460d0120034188086a200341f0036a41017241e00010f6041a02402006450d002008102e0b200341f0036a20034188086a41e00010f6041a200341013a00a007200341a0076a410172200341f0036a41e00010f6041a0c030b41a19ac20021094127210a0c030b41eff0c200413320034198056a4184f4c2001053000b200341003a00a0070b024020032802fc04450d002002102e0b200341c1076a2105200341e1076a2112200341c0066a41206a211820034180076a2119200341a0076a4101722113200341f0036a410172210a4104210941e7e485f30621080240024003400240024002400240200841e9dabdf30646220e0d000240200841e7e485f306470d00200341c0066a21070c020b200841e2c289ab06470d02201821070c010b201921070b0240412010292206450d0020062007290000370000200641186a200741186a290000370000200641106a200741106a290000370000200641086a200741086a290000370000412021024100210c0c020b41204101102c000b4101210c41c8ecc500210741002102410121060b200320023602940820032002360290082003200636028c082003200836028808200341f8046a20034188086a1079200341f0036a20032802f804220d20032802800510dc010240024020032d00f0034101470d00200341d8046a41186a220f200a41186a290000370300200341d8046a41106a2210200a41106a290000370300200341d8046a41086a2211200a41086a2900003703002003200a2900003703d804024020032802fc04450d00200d102e0b02402002450d002006102e0b200341f0036a41186a200f290300370300200341f0036a41106a2010290300370300200341f0036a41086a2011290300370300200320032903d8043703f003200341f0036a200341a0066a412010f804450d0141c89ac20021094118210a0c050b024020032802fc04450d00200d102e0b2002450d002006102e0b0240024020032d00a0074101470d00024002400240200841e2c289ab06460d00200e0d010240200841e7e485f306460d004100210641c8ecc500210e0c030b412021062013210e0c020b412021062005210e0c010b412021062012210e0b024020022006470d002007200e460d022007200e200210f804450d020b0240024020060d004101210d0c010b20061029220d450d04200d200e200610f6041a0b200320063602fc03200320063602f8032003200d3602f403200320083602f00320034188086a200341f0036a1079200328028808220e20032802900810060240200328028c08450d00200e102e0b2006450d00200d102e0b410121060240200c0d00200210292206450d0420062007200210f6041a0b200320023602fc03200320023602f803200320063602f403200320083602f00320034188086a200341f0036a1079200328028808210820032003280290083602fc04200320083602f804200341a0066a200341f8046a109a020240200328028c08450d002008102e0b2002450d002006102e0b02402009410c460d002009418cd8c1006a2800002108200941046a21090c010b0b20034188086a200341a0066a107720032802900821082003280288082102200341003602f803200342013703f003200341c0066a200341f0036a104a2018200341f0036a104a2019200341f0036a104a20032802f40321062002200820032802f003220720032802f803100402402006450d002007102e0b0240200328028c08450d002002102e0b200341013a00f003200341c0066a41086a22024200370300200342003703c00641ccdfc500410f200341c0066a100320034188086a41086a2002290300370300200320032903c0063703880820034188086a4110200341f0036a41011004410021090240201a450d00200b102e0b0c030b20064101102c000b20024101102c000b201a450d00200b102e0b41002107410121084101210b410121060c160b200341e8086a41306a200141386a290300370300200341e8086a41286a200141306a290300370300200341e8086a41206a200141286a290300370300200341e8086a41186a200141206a290300370300200341e8086a41106a200141186a290300370300200341e8086a41086a200141106a2903003703002003200141086a2903003703e808200341f0036a41206a200241206a290200370300200341f0036a41186a200241186a290200370300200341f0036a41106a200241106a290200370300200341f0036a41086a200241086a290200370300200320022902003703f00320034198026a200341e8086a200341f0036a10a202200328029c02210a200328029802210941002106410121084101210b0c140b200341cc036a41026a22062001410f6a2d00003a0000200341d0036a41086a2207200141206a290300370300200341d0036a410d6a2209200141256a29000037000020032001410d6a2f00003b01cc032003200141186a2903003703d003200141386a2903002114200141306a2903002104200141146a280200210d200141106a28020021082001410c6a2d0000210e20022d0001210c20022d0000210a0240024002400240024002400240200141086a2802000e03000102000b200341e8086a41146a4101360200200342013702ec08200341cc91c5003602e8082003411c3602a407200341c491c5003602a0072003200341a0076a3602f808200341e8086a41d4b4c000106a000b2002411a6a2901002115200241196a2d0000210f200241186a2d00002110200241166a2f01002111200241156a2d00002118200241146a2d00002119200241126a2f0100211a200241116a2d0000210b200241106a2d000021052002410e6a2f010021122002410d6a2d000021132002410c6a2d000021162002410a6a2f01002117200241096a2d0000211d200241086a2d0000211e200241066a2f0100211f200241056a2d00002120200241046a2d00002121200241026a2f01002122200341bc056a41026a20062d00003a000020034198056a41086a200729030037030020034198056a410d6a2009290000370000200320032f01cc033b01bc05200320032903d003370398054101210241b5f0c200210941002106412a210702400240200a41ff0171450d004100210a0c010b4100210a200c41ff01714101470d00201f410874202072201e41187472210941002102201d2107201721062016210a0b200641ffff0371410874200741ff017172200a41187472210a20020d07200320153703b8072003200f3a00b707200320103a00b607200320113b01b407200320183a00b307200320193a00b2072003201a3b01b0072003200b3a00af07200320053a00ae07200320123b01ac07200320133a00ab072003200a3600a707200320093600a307200320213a00a207200320223b01a007200341ec036a41026a2202200341bc056a41026a2d00003a0000200320032f01bc053b01ec03200341e8086a41086a20034198056a41086a290300370300200341e8086a410d6a220620034198056a410d6a29000037000020032003290398053703e8080240200e41ff01714101460d00200341f8046a41026a20022d00003a0000200341a0066a41086a200341e8086a41086a290300370300200341a0066a410d6a2006290000370000200320032f01ec033b01f804200320032903e8083703a0060c020b200341c0056a200841067610bb0120032802c00521060240024020032802c8052008413f7122024b0d00410021020c010b200341f8046a41026a200620024105746a220241026a2d00003a0000200341a8066a200241136a290000370300200341ad066a200241186a290000370000200320022f00003b01f8042003200229000b3703a0062002280007210d20022800032108410121020b024020032802c405450d002006102e0b20020d01410121024115210d41ccc4c20021080c020b200141c8006a2903002115200141c0006a290300211b200341a0076a41086a2007290300370300200341a0076a410d6a2009290000370000200320032f01cc033b01b405200320032903d0033703a007200320062d00003a00b6050240200c200a7241ff0171450d00418df0c20021094128210a410121084101210b0c170b200341ec036a41026a220220032d00b6053a0000200341e8086a41086a2206200341a0076a41086a290300370300200341e8086a410d6a2207200341a0076a410d6a290000370000200320032f01b4053b01ec03200320032903a0073703e808024002400240200e41ff01714101460d00200341f8046a41026a20022d00003a0000200341a0066a41086a2006290300370300200341a0066a410d6a2007290000370000200320032f01ec033b01f804200320032903e8083703a0060c010b200341f0036a200841067610bb0120032802f00321060240024020032802f8032008413f7122024b0d00410021020c010b200341f8046a41026a200620024105746a220241026a2d00003a0000200341a8066a200241136a290000370300200341ad066a200241186a290000370000200320022f00003b01f8042003200229000b3703a0062002280007210d20022800032108410121020b024020032802f403450d002006102e0b20020d004101210241ccc4c20021084115210d0c010b200341bc056a41026a200341f8046a41026a2d00003a0000200341c0056a41086a200341a0066a41086a290300370300200341c0056a410d6a200341a0066a410d6a290000370000200320032f01f8043b01bc05200320032903a0063703c005410021020b200341b8056a41026a2206200341bc056a41026a2d00003a000020034188086a41086a2207200341c0056a41086a29030037030020034188086a41106a200341c0056a41106a290300370300200320032f01bc053b01b805200320032903c0053703880820020d02200341fb086a200729030037000020034180096a20034195086a290000370000200320032f01b8053b01e8082003200d3600ef08200320083600eb0820032003290388083700f308200320062d00003a00ea080240024002400240411410292202450d00200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702f403200320023602f003200341e8086a200341f0036a104a20032802f403210220034180026a20032802f003220620032802f803106e20034180026a41106a290300420020032802800222081b211c200329038802420020081b212802402002450d002006102e0b20282004542208201c201454201c20145122021b0d012028200456201c20145620021b450d03200341e8016a41c28cc00041161070200341f8016a290300212920032903f001212a20032802e8012102200341c0066a41086a22064200370300200342003703c00641c28cc0004116200341c0066a100320034188086a41086a2006290300370300200320032903c00637038808200342002029420020021b22292008ad2014201c7d7c7c202a420020021b221c202820047d222a54ad7d2228201c202a7d222a201c56202820295620282029511b22021b3703f80320034200202a20021b3703f003200341f0036a21020c020b41144101102c000b200341d0016a41c28cc00041161070200341e0016a290300212920032903d801212a20032802d0012102200341c0066a41086a22084200370300200342003703c00641c28cc0004116200341c0066a100320034188086a41086a2008290300370300200320032903c006370388082003427f2029420020021b22292014201c7d2004202854ad7d7c202a420020021b221c200420287d7c2228201c542202ad7c221c2002201c202954201c2029511b22021b3703f8032003427f202820021b3703f003200341f0036a21020b20034188086a41102002411010040b200341e8086a2004201410730240024002400240411810292202450d00200241002900ec8c40370000200241106a41002900fc8c40370000200241086a41002900f48c403700002003429880808080033702f403200320023602f003200341e8086a200341f0036a104a20032802f4032102200341b8016a20032802f003220620032802f803106e200341b8016a41106a290300420020032802b80122081b210420032903c001420020081b211402402002450d002006102e0b2014201b5422082004201554200420155122021b0d012014201b56200420155620021b450d03200341a0016a41c28cc00041161070200341b0016a290300211c20032903a801212820032802a0012102200341c0066a41086a22064200370300200342003703c00641c28cc0004116200341c0066a100320034188086a41086a2006290300370300200320032903c0063703880820034200201c420020021b221c2008ad201520047d7c7c2028420020021b22042014201b7d222854ad7d2214200420287d22282004562014201c562014201c511b22021b3703f80320034200202820021b3703f003200341f0036a21020c020b41184101102c000b20034188016a41c28cc0004116107020034198016a290300211c20032903900121282003280288012102200341c0066a41086a22084200370300200342003703c00641c28cc0004116200341c0066a100320034188086a41086a2008290300370300200320032903c006370388082003427f201c420020021b221c201520047d201b201454ad7d7c2028420020021b2204201b20147d7c22142004542202ad7c220420022004201c542004201c511b22021b3703f8032003427f201420021b3703f003200341f0036a21020b20034188086a41102002411010040b200341e8086a201b2015108c010c040b200341d8046a41026a200341f8046a41026a2d00003a0000200341c0066a41086a200341a0066a41086a290300370300200341c0066a410d6a200341a0066a410d6a290000370000200320032f01f8043b01d804200320032903a0063703c006410021020b200341b8056a41026a2206200341d8046a41026a2d00003a000020034188086a41086a2207200341c0066a41086a29030037030020034188086a41106a200341c0066a41106a290300370300200320032f01d8043b01b805200320032903c006370388082002450d010b200d210a20082109410121084101210b0c130b20034183046a200729030037000020034188046a20034195086a290000370000200320032f01b8053b01f0032003200d3600f703200320083600f30320032003290388083700fb03200320062d00003a00f203411410292202450d03200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702ec08200320023602e808200341a0076a200341e8086a104a20032802ec082102200341f0006a20032802e808220620032802f008106e200341f0006a41106a290300211b200328027021082003290378211c02402002450d002006102e0b411410292202450d04200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702ec08200320023602e808200341f0036a200341e8086a104a20032802ec082102200341d8006a20032802e808220620032802f008106e200341d8006a41106a2903002129200328025821072003290360212a02402002450d002006102e0b024020044280a094a58d1d7c2215200454220220142002ad7c2228201454201520045a1b450d004128210a41aeb5c0002109410121084101210b0c130b0240201c420020081b221c20157d222b201c56201b420020081b221b20287d201c201554ad7d2215201b562015201b511b450d00411d210a4191b5c0002109410121084101210b0c130b2029420020071b211b202a420020071b211c0240200442ffffe883b1de165620144200522014501b0d00201c201b8450450d00411f210a41d6b5c0002109410121084101210b0c130b200341d0006a200341a0076a4102202b201510560240200328025022090d000240201c20047c2228201c542202201b20147c2002ad7c221c201b54201c201b511b450d00412d210a41e4b4c0002109410121084101210b0c140b200341a0076a200341f0036a412010f804450d01200341a0076a202b20151073411410292202450d06200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702ec08200320023602e808200341f0036a200341e8086a104a20032802ec08210820032802f008210620032802e8082102200341f8046a41186a22074200370300200341f8046a41106a22094200370300200341f8046a41086a220a4200370300200342003703f80420022006200341f8046a1000200341d8046a41186a2007290300370300200341d8046a41106a2009290300370300200341d8046a41086a200a290300370300200320032903f8043703d804200341d8046a412041c8ecc500410041001005210602402008450d002002102e0b02402006417f470d00200341f0036a1071200341a0096a201c37030020034198096a2028370300200341e8086a41086a41003a0000200341f1086a20032903f003370000200341f9086a200341f0036a41086a29030037000020034181096a20034180046a29030037000020034189096a20034188046a290300370000200341023a00e80841c8ecc5004100200341e8086a10720b200341f0036a2028201c1073200341386a41c28cc00041161070200341386a41106a29030021152003290340211b20032802382102200341c0066a41086a22084200370300200342003703c00641c28cc0004116200341c0066a100320034188086a41086a2008290300370300200320032903c00637038808200342002015420020021b221c201b420020021b22154280a094a58d1d54ad7d221b20154280e0ebdaf2627c2228201556201b201c56201542ff9f94a58d1d561b22021b3703f00820034200202820021b3703e80820034188086a4110200341e8086a41101004200341d0096a4200370300200341c8096a4280a094a58d1d370300200341c0096a2014370300200341b8096a2004370300200341e8086a41086a41023a0000200341f1086a20032903a007370000200341f9086a200341a0076a41086a29030037000020034181096a200341a0076a41106a29030037000020034189096a200341a0076a41186a29030037000020034191096a20032903f00337000020034199096a200341f0036a41086a290300370000200341a1096a200341f0036a41106a290300370000200341a9096a200341f0036a41186a290300370000200341023a00e80841c8ecc5004100200341e8086a10720c010b2003280254210a410121084101210b0c120b410021090b0b410121084101210b0c0f0b41144101102c000b41144101102c000b41144101102c000b10a302000b024020032802f4082208450d0020032802ec082102200841246c210803400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022008415c6a22080d000b0b024020032802f008450d0020032802ec08102e0b02402007200d460d0003402007280204220e450d01200741086a280200210f02402007410c6a2802002202450d00200241246c2108200e210203400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022008415c6a22080d000b0b200741f0006a21070240200f450d00200e102e0b2007200d470d000b0b02402005450d002010102e0b4100210b410121082004a7450d0a200c102e0c0a0b2007200d460d00034020072802042209450d01200741086a280200210a02402007410c6a2802002202450d00200241246c21082009210203400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022008415c6a22080d000b0b200741f0006a21070240200a450d002009102e0b2007200d470d000b0b02402005450d002010102e0b200341c0066a41086a22024200370300200342003703c006419893c2004111200341c0066a100320034188086a41086a2002290300370300200320032903c00637038808200341e8086a200c2004422088a710a40220034188086a411020032802e808220220032802f0081004024020032802ec08450d002002102e0b4101210802402004a70d004100210b0c060b200c102e4100210b0c050b02402008450d002010200841f0006c6a210c20102107034002402007410c6a2802002208450d0020072802042102200841246c210803400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022008415c6a22080d000b0b200741f0006a21020240200741086a280200450d002007280204102e0b200221072002200c470d000b0b4100210b410121082005450d072010102e0c070b41002112410021090c010b41002113410021090b4128210a4101210b4100210802402007417f6a220241054b0d0041012106410121074101210c4101210d4101210e4101210f410121104101211141012118410121194101211a024002400240024020020e06130013010203130b4100210841000d082004a70d070c080b4100210841000d072004a70d060c070b2013450d0602402004422088a72202450d00200241186c21062005210203400240200241046a280200450d002002280200102e0b0240200241106a280200450d002002410c6a280200102e0b200241186a2102200641686a22060d000b0b2004a70d050c060b2012450d0502402004422088a72202450d002002410c6c21062005210203400240200241046a280200450d002002280200102e0b2002410c6a2102200641746a22060d000b0b2004a70d040c050b02402004422088a72202450d002002410c6c21062005210203400240200241046a280200450d002002280200102e0b2002410c6a2102200641746a22060d000b0b2004a70d030c040b410021080b41012106410121074101210c4101210d4101210e4101210f410121104101211141012118410121190b4101211a410021090c0b0b2005102e0b410121060b410121070b4101210c0b4101210d0b4101210e0b4101210f0b410121100b410121110b410121180b410121194101211a0b0240024020012d0000220241114b0d0002400240024002400240024002400240024002400240024020020e12000d0d010d0d020304050607080d090d0a0b000b2008450d0c0240200141086a280200220241054b0d0002400240024020020e06101000100102100b200141106a280200450d0f2001410c6a280200102e0c0f0b200141106a280200450d0e2001410c6a280200102e0c0e0b0240200141146a2802002208450d002001410c6a2802002102200841186c210803400240200241046a280200450d002002280200102e0b0240200241106a280200450d002002410c6a280200102e0b200241186a2102200841686a22080d000b0b200141106a280200450d0d200128020c102e0c0d0b0240200141146a2802002208450d002001410c6a28020021022008410c6c210803400240200241046a280200450d002002280200102e0b2002410c6a2102200841746a22080d000b0b200141106a280200450d0c200128020c102e0c0c0b200b450d0b02402001410c6a2802002202450d00200141046a2802002207200241f0006c6a210c034002402007410c6a2802002208450d0020072802042102200841246c210803400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022008415c6a22080d000b0b200741f0006a21020240200741086a280200450d002007280204102e0b200221072002200c470d000b0b200141086a280200450d0b2001280204102e0c0b0b2006450d0a0240200141086a2d00002202410d4b0d0020024106470d0b200141106a280200450d0b2001410c6a280200102e0c0b0b200141106a280200450d0a2001410c6a280200102e0c0a0b2007450d09200141086a280200450d09200141046a280200102e0c090b200c450d08200141086a2d0000417f6a220241074b0d08024002400240024020020e08000c0c0c0c010203000b2001410c6a2202280200102f2002280200102e0c0b0b2001410c6a2202280200102f2002280200102e0c0a0b2001410c6a2202280200102f2002280200102e0c090b2001410c6a2202280200102f2002280200102e0c080b200d450d07200141046a2d0000417f6a220241024b0d0702400240024020020e03000102000b2001410c6a280200450d09200141086a280200102e0c090b200141086a2202280200102f2002280200102e0c080b2001410c6a2202280200102f2002280200102e0c070b200e450d06200141046a2d0000417f6a220241024b0d0602400240024020020e03000102000b2001410c6a280200450d08200141086a280200102e0c080b200141086a2202280200102f2002280200102e0c070b2001410c6a2202280200102f2002280200102e0c060b200f450d05200141086a280200417f6a220241014b0d050240024020020e020001000b200141106a280200450d062001410c6a280200102e0c060b200141106a280200450d052001410c6a280200102e0c050b2010450d04200141046a2d00004104490d042001410c6a280200450d04200141086a280200102e0c040b2011450d03200141086a280200450d03200141046a280200102e0c030b2018450d02200141086a2d0000417e6a220241024b0d0202400240024020020e03000102000b200141106a280200450d042001410c6a280200102e0c040b200141346a280200450d03200141306a280200102e0c030b200141306a280200450d022001412c6a280200102e0c020b2019450d01200141046a2802004101470d01200141086a2202280200102f2002280200102e0c010b201a450d0002402001410c6a280200450d00200141086a280200102e0b02402001411c6a2802002208450d00200141146a28020021022008410c6c210803400240200241046a280200450d002002280200102e0b2002410c6a2102200841746a22080d000b0b200141186a280200450d002001280214102e0b2000200a36020420002009360200200341f0096a24000be30301097f230041306b220224002002410036020820024201370300200141106a20021046200120021066200141306a20021046200141d0006a20021046200128020421032001410c6a280200220120021047024002400240024020010d002002280208210420022802042105200228020021060c010b200141246c210720022802042105200228020821010340200241106a200310452002280210210802400240200520016b20022802182209490d00200120096a2104200228020021060c010b200120096a22042001490d0420054101742206200420042006491b220a4100480d040240024020050d00200a102921060c010b20022802002005200a102a21060b2006450d032002200a36020420022006360200200a21050b20022004360208200620016a2008200910f6041a02402002280214450d002008102e0b200341246a2103200421012007415c6a22070d000b0b200241106a41186a22014200370300200241106a41106a22034200370300200241106a41086a220942003703002002420037031020062004200241106a1000200041186a2001290300370000200041106a2003290300370000200041086a20092903003700002000200229031037000002402005450d002006102e0b200241306a24000f0b200a4101102c000b102d000baf0b030f7f037e027f230041c0006b22012400200028020821022000280204210320002802002104200141086a220042003703002001420037030041999bc500411920011003200141206a41086a22052000290300370300200120012903003703202001200141206a10b30302400240200128020422060d00410421064100210741002108410021090c010b2001410c6a280200210720012802082108200128020021090b20004200370300200142003703004192e9c300411620011003200520002903003703002001200129030037032020014100360200200141206a41102001100821050240024020012802002200417f460d0020012000360234200120053602302001200141306a103002402001280200220a450d00200141086a280200210b2001280204210c2000450d022005102e0c020b41eff0c2004133200141386a4184f4c2001053000b4100210c4101210a4100210b0b0240024002400240024002402002450d002004200241246c6a210d200a200b4105746a210e2004210503402005280220210f200541086a2900002110200541106a290000211120052900002112200141186a200541186a290000370300200141106a2011370300200141086a201037030020012012370300200541246a2105200a2100410021020240024003400240200e20006b41e0004b0d002000200e460d03034020012000460d03200220002001412010f804220b4100476a2102200b450d03200e200041206a2200470d000c040b0b20012000460d01200220002001412010f804220b4100476a2102200b450d01200041206a220b2001460d012002200b2001412010f804220b4100476a2102200b450d01200041c0006a220b2001460d012002200b2001412010f804220b4100476a2102200b450d01200041e0006a220b2001460d0120004180016a21002002200b2001412010f804220b4100476a2102200b0d000b0b2009200f6a22132009490d00024002402007200241016a2200490d00200821090c010b02400240200820076b2000200720072000491b221420076b220b490d00200821090c010b2007200b6a22002007490d0920084101742209200020002009491b220941ffffffff03712009470d09200941027422004100480d090240024020080d002000102921060c010b200620084102742000102a21060b2006450d050b200620074102746a210002400240200b4102490d002007417f7320146a210b034020004100360200200041046a2100200b417f6a220b0d000b2014417f6a21070c010b200b450d010b20004100360200200741016a21070b200720024d0d04200620024102746a22002000280200200f6a36020020092108201321090b2005200d470d000b0b02402003450d002004102e0b0240200c450d00200a102e0b200141086a220042003703002001420037030041999bc500411920011003200141206a41086a2000290300370300200120012903003703202001410036020820014201370300410410292200450d022000200936000020014284808080c000370204200120003602002007200110470240024020070d00200128020821072001280204210e200128020021020c010b200741027421094100200128020822006b21052001280204210e2006210b0340200b280200210f02400240200e20056a4104490d00200128020021020c010b200041046a22022000490d07200e4101742207200220022007491b22074100480d0702400240200e0d002007102921020c010b2001280200200e2007102a21020b2002450d0620012007360204200120023602002007210e0b200b41046a210b2001200041046a2207360208200220006a200f3600002005417c6a2105200721002009417c6a22090d000b0b200141206a41102002200710040240200e450d002002102e0b02402008450d002006102e0b200141c0006a24000f0b20004104102c000b41c099c500200220071038000b41044101102c000b20074101102c000b102d000b8505010e7f230041e0006b220224002002410036023820014110200241386a1008210302400240024002400240024020022802382204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a103120022802080d04200228021422054160712201417f4c0d01200228020c210602400240200541057622070d00410121080c010b200110292208450d030b02402006450d004100210903402005210a200241003a00582009220b41016a2109410021010240024002400340200a2001460d01200241386a20016a2002280210220c2d00003a00002002200c41016a3602102002200141016a220c3a0058200c2101200c4120470d000b200241186a41186a220d200241386a41186a290300370300200241186a41106a220e200241386a41106a290300370300200241186a41086a220f200241386a41086a290300370300200220022903383703182007200b470d020240200b4101742201200920092001491b220741ffffff3f712007470d002007410574220141004e0d020b102d000b200241003602140240200141ff0171450d00200241003a00580b2007450d082008102e0c080b02400240200b0d002001102921080c010b2008200b4105742001102a21080b2008450d060b200a200c6b21052008200b4105746a22012002290318370000200141186a200d290300370000200141106a200e290300370000200141086a200f29030037000020092006470d000b2002200a200c6b3602140b2008450d042000200736020420002008360200200041086a20063602002004450d002003102e0b200241e0006a24000f0b1032000b20014101102c000b20014101102c000b41eff0c2004133200241386a4184f4c2001053000b9c0201057f230041106b220324000240024002400240200141046a2204417f4c0d000240024020040d00410121050c010b200410292205450d020b2003410036020820032004360204200320053602002001200310470240024020032802042206200328020822056b2001490d00200328020021040c010b200520016a22042005490d0420064101742207200420042007491b22074100480d040240024020060d002007102921040c010b200328020020062007102a21040b2004450d032003200736020420032004360200200721060b200420056a2000200110f6041a200228020020022802042004200520016a100402402006450d002004102e0b200341106a24000f0b1032000b20044101102c000b20074101102c000b102d000bdf0301017f024002400240024002400240410110292202450d00200220002d00003a0000200241014102102a2202450d01200220002d00013a0001200241024104102a2202450d02200220002d00023a0002200220002d00033a0003200241044108102a2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102a2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102a2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f200128020020012802042002412010042002102e0f0b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000b806406077f017e0f7f047e0e7f0b7e230041a00b6b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e06000102030405000b200341ec036a4101360200200342013702dc03200341cc91c5003602d8032003411c3602d407200341c491c5003602d0072003200341d0076a3602e803200341d8036a41a0e1c300106a000b200141e0006a2802002104200341d0076a200141086a41d80010f6041a200341a0066a41186a200141fc006a280200360200200341a0066a41106a200141f4006a290200370300200341a0066a41086a200141ec006a2902003703002003200141e4006a2902003703a006024020022d000120022d000072450d00418df0c2002105412821040c060b20034180096a41086a22024200370300200342003703800941ffa0c500411820034180096a1003200341e80a6a41086a200229030037030020032003290380093703e80a41002102200341003602d803200341e80a6a4110200341d8036a10082106024020032802d8032205417f460d00200320053602e409200320063602e009200341d8036a200341e0096a10fb0120032d00c8044102460d0720032802b00421022005450d002006102e0b024020022004490d0041b0e1c3002105413521040c060b200341d8036a41086a41033a00002003410c3a00d803200341d8036a410c6a20043602004100210541c8ecc5004100200341d8036a1072200341d8036a200341d0076a41d80010f6041a200341bc046a200341a0066a41086a290300370200200341c4046a200341a0066a41106a290300370200200341cc046a200341a0066a41186a280200360200200320043602b004200320032903a0063702b40420034180096a41086a22024200370300200342003703800941ffa0c500411820034180096a1003200341e80a6a41086a200229030037030020032003290380093703e80a200341003602e809200342013703e009200341d8036a200341e0096a10fe0120032802e4092102200341e80a6a411020032802e009220420032802e80910042002450d042004102e0c040b200141086a2802002107200141046a280200210841b5f0c2002105412a210420022d00000d1320022d00014101470d132001410c6a2802002109200141106a290300210a200241196a2d00002105200241186a2d00002104200241166a2f01002106200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211920032002411a6a2901003703b805200320053a00b705200320043a00b605200320063b01b4052003200b3a00b3052003200c3a00b2052003200d3b01b0052003200e3a00af052003200f3a00ae05200320103b01ac05200320113a00ab05200320183a00a205200320193b01a005200320142013410874201241187472723600a705200320172016410874722015411874723600a305200341e0006a41eea0c500411110810102404280ade20420032903687d4280ade20420032802601b200a5a0d00418de3c3002105411b21040c140b200341c8006a41fce2c30041111070024020032802480d004201211a4200211b0c120b2003290350221a200341d8006a290300221b8450450d114200211a4200211b4200211c4200211d0c120b200141c0006a290300211d200141386a290300211c2002411a6a290100211a200241196a2d0000210f200241186a2d00002110200241166a2f01002111200241156a2d00002112200241146a2d00002113200241126a2f01002114200241116a2d00002115200241106a2d000021162002410e6a2f010021172002410d6a2d00002118200241046a2d00002119200241026a2f01002109200141306a280200211e2001412c6a2802002108200141286a280200210d2001411d6a290000211b2001411c6a2d0000211f2001411b6a2d00002120200141196a2f00002121200141186a2d00002122200141176a2d00002123200141156a2f00002124200141146a2d00002125200141136a2d00002126200141116a2f00002127200141106a2d000021282001410c6a2802002129200141086a280200210c200141076a2d0000212a200141056a2f0000212b200141046a2d0000210e200141c8006a290300210a41b5f0c2002105412a21070240024020022d0000450d0041012106410021044100210b0c010b41012106410021044100210b20022d00014101470d002002410c6a2d0000210b2002410a6a2f01002104200241096a2d00002107200241066a2f0100410874200241056a2d000072200241086a2d0000411874722105410021060b200441ffff0371410874200741ff017172200b41187472210420060d0f0240200e41ff01714101470d00200341d8036a200c41067610bb0120032802d80321060240024020032802e003200c413f7122024b0d00410021020c010b200620024105746a2202290018211b20022d0017211f20022d0016212020022f0014212120022d0013212220022d0012212320022f0010212420022d000f212520022d000e212620022f000c212720022d000b2128200228000721292002280003210c20022d0002212a20022f0000212b410121020b024020032802dc03450d002006102e0b20020d0041ccc4c2002105411521040c100b2003201a3703b0032003200f3a00af03200320103a00ae03200320113b01ac03200320123a00ab03200320133a00aa03200320143b01a803200320153a00a703200320163a00a603200320173b01a403200320183a00a3032003200436009f032003200536009b03200320193a009a03200320093b019803200341d8016a41eea0c500411110810102404280ade20420032903e0017d4280ade20420032802d8011b200a5a0d00418de3c3002105411b21040c0d0b200341c0016a41fce2c30041111070024020032802c0010d004201211a4200212c0c0b0b20032903c801221a200341d0016a290300222c8450450d0a4200211a4200212c4200212d4200212e0c0b0b200141386a290300211b200141306a290300211d200141c0006a290300210a200341f8026a41186a200141196a290000370300200341f8026a41106a200141116a290000370300200341f8026a41086a200141096a290000370300200320012900013703f8022002411a6a290100211a200241196a2d0000210d200241186a2d0000210e200241166a2f0100210f200241156a2d00002110200241146a2d00002111200241126a2f01002112200241116a2d00002113200241106a2d000021142002410e6a2f010021152002410d6a2d00002116200241046a2d00002117200241026a2f010021182001412c6a2802002119200141286a2802002108200141246a280200210c41b5f0c2002105412a21070240024020022d0000450d0041012106410021044100210b0c010b41012106410021044100210b20022d00014101470d002002410c6a2d0000210b2002410a6a2f01002104200241096a2d00002107200241066a2f0100410874200241056a2d000072200241086a2d0000411874722105410021060b200441ffff0371410874200741ff017172200b41187472210402402006450d002008450d09200c102e0c090b2003201a3703b0032003200d3a00af032003200e3a00ae032003200f3b01ac03200320103a00ab03200320113a00aa03200320123b01a803200320133a00a703200320143a00a603200320153b01a403200320163a00a3032003200436009f032003200536009b03200320173a009a03200320183b019803200341d0026a41eea0c500411110810102404280ade20420032903d8027d4280ade20420032802d0021b200a5a0d00418de3c3002105411b21040c070b200341b8026a41fce2c30041111070024020032802b8020d004201211a4200211c0c050b20032903c002221a200341c8026a290300221c8450450d044200211a4200211c4200212e4200212c0c050b200341e0096a41186a200141196a290000370300200341e0096a41106a200141116a290000370300200341e0096a41086a200141096a290000370300200320012900013703e009200341a0066a41206a200141c1006a2d00003a0000200341a0066a41186a200141396a290000370300200341a0066a41106a200141316a290000370300200341a0066a41086a200141296a2900003703002003200141216a2900003703a006200341d8036a41086a2205200241096a290000370300200341d8036a41106a2204200241116a290000370300200341d8036a41186a2206200241196a290000370300200341d8036a41206a220b200241216a2d00003a0000200341a4056a2207200241266a2f01003b0100200320022900013703d8032003200241226a2801003602a005024020022d00002202450d00200341d0076a41266a20032802a005360100200341dd076a2005290300370000200341e5076a2004290300370000200341ed076a2006290300370000200341f5076a200b2d00003a0000200341fa076a20072f01003b0100200320023a00d407200320032903d8033700d507200341013a00d00741e5e1c300210541e90021040c020b200341d0076a41216a200b2d00003a0000200341d0076a41196a2006290300370000200341d0076a41116a2004290300370000200341d0076a41096a2005290300370000200320032903d803220a3700d107200341003a00d00741e5e1c300210541e9002104200aa741ff0171417f6a220241014b0d0102400240024020020e020100010b20032d00a0064101470d03200341a0066a4101722104410021020c010b20032d00a0064101460d0241022102200341d0076a41027221040b41002105200341d8036a200341e0096a20024100105b20032d00d8032102024020032d00e0030d00200341fc036a280200450d00200341f8036a280200102e0b200241ff01714101470d00200341d8036a20044296014200108e01024020032802d8034101470d0020032802e003210420032802dc0321050c020b200341d8036a41106a290300211a20032903e003211b200341e0026a41c28cc00041161070200341e0026a41106a290300210a20032903e802211d20032802e002210220034180096a41086a22044200370300200342003703800941c28cc000411620034180096a1003200341e80a6a41086a200429030037030020032003290380093703e80a2003427f201a200a420020021b220a7c201b201d420020021b221a7c221b201a542202ad7c221a2002201a200a54201a200a511b22021b3703a8052003427f201b20021b3703a005200341e80a6a4110200341a0056a411010040b0b4101210b410121060c0f0b41eff0c2004133200341980b6a4184f4c2001053000b20034198026a201c4200200a420010fb04200341a8026a201a4200200a420010fb0420034188026a42004200201a420010fb04024020032903a00220032903900284420052200341b0026a290300222e2003290398022003290388027c7c222c202e5472450d0041a8e3c3002105412721040c020b20032903a802212e0b200341d8036a20034198036a202e202c4108107a20032802d8034101470d0120032802e003210420032802dc0321050b2008450d01200c102e0c010b200341d8036a41106a290300212e20032903e003212c200341b8036a41186a201c3703002003201a3703c8032003200a3703c0032003200a3703b80320034180096a41086a22024200370300200342003703800941ffa0c500411820034180096a1003200341e80a6a41086a200229030037030020032003290380093703e80a200341003602d803200341e80a6a4110200341d8036a100821020240024020032802d803220f417f460d002002450d002003200f3602d407200320023602d007200341d8036a200341d0076a10fb01024020032d00c80422054102460d0020032802c404210420032802c004210620032802bc04210b20032802b804210720032802b404210d20032802b004210e20032903a804210a20032903a004211a200329039804211c200329039004212d200329038804212f200329038004213020032903f803213120032903f003213220032903e803213320032903e003213420032903d8032135200320032800c9043602a0062003200341cc046a2800003600a3060240200f450d002002102e0b200320032802a0063602d007200320032800a3063600d3070c020b41eff0c2004133200341980b6a4184f4c2001053000b428701212d42af01211c4201210a410021054104210d4180800421074110210b418080012106412021044100210e4201211a4201212f4201213042012131420121324201213342012134420121350b200320053a00c804200320043602c404200320063602c0042003200b3602bc04200320073602b8042003200d3602b4042003200e3602b0042003200a3703a8042003201a3703a0042003201c370398042003202d370390042003202f370388042003203037038004200320313703f803200320323703f003200320333703e803200320343703e003200320353703d803200341d8046a420037030020034188056a4200370300200341f8046a4200370300200341e8046a4200370300200341cc046a20032800d30736000020034280888080808010370390052003428080e983b1de163703d00420034280a094a58d1d3703800520034280a094a58d1d3703f00420034280a094a58d1d3703e004200320032802d0073600c9042003200341d8036a360298052003200341d8036a36029c05200341d0076a41186a220520034198036a41186a290300370300200341d0076a41106a220420034198036a41106a290300370300200341d0076a41086a220220034198036a41086a29030037030020032003290398033703d007200341f8016a41c5c1c200410d108101200329038002210a20032802f801210620034180096a41086a220b4200370300200342003703800941b0f3c200410d20034180096a1003200341e80a6a41086a200b29030037030020032003290380093703e80a200341f0016a200341e80a6a10ac03200341d4056a4200370200200341a0056a41286a41a481c000360200200341a0056a41246a41c8ecc500360200200341bc056a4200370200200341a0056a41186a41e08dc000360200200341f4056a2002290300370200200341fc056a200429030037020020034184066a20052903003702002003428080808080013702cc054100211f200341003602b405200341003602a805200320032903d0073702ec0520032802f001210520032802f401210420032003419c056a3602e405200320034198056a3602e0052003200341d8036a3602dc0520032004410020051b3602e8052003200a420020061b3703a005200320193602a806200320083602a4062003200c3602a006200341d0076a200341a0056a201d201b200341b8036a200341f8026a200341a0066a104d410121200240024020032802d0074101470d00200341dc076a290200221b422888211c201b422088211d2002280200210420032802d40721054101211f410121200c010b200341fc076a290200221b422888211c200341d0076a41286a2802002104200341d0076a41246a2802002105201b422088221da741ff01710d00200341d0076a41086a200341bc056a290200370300200341a0066a41086a200341dc076a280200360200200320032902b4053703d007200320032902d4073703a006200341980b6a200341a0066a10ec014100211f4200211d410021200b20034198036a20032903b80320032903c00320032903c803200341b8036a41186a290300202c202e10d90320032802d805210620032802d405210b200320032802d0052202360298062003200b36029406200320023602900620032002200641b0016c6a221036029c0602402006450d00200341e0096a410172211720034187096a2118200341e9096a210720034180096a4102722108200341d0076a41106a2119200341f8076a2116200341b4086a211220034191086a210c200341f1076a210d200341d0076a4101722111200341c8086a2109034020022d00002106200341a0066a200241016a41af0110f6041a0240024020064103460d00200320063a00d0072011200341a0066a41af0110f604210b024002400240024020060e03000102000b20032802d807210f20032802dc07210b20032802d40721062018201941d80010f6041a2003410c3a00e009201720034180096a41df0010f6041a2006200b200341e0096a10724101210b4100210e0240200f450d002006102e0b4100210f0c020b200341e80a6a41186a2206200b41186a220e290000370300200341e80a6a41106a220f200b41106a2213290000370300200341e80a6a41086a2214200b41086a22152900003703002003200b2900003703e80a200341e0096a201641880110f6041a2008200b290000370000200841086a2015290000370000200841106a2013290000370000200841186a200e29000037000020034180023b018009200341e8016a200341e0096a20034180096a10950220032802e801210b200720032903e80a370000200741086a2014290300370000200741106a200f290300370000200741186a2006290300370000200341043a00e8092003410c3a00e0092003200b453a00890a4100210b41c8ecc5004100200341e0096a10724101210e4100210f0c010b2009290300210a20032903c008211a200341e80a6a41186a200b41186a290000370300200341e80a6a41106a200b41106a290000370300200341e80a6a41086a200b41086a2900003703002003200b2900003703e80a20034180096a41186a200d41186a29000037030020034180096a41106a200d41106a29000037030020034180096a41086a200d41086a2900003703002003200d29000037038009200341e0096a41186a200c41186a290000370300200341e0096a41106a200c41106a290000370300200341e0096a41086a200c41086a2900003703002003200c2900003703e009200341880b6a41086a201241086a280200360200200320122902003703880b200341e80a6a20034180096a200341e0096a201a200a200341880b6a10da034101210e4101210b4101210f0b024020032d00d007220641014b0d000240024020060e020001000b200e450d03024020032802d807450d0020032802d407102e0b20032d00e0074105490d03200328028808450d03200328028408102e0c030b200b450d022016102f0c020b200f20032802b80845720d0120032802b408102e0c010b2003200241b0016a360298060c020b200241b0016a22022010470d000b20032010360298060b20034190066a102b02400240201f0d00024020040d00410021050c020b2005102e410021050c010b024020050d00410021050c010b201c422886201d4220864280808080f01f8384500d00201ba7102e0b024020032802a8052202450d00200341ac056a280200450d002002102e0b2020450d00200341a0056a41186a280200210220032802c00521080240024020032802bc05220b0d00200221060c010b200b210720022106034020062802880b21062007417f6a22070d000b0340200220022f01064102746a41880b6a2802002102200b417f6a220b0d000b0b200341ec076a20022f0106360200200341d0076a41186a4100360200200341e4076a2002360200200320083602f007200341003602e007200342003703d807200320063602d407200341003602d007200341d0076a10540b410021074101210b410121060c0a0b200341a0016a202c4200200a420010fb04200341b0016a201a4200200a420010fb0420034190016a42004200201a420010fb04024020032903a80120032903980184420052200341b8016a290300222d20032903a0012003290390017c7c222e202d5472450d0041a8e3c3002105412721040c020b20032903b001212d0b200341d8036a20034198036a202d202e4108107a20032802d8034101470d0120032802e003210420032802dc0321050b2008450d01200d102e0c010b200341d8036a41106a290300212d20032903e003212e200341b8036a41186a202c3703002003201a3703c8032003200a3703c0032003200a3703b80320034180096a41086a22024200370300200342003703800941ffa0c500411820034180096a1003200341e80a6a41086a200229030037030020032003290380093703e80a200341003602d803200341e80a6a4110200341d8036a100821020240024020032802d8032210417f460d002002450d00200320103602d407200320023602d007200341d8036a200341d0076a10fb01024020032d00c80422054102460d0020032802c404210420032802c004210620032802bc04210b20032802b804210720032802b404210e20032802b004210f20032903a804210a20032903a004211a200329039804212c200329039004212f2003290388042130200329038004213120032903f803213220032903f003213320032903e803213420032903e003213520032903d8032136200320032800c9043602a0062003200341cc046a2800003600a30602402010450d002002102e0b200320032802a0063602d007200320032800a3063600d3070c020b41eff0c2004133200341980b6a4184f4c2001053000b428701212f42af01212c4201210a410021054104210e4180800421074110210b418080012106412021044100210f4201211a420121304201213142012132420121334201213442012135420121360b200320053a00c804200320043602c404200320063602c0042003200b3602bc04200320073602b8042003200e3602b4042003200f3602b0042003200a3703a8042003201a3703a0042003202c370398042003202f3703900420032030370388042003203137038004200320323703f803200320333703f003200320343703e803200320353703e003200320363703d803200341d8046a4200370300200341d8036a41b0016a4200370300200341f8046a4200370300200341e8046a4200370300200341cc046a20032800d30736000020034280888080808010370390052003428080e983b1de163703d00420034280a094a58d1d3703800520034280a094a58d1d3703f00420034280a094a58d1d3703e004200320032802d0073600c9042003200341d8036a360298052003200341d8036a36029c05200341d0076a41186a220220034198036a41186a290300370300200341d0076a41106a220520034198036a41106a290300370300200341d0076a41086a220420034198036a41086a29030037030020032003290398033703d00720034180016a41c5c1c200410d108101200329038801210a200328028001210620034180096a41086a220b4200370300200342003703800941b0f3c200410d20034180096a1003200341e80a6a41086a200b29030037030020032003290380093703e80a200341f8006a200341e80a6a10ac03200341d4056a4200370200200341c8056a41a481c000360200200341c4056a41c8ecc500360200200341bc056a4200370200200341a0056a41186a41e08dc000360200200341f4056a2004290300370200200341fc056a200529030037020020034184066a20022903003702002003428080808080013702cc05200341003602b405200341003602a805200320032903d0073702ec0520032802782102200328027c210520032003419c056a3602e405200320034198056a3602e0052003200341d8036a3602dc0520032005410020021b3602e8052003200a420020061b3703a0052003201b3703e8072003201f3a00e707200320203a00e607200320213b01e407200320223a00e307200320233a00e207200320243b01e007200320253a00df07200320263a00de07200320273b01dc07200320283a00db07200320293600d7072003200c3600d3072003202a3a00d2072003202b3b01d0072003201e3602a806200320083602a4062003200d3602a006200341f8026a200341a0056a200341d0076a201c201d200341b8036a200341a0066a105a41012119024020032802f80222090d00200341f8026a41106a2d00000d00200341d0076a41086a200341bc056a290200370300200341a0066a41086a200341dc076a280200360200200320032902b4053703d007200320032902d4073703a006200341980b6a200341a0066a10ec01410021190b20034198036a20032903b80320032903c00320032903c803200341b8036a41186a290300202e202d10d90320032802d805210520032802d4052104200320032802d0052202360298062003200436029406200320023602900620032002200541b0016c6a220e36029c0602402005450d00200341e0096a410172211520034187096a2116200341e9096a210620034180096a410272210b200341d0076a41106a2117200341f8076a2114200341b4086a211020034191086a2107200341f1076a2108200341d0076a410172210f200341c8086a2118034020022d00002105200341a0066a200241016a41af0110f6041a0240024020054103460d00200320053a00d007200f200341a0066a41af0110f6042104024002400240024020050e03000102000b20032802d807210d20032802dc07210420032802d40721052016201741d80010f6041a2003410c3a00e009201520034180096a41df0010f6041a20052004200341e0096a1072410121044100210c0240200d450d002005102e0b4100210d0c020b200341e80a6a41186a2205200441186a220c290000370300200341e80a6a41106a220d200441106a2211290000370300200341e80a6a41086a2212200441086a2213290000370300200320042900003703e80a200341e0096a201441880110f6041a200b2004290000370000200b41086a2013290000370000200b41106a2011290000370000200b41186a200c29000037000020034180023b018009200341f0006a200341e0096a20034180096a10950220032802702104200620032903e80a370000200641086a2012290300370000200641106a200d290300370000200641186a2005290300370000200341043a00e8092003410c3a00e00920032004453a00890a4100210441c8ecc5004100200341e0096a10724101210c4100210d0c010b2018290300210a20032903c008211a200341e80a6a41186a200441186a290000370300200341e80a6a41106a200441106a290000370300200341e80a6a41086a200441086a290000370300200320042900003703e80a20034180096a41186a200841186a29000037030020034180096a41106a200841106a29000037030020034180096a41086a200841086a2900003703002003200829000037038009200341e0096a41186a200741186a290000370300200341e0096a41106a200741106a290000370300200341e0096a41086a200741086a290000370300200320072900003703e009200341880b6a41086a201041086a280200360200200320102902003703880b200341e80a6a20034180096a200341e0096a201a200a200341880b6a10da034101210c410121044101210d0b024020032d00d007220541014b0d000240024020050e020001000b200c450d03024020032802d807450d0020032802d407102e0b20032d00e0074105490d03200328028808450d03200328028408102e0c030b2004450d022014102f0c020b200d20032802b80845720d0120032802b408102e0c010b2003200241b0016a360298060c020b200241b0016a2202200e470d000b2003200e360298060b20034190066a102b20034180036a280200210420032802fc0221050240024020090d00024020040d00410021050c020b2005102e410021050c010b024020050d00410021050c010b20034184036a290200220a428080808010540d00200aa7102e0b024020032802a8052202450d00200341ac056a280200450d002002102e0b2019450d00200341a0056a41186a280200210220032802c00521080240024020032802bc05220b0d00200221060c010b200b210720022106034020062802880b21062007417f6a22070d000b0340200220022f01064102746a41880b6a2802002102200b417f6a220b0d000b0b200341ec076a20022f0106360200200341d0076a41186a4100360200200341e4076a2002360200200320083602f007200341003602e007200342003703d807200320063602d407200341003602d007200341d0076a10540b410021064101210b0c040b410021064101210b2008450d03200d102e0c030b200341286a201b4200200a420010fb04200341386a201a4200200a420010fb04200341186a42004200201a420010fb0402402003290330200329032084420052200341c0006a290300221c200329032820032903187c7c221d201c5472450d0041a8e3c3002105412721040c020b2003290338211c0b200341d8036a200341a0056a201c201d4108107a024020032802d8034101470d0020032802e003210420032802dc0321050c010b200341d8036a41106a290300211c20032903e003211d20034180096a41086a22024200370300200342003703800941ffa0c500411820034180096a1003200341e80a6a41086a200229030037030020032003290380093703e80a200341003602d803200341e80a6a4110200341d8036a100821020240024020032802d8032204417f460d002002450d00200320043602a406200320023602a006200341d8036a200341a0066a10fb01024020032d00c80422054102460d00200341d0076a200341d8036a41f00010f6041a2003200341cc046a22062800003600e309200320032800c9043602e00902402004450d002002102e0b200341d8036a200341d0076a41f00010f6041a200620032800e309360000200320032802e0093600c90420032903d803212c0c020b41eff0c2004133200341980b6a4184f4c2001053000b41002105200341003602b004200341203602c404200342908080808080103702bc04200342848080808080c0003702b4044201212c200342013703a804200342013703a004200342af013703980420034287013703900420034201370388042003420137038004200342013703f803200342013703f003200342013703e803200342013703e003200342013703d8030b200341086a202c42002009ad420010fb04200320053a00c8044200200a427f200329030820032903104200521b7d222c202c200a5622021b212c0240024002402002450d00419ddbc1002105412c21040c010b200341d0076a20082009200341d8036a10f701024020032802d0074101470d00200341d8076a280200210420032802d40721050c010b200341e80a6a41186a2202200341ec076a280200360200200341e80a6a41106a220d200341d0076a41146a290200370300200341e80a6a41086a220e200341dc076a290200370300200320032902d4073703e80a200341d0076a41186a22054200370300200341d0076a41106a220b4200370300200341d0076a41086a220c4200370300200342003703d00720082009200341d0076a10002003419a036a20032d00d207220f3a0000200341b8036a41086a2210200341d0076a41136a290000370300200341c5036a22112005290000370000200320032f01d00722123b019803200320032900db07222e3703b80320032800d307210620032800d7072104200341e0096a41136a2010290300370000200341e0096a41186a20112900003700002003200f3a00e209200320123b01e009200320043600e709200320063600e3092003202e3700eb0920034180096a41186a200228020036020020034180096a41106a200d29030037030020034180096a41086a200e290300370300200320032903e80a3703800902400240411410292202450d00200241106a41002800aca543360000200241086a41002900a4a5433700002002410029009ca54337000020034294808080c0023702d407200320023602d007200341e0096a200341d0076a104620032802d407210d20032802d807210e20032802d007210220054200370300200b4200370300200c4200370300200342003703d0072002200e200341d0076a1000200341a0066a41186a2005290300370300200341a0066a41106a200b290300370300200341a0066a41086a200c290300370300200320032903d0073703a006200341203602d4072003200341a0066a3602d00720034180096a200341d0076a10f8010240200d450d002002102e0b024020034190096a280200450d00200328028c09102e0b200341f3096a200341b8036a41086a290300370000200341e0096a41186a200341b8036a410d6a29000037000020032003419a036a2d00003a00e209200320032f0198033b01e009200320043600e709200320063600e309200320032903b8033700eb09411510292202450d012002410d6a4100290094a543370000200241086a410029008fa54337000020024100290087a54337000020034295808080d0023702d407200320023602d007200341e0096a200341d0076a104620032802d407210520032802d807210b20032802d0072102200341d0076a41186a220c4200370300200341d0076a41106a220d4200370300200341d0076a41086a220e4200370300200342003703d0072002200b200341d0076a1000200341a0066a41186a200c290300370300200341a0066a41106a200d290300370300200341a0066a41086a200e290300370300200320032903d0073703a006200341203602d4072003200341a0066a3602d00720082009200341d0076a10990202402005450d002002102e0b02402007450d002008102e0b20034180096a41026a20034198036a41026a2d000022023a0000200341a0066a41086a2205200341b8036a41086a290300370300200341a0066a410d6a220b200341b8036a410d6a290000370000200320032f01980322073b018009200320032903b8033703a006200341d0076a41086a41023a0000200341d9076a20073b0000200341db076a20023a0000200341e0076a20043602002003410c3a00d007200341d0076a410c6a2006360200200341e4076a20032903a006370200200341ec076a2005290300370200200341f1076a200b2900003700004100210541c8ecc5004100200341d0076a1072200341a0056a200a202c201a201b201d201c10d9030c030b41144101102c000b41154101102c000b02402007450d002008102e0b200341a0056a200a202c201a201b201d201c10d9030b410121064100210b0c010b410121064100210b2007450d002008102e0b410121070b024020012d0000417e6a220241024b0d00024002400240024020020e03000102000b200b450d03200141086a280200450d03200141046a280200102e0c030b20060d010c020b2007450d01200141286a280200450d01200141246a280200102e0c010b2001412c6a280200450d00200141286a280200102e0b2000200436020420002005360200200341a00b6a24000bc40101027f230041206b22012400200141106a41086a220242003703002001420037031041acb4c200411b200141106a1003200141086a200229030037030020012001290310370300200028020021022000280208210020014100360218200142013703102000200141106a104702402000450d002000410574210003402002200141106a104a200241206a2102200041606a22000d000b0b2001280214210220014110200128021022002001280218100402402002450d002000102e0b200141206a24000bae0f030b7f077e057f230022042105200441c0016b41607122042400024002400240024002400240200141ffffff3f712001470d0020014105742206417f4c0d000240024020060d00410121070c010b200610292207450d020b410021084100210602402001450d0020014105742109416020006b210a2007210620002108034020062008290000370000200641186a200841186a290000370000200641106a200841106a290000370000200641086a200841086a290000370000200641206a2106200841206a2108200941606a22090d000b200020014105746a200a6a41057641016a2106200121080b20042006360218200420083602142004200736021020072006200441206a410041202006676b105f200441a0016a41086a22064200370300200442003703a00141e0c9c200411d200441a0016a100320044180016a41086a2006290300370300200420042903a00137038001200441003602a00120044180016a4110200441a0016a100821080240024020042802a0012206417f460d002004200636024420042008360240200441a0016a200441c0006a103020042802a001220b450d04200441a8016a280200210920042802a401210c2006450d012008102e0c010b4101210b410021094100210c0b2009410574220a450d05200441a0016a411472210d200441a0016a410872210e200b21060340200641086a290000210f200641106a290000211020062900002111200441206a41186a200641186a290000370300200441206a41106a2010370300200441206a41086a200f37030020042011370320200441c0006a200441206a109003200441003602a80120042903582111200420042903b801221237035820042903502113200420042903b001221437035020042903402115200420042903a0013703402004290348210f200420042903a80122103703482014422088a721002010422088a721012012a721072010a721080240200fa72209450d00200420153703a0012004200f3703a801200420133703b001200420113703b801200420092013a74105746a36028c0120042009360288012004200f422088a73602840120042009360280012004200441106a36029001200441f0006a20044180016a1042200e41086a200441f0006a41086a2216280200360200200e200429037037020020042013422088a722092011422088a74105746a36028c01200420093602880120042011a73602840120042009360280012004200441106a36029001200441f0006a20044180016a1042200d41086a2016280200360200200d200429037037020020042903a801210f20042903a001211320042903b801211020042903b001211102402008450d0002402001450d002008102e0b2007450d002000102e0b200420133703402004200f370348200f422088a72101200420113703502011422088a7210020042010370358200fa721082010a721070b0240024020080d00411a10292208450d06200841186a41002f0095ca423b0000200841106a410029008dca42370000200841086a4100290085ca42370000200841002900fdc9423700002004429a808080a0033702a401200420083602a001200441206a200441a0016a104620042802a401210920042802a801210120042802a0012108200441a0016a41186a22074200370300200441a0016a41106a22004200370300200441a0016a41086a22164200370300200442003703a00120082001200441a0016a100020044180016a41186a200729030037030020044180016a41106a200029030037030020044180016a41086a2016290300370300200420042903a0013703800120044180016a412010062009450d012008102e0c010b411a10292209450d06200941186a41002f0095ca423b0000200941106a410029008dca42370000200941086a4100290085ca42370000200941002900fdc9423700002004429a808080a0033702a401200420093602a001200441206a200441a0016a104620042802a401211620042802a801211720042802a0012109200441a0016a41186a22184200370300200441a0016a41106a22194200370300200441a0016a41086a221a4200370300200442003703a00120092017200441a0016a100020044180016a41186a201829030037030020044180016a41106a201929030037030020044180016a41086a201a290300370300200420042903a00137038001200441203602a401200420044180016a3602a001200441c0006a200441a0016a108e0302402016450d002009102e0b02402001450d002008102e0b2007450d002000102e0b200641206a2106200a41606a220a0d000c060b0b1032000b20064101102c000b41eff0c2004133200441206a4184f4c2001053000b411a4101102c000b411a4101102c000b0240200c450d00200b102e0b200441003602a801200442013703a0012003200441a0016a104702402003450d002003410574210603402002200441a0016a104a200241206a2102200641606a22060d000b0b20042802a401210820042802a801210920042802a0012106200441a0016a41086a22024200370300200442003703a00141d2c1c200411b200441a0016a100320044180016a41086a2002290300370300200420042903a0013703800120044180016a411020062009100402402008450d002006102e0b02402004280214450d002004280210102e0b200524000ba808010e7f230041206b220424002002410020031b21052000410020011b2106200241206a200220031b2107200041206a200020011b2108200020014105746a2109200220034105746a210a4100210b4100210c4101210d4100210e4100210f410121100340024002400240024002400240024002402005450d0003402006450d02024020052006460d0020052006412010f80422020d040b410020072007200a4622021b210541002008200820094622031b21062007200741206a20021b21072008200841206a20031b210820050d000b0b4100210520060d03200d200b20002001109d020240200c450d00200d102e0b0240200f450d002010102e0b200441206a24000f0b200441186a2202200541186a290000370300200441106a2203200541106a290000370300200441086a2211200541086a290000370300200420052900003703000240200c200b470d00200b41016a2206200b490d04200b4101742205200620062005491b220c41ffffff3f71200c470d04200c41057422064100480d0402400240200b0d0020061029210d0c010b200d200b4105742006102a210d0b200d450d020b200d200b4105746a22062004290300370000200641186a2002290300370000200641106a2003290300370000200641086a20112903003700002007200741206a2007200a4622051b2102410021064100200720051b21050c050b2002417f4a0d01200441186a2202200541186a290000370300200441106a2203200541106a290000370300200441086a2211200541086a290000370300200420052900003703000240200c200b470d00200b41016a2205200b490d03200b410174220c20052005200c491b220c41ffffff3f71200c470d03200c41057422054100480d0302400240200b0d0020051029210d0c010b200d200b4105742005102a210d0b200d0d0020054101102c000b200d200b4105746a22052004290300370000200541186a2002290300370000200541106a2003290300370000200541086a20112903003700002007200741206a2007200a4622051b21024100200720051b21050c040b20064101102c000b200441186a2202200641186a290000370300200441106a2203200641106a290000370300200441086a2211200641086a290000370300200420062900003703000240200f200e470d00200e41016a2206200e490d01200e410174220f20062006200f491b220f41ffffff3f71200f470d01200f41057422064100480d0102400240200e0d002006102921100c010b2010200e4105742006102a21100b2010450d020b2010200e4105746a22062004290300370000200641186a2002290300370000200641106a2003290300370000200641086a201129030037000041002008200820094622021b2106200e41016a210e2008200841206a20021b21080c030b102d000b20064101102c000b200b41016a210b200221070c000b0bec5302157f037e230041b0046b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d000022040e050001020304000b200341ac036a41013602002003420137029c03200341cc91c500360298032003411c36029402200341c491c50036029002200320034190026a3602a80320034198036a41b4e7c200106a000b200141086a2802002105200141046a2802002106024020022d000120022d000072450d00418df0c200210741282108410021094101210a02402005450d002006102e0b410121060c160b20062001410c6a2802002202105d20034198036a41086a22074200370300200342003703980341d2c1c200411b20034198036a100320034190026a41086a2007290300370300200320032903980337039002200341003602980320034190026a411020034198036a100821082003280298032207417f460d042003200736026c2003200836026820034198036a200341e8006a10302003280298032209450d03200341a0036a280200210a200328029c03210b02402007450d002008102e0b200620022009200a109e02200b450d142009102e0c140b200141046a280200210941b5f0c2002107412a210820022d00000d1220022d00014101470d12200241196a2d00002107200241186a2d00002108200241166a2f0100210a200241156a2d00002106200241146a2d00002105200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211720032002411a6a29010037038802200320073a008702200320083a0086022003200a3b018402200320063a008302200320053a0082022003200b3b0180022003200c3a00ff012003200d3a00fe012003200e3b01fc012003200f3a00fb01200320163a00f201200320173b01f001200320122011410874201041187472723600f701200320152014410874722013411874723600f30120034198036a41086a22024200370300200342003703980341d2c1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082107024002402003280298032202417f460d002003200236026c2003200736026820034198036a200341e8006a10302003280298032208450d06200341a0036a280200210a200328029c03210602402002450d002007102e0b2008200a200341f0016a108a03210202402006450d002008102e0b2002450d010c120b41014100200341f0016a108a030d110b41c4e7c2002107411521080c120b200141086a2802002109200141046a28020021172002411a6a2901002118200241196a2d0000210b200241186a2d0000210c200241166a2f0100210d200241156a2d0000210e200241146a2d0000210f200241126a2f01002110200241116a2d00002111200241106a2d000021122002410e6a2f010021132002410d6a2d00002114200241046a2d00002115200241026a2f01002116412a210841b5f0c20021070240024020022d0000450d004101210a41002106410021050c010b4101210a410021064100210520022d00014101470d002002410c6a2d000021062002410a6a2f01002105200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d00004118747221074100210a0b200541ffff0371410874200641187472200841ff0171722108200a0d0e200320183703402003200b3a003f2003200c3a003e2003200d3b013c2003200e3a003b2003200f3a003a200320103b0138200320113a0037200320123a0036200320133b0134200320143a00332003200836002f2003200736002b200320153a002a200320163b012820034198036a41086a22024200370300200342003703980341d2c1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082102024002402003280298032207417f460d002002450d002003200736026c2003200236026820034198036a200341e8006a10302003280298032208450d06200341a0036a280200210a200328029c03210602402007450d002002102e0b2008200a200341286a108a03210202402006450d002008102e0b2002450d010c0a0b41014100200341286a108a030d090b41c4e7c2002107411521080c0e0b200141216a2d00002117200141246a2802002116200341286a41186a200141196a290000370300200341286a41106a200141116a290000370300200341286a41086a200141096a290000370300200320012900013703282002411a6a2901002118200241196a2d00002105200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d00002113200241046a2d00002114200241026a2f0100211541b5f0c2002107412a21080240024020022d0000450d00410121094100210a410021060c010b410121094100210a4100210620022d00014101470d002002410c6a2d000021062002410a6a2f0100210a200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021090b200a41ffff0371410874200841ff017172200641187472210820090d0620032018370360200320053a005f2003200b3a005e2003200c3b015c2003200d3a005b2003200e3a005a2003200f3b0158200320103a0057200320113a0056200320123b0154200320133a00532003200836004f2003200736004b200320143a004a200320153b014820034198036a41086a22024200370300200342003703980341d2c1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082102024002402003280298032207417f460d002002450d002003200736026c2003200236026820034198036a200341e8006a10302003280298032208450d06200341a0036a2802002109200328029c03210a02402007450d002002102e0b20082009200341c8006a108a0321020240200a450d002008102e0b2002450d010c070b41014100200341c8006a108a030d060b41cae8c2002107411221080c060b41eff0c2004133200341a8046a4184f4c2001053000b2006200241014100109e020c0f0b41eff0c2004133200341a8046a4184f4c2001053000b41eff0c2004133200341a8046a4184f4c2001053000b41eff0c2004133200341a8046a4184f4c2001053000b20034198036a200341286a109003024020032802a00322090d0041b7e8c2002107411321080c010b200341b0036a280200210b200341ac036a28020021064110210820032802a403210c41dce8c2002107024020162003280298032210470d00200341b4036a280200210d200328029c032111200920034198036a41106a280200220e4105746a210a200921024100210802400240024003400240200a20026b41e0004b0d002002200a470d024100210f0c040b200341c8006a2002460d0220082002200341c8006a412010f80422074100476a21082007450d02200241206a2207200341c8006a460d0220082007200341c8006a412010f80422074100476a21082007450d02200241c0006a2207200341c8006a460d0220082007200341c8006a412010f80422074100476a21082007450d02200241e0006a2207200341c8006a460d0220024180016a210220082007200341c8006a412010f80422074100476a210820070d000c020b0b2009200e4105746a210a0340200341c8006a2002460d0120082002200341c8006a412010f80422074100476a21082007450d014100210f200a200241206a2202470d000c020b0b4101210f0b2006200d4105746a2105200621024100210702400240024003400240200520026b41e0004b0d0020022005470d024100210a0c040b200341c8006a2002460d0220072002200341c8006a412010f804220a4100476a2107200a450d02200241206a220a200341c8006a460d022007200a200341c8006a412010f804220a4100476a2107200a450d02200241c0006a220a200341c8006a460d022007200a200341c8006a412010f804220a4100476a2107200a450d02200241e0006a220a200341c8006a460d0220024180016a21022007200a200341c8006a412010f804220a4100476a2107200a0d000c020b0b0340200341c8006a2002460d0120072002200341c8006a412010f804220a4100476a2107200a450d014100210a2005200241206a2202470d000c020b0b4101210a0b024002400240024002400240024002400240201741ff01710d00200a450d010c080b200f0d0720034198036a41186a2205200341c8006a41186a29030037030020034198036a41106a220f200341c8006a41106a29030037030020034198036a41086a2212200341c8006a41086a29030037030020032003290348370398030240200c200e460d00200c21080c020b200c41016a2202200c490d0b200c4101742208200220022008491b220841ffffff3f712008470d0b200841057422024100480d0b02400240200c0d002002102921090c010b2009200c4105742002102a21090b20090d0120024101102c000b20034198036a41186a220a200341c8006a41186a29030037030020034198036a41106a2205200341c8006a41106a29030037030020034198036a41086a2212200341c8006a41086a290300370300200320032903483703980302400240200b200d460d00200b21070c010b200b41016a2202200b490d0b200b4101742207200220022007491b220741ffffff3f712007470d0b200741057422024100480d0b02400240200b0d002002102921060c010b2006200b4105742002102a21060b20060d0020024101102c000b2006200d4105746a2202200329039803370000200241186a200a290300370000200241106a2005290300370000200241086a2012290300370000200d41016a210d02400240200f450d00200e20084d0d012009200e417f6a220e4105746a22022900002118200229000821192002290010211a200920084105746a220841186a200241186a2900003700002008201a37001020082019370008200820183700000b200c21082007210b0c020b4184e9c2002008200e1038000b2009200e4105746a2202200329039803370000200241186a2005290300370000200241106a200f290300370000200241086a2012290300370000200e41016a210e200a450d00200d20074d0d012006200d417f6a220d4105746a22022900002118200229000821192002290010211a200620074105746a220741186a200241186a2900003700002007201a37001020072019370008200720183700000b200341bd036a2003290328370000200341a5036a200341c8006a41086a290300370000200341ad036a200341c8006a41106a290300370000200341b5036a200341c8006a41186a290300370000200341c5036a200341286a41086a290300370000200341cd036a200341286a41106a290300370000200341d5036a200341286a41186a290300370000200341013a009c03200341073a0098032003200329034837009d03200341e4036a200d360200200341e0036a200e360200200341dd036a20173a000041c8ecc500410020034198036a107220034198036a41086a22024200370300200342003703980341d2c1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082107200328029803220a417f460d022007450d022003200a36026c2003200736026820034198036a200341e8006a1030200328029803220c450d01200341a0036a2802002102200328029c0321050240200a450d002007102e0b2005450d03200c102e0c030b4184e9c2002007200d1038000b41eff0c2004133200341a8046a4184f4c2001053000b410021020b024002400240024002400240024002400240200e20114f220a0d0041002002200d6b2207200720024b1b2011490d00200341b4036a200d36020020034198036a41186a200b36020020034198036a41106a200e360200200341a4036a2008360200200320063602ac03200320093602a0032003201136029c032003201036029803411a10292202450d01200241186a41002f0095ca423b0000200241106a410029008dca42370000200241086a4100290085ca42370000200241002900fdc9423700002003429a808080a003370294022003200236029002200341286a20034190026a10462003280294022107200328029802210a200328029002210220034190026a41186a2205420037030020034190026a41106a220c420037030020034190026a41086a220d420037030020034200370390022002200a20034190026a1000200341f0016a41186a2005290300370300200341f0016a41106a200c290300370300200341f0016a41086a200d29030037030020032003290390023703f00120034120360294022003200341f0016a3602900220034198036a20034190026a108e0302402007450d002002102e0b02402008450d002009102e0b200b0d050c060b0240200a0d00200341a5036a200341306a290300370000200341ad036a200341386a290300370000200341b5036a200341c0006a290300370000200341033a009c03200341073a0098032003200329032837009d0341c8ecc500410020034198036a10720c040b200341a5036a200341286a41086a290300370000200341ad036a200341286a41106a290300370000200341b5036a200341286a41186a290300370000200341023a009c03200341073a0098032003200329032837009d0341c8ecc500410020034198036a1072411e10292207450d01200741166a41002900fee942370000200741106a41002900f8e942370000200741086a41002900f0e942370000200741002900e8e9423700002003429e808080e00337029c032003200736029803200341286a20034198036a1046200328029c03210c20032802a003210a200328029803210720034190026a41186a2205420037030020034190026a41106a220d420037030020034190026a41086a220e420037030020034200370390022007200a20034190026a1000200341f0016a41186a2005290300370300200341f0016a41106a200d290300370300200341f0016a41086a200e29030037030020032003290390023703f0012003410036029803200341f0016a412020034198036a1008210502400240200328029803220d417f470d004113210a0c010b024020050d004113210a0c010b2003200d3602a404200320053602a00420034198036a200341a0046a10b80120032d009803220a4113460d0320034190026a20034198036a41017241870110f6041a0240200d450d002005102e0b200341f0016a412010060b200341e8006a20034190026a41870110f6041a0240200a4113470d00200c450d042007102e0c040b20034190026a200341e8006a41870110f6041a0240200c450d002007102e0b2003200a3a00980320034198036a41017220034190026a41870110f6041a200341f4006a2002360200200341e8006a41086a2011360200200341003a006c200341023a0068200341206a20034198036a200341e8006a10950220032802202102200341a5036a200341286a41086a290300370000200341ad036a200341386a290300370000200341b5036a200341c0006a290300370000200341bd036a2002453a0000200341043a009c03200341073a0098032003200329032837009d0341c8ecc500410020034198036a10720c030b411a4101102c000b411e4101102c000b41eff0c2004133200341a8046a4184f4c2001053000b411a10292202450d02200241186a41002f0095ca423b0000200241106a410029008dca42370000200241086a4100290085ca42370000200241002900fdc9423700002003429a808080a00337029c032003200236029803200341286a20034198036a1046200328029c03210a20032802a0032105200328029803210720034190026a41186a220c420037030020034190026a41106a220d420037030020034190026a41086a2202420037030020034200370390022007200520034190026a1000200341f0016a41186a200c290300370300200341f0016a41106a200d290300370300200341f0016a41086a200229030037030020032003290390023703f001200341f0016a412010060240200a450d002007102e0b20034198036a41086a22074200370300200342003703980341e0c9c200411d20034198036a100320022007290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082107024002402003280298032202417f460d002003200236026c2003200736026820034198036a200341e8006a1030200328029803220a450d05200329029c03211802402002450d002007102e0b2003201837026c2003200a3602680c010b20034100360270200342013703680b200341e8006a200341286a103720034198036a41086a22024200370300200342003703980341e0c9c200411d20034198036a100320034190026a41086a20022903003703002003200329039803370390022003280268210a20032802702102200341003602a0032003420137039803200220034198036a104702402002450d0020024105742107200a21020340200220034198036a1046200241206a2102200741606a22070d000b0b200328029c03210220034190026a4110200328029803220720032802a003100402402002450d002007102e0b0240200328026c450d00200a102e0b02402008450d002009102e0b200b450d010b2006102e0b410021070c040b411a4101102c000b41eff0c2004133200341a8046a4184f4c2001053000b41ece8c2002107411621080b0240200c450d002009102e0b200b450d002006102e0b4101210a41012106410121090c0b0b200341003602a0032003420137039803200920034198036a10bc01200328029c03210720032802a0032108200328029803210220034190026a41186a220a420037030020034190026a41106a2206420037030020034190026a41086a2205420037030020034200370390022002200820034190026a1000200341c8006a41186a2208200a290300370300200341c8006a41106a220a2006290300370300200341c8006a41086a22062005290300370300200320032903900237034802402007450d002002102e0b20034198036a41186a200829030037030020034198036a41106a200a29030037030020034198036a41086a2006290300370300200320032903483703980302400240024002400240024002400240411e10292202450d00200241166a41002900fee942370000200241106a41002900f8e942370000200241086a41002900f0e942370000200241002900e8e9423700002003429e808080e00337029402200320023602900220034198036a20034190026a104620032802940221072003280298022108200328029002210220034190026a41186a220a420037030020034190026a41106a2206420037030020034190026a41086a2205420037030020034200370390022002200820034190026a1000200341f0016a41186a200a290300370300200341f0016a41106a2006290300370300200341f0016a41086a200529030037030020032003290390023703f001200341f0016a412041c8ecc500410041001005210802402007450d002002102e0b2008417f470d01024020174102490d00200341186a4186eac2004121107d200328021c21052003280218210b200341106a4186eac2004121107d200328021021072003280214210820034198036a41086a2202420037030020034200370398034186eac200412120034198036a100320034190026a41086a220a20022903003703002003200329039803370390022003200841016a410120071b3602980320034190026a411020034198036a4104100420024200370300200342003703980341e0c9c200411d20034198036a1003200a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a100821022003280298032206417f460d042002450d042003200636026c2003200236026820034198036a200341e8006a1030200328029803220a450d0320034198036a41086a220c2802002107200328029c03210802402006450d002002102e0b20034198036a41186a200341c8006a41186a29030037030020034198036a41106a200341c8006a41106a290300370300200c200341c8006a41086a290300370300200320032903483703980320034198036a210220072008470d070c060b20034198036a41086a22024200370300200342003703980341d2c1c200411b20034198036a100320034190026a41086a200229030037030020032003290398033703900241002102200341003602980320034190026a411020034198036a1008210802402003280298032207417f460d002003200736026c2003200836026820034198036a200341e8006a10302003280298032206450d05200341a0036a2802002102200328029c03210a02402007450d002008102e0b200a450d002006102e0b20034198036a200941880110f6041a2003419c026a200236020020034190026a41086a4101360200200341003a009402200341023a009002200341086a20034198036a20034190026a10950220032802082102200341a5036a200341c8006a41086a290300370000200341ad036a200341d8006a290300370000200341b5036a200341e0006a290300370000200341bd036a2002453a0000200341043a009c03200341073a0098032003200329034837009d0320034198036a21020c070b411e4101102c000b41d9e7c2002107411f21080c0b0b41eff0c2004133200341a8046a4184f4c2001053000b20034198036a41186a200341c8006a41186a29030037030020034198036a41106a200341c8006a41106a29030037030020034198036a41086a200341c8006a41086a29030037030020032003290348370398034101210a4100210820034198036a21020c010b41eff0c2004133200341a8046a4184f4c2001053000b200841016a22072008490d0220084101742206200720072006491b220641ffffff3f712006470d022006410574220c4100480d020240024020080d00200c1029210a0c010b200a2008410574200c102a210a0b2008210720062108200a450d060b200a2007410574220c6a22062002290000370000200641186a200241186a290000370000200641106a200241106a290000370000200641086a200241086a29000037000020034198036a41086a22024200370300200342003703980341e0c9c200411d20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602a0032003420137039803200741016a220220034198036a1047024020022007490d00200c41206a2107200a21020340200220034198036a1046200241206a2102200741606a22070d000b0b200328029c03210220034190026a4110200328029803220720032802a003100402402002450d002007102e0b02402008450d00200a102e0b200341e8006a41186a200341c8006a41186a290300370300200341e8006a41106a200341c8006a41106a290300370300200341e8006a41086a200341c8006a41086a2903003703002003200329034837036820034198036a200941880110f6041a411e10292202450d02200241166a41002900fee942370000200241106a41002900f8e942370000200241086a41002900f0e942370000200241002900e8e9423700002003429e808080e003370294022003200236029002200341e8006a20034190026a104620032802940221072003280298022108200328029002210220034190026a41186a220a420037030020034190026a41106a2206420037030020034190026a41086a220c420037030020034200370390022002200820034190026a1000200341f0016a41186a200a290300370300200341f0016a41106a2006290300370300200341f0016a41086a200c29030037030020032003290390023703f0012003410036029802200342013703900220034198036a20034190026a10bc012003280294022108200341f0016a4120200328029002220a200328029802100402402008450d00200a102e0b02402007450d002002102e0b20034198036a102f412010292202450d0320022003290328370000200241186a200341286a41186a290300370000200241106a200341286a41106a290300370000200241086a200341286a41086a290300370000200341e8006a41186a200341c8006a41186a290300370300200341e8006a41106a200341c8006a41106a290300370300200341e8006a41086a200341c8006a41086a29030037030020032003290348370368200341b4036a4100360200200341a4036a428180808010370200200342013702ac03200320023602a0032003201736029c03200320054100200b1b220836029803411a10292207450d04200741186a41002f0095ca423b0000200741106a410029008dca42370000200741086a4100290085ca42370000200741002900fdc9423700002003429a808080a003370294022003200736029002200341e8006a20034190026a1046200328029402210a2003280298022106200328029002210720034190026a41186a2205420037030020034190026a41106a220b420037030020034190026a41086a220c420037030020034200370390022007200620034190026a1000200341f0016a41186a2005290300370300200341f0016a41106a200b290300370300200341f0016a41086a200c29030037030020032003290390023703f00120034120360294022003200341f0016a3602900220034198036a20034190026a108e030240200a450d002007102e0b2002102e200341a5036a200341286a41086a290300370000200341ad036a200341286a41106a290300370000200341b5036a200341286a41186a290300370000200341bd036a2003290348370000200341c5036a200341c8006a41086a290300370000200341cd036a200341c8006a41106a290300370000200341d5036a200341c8006a41186a290300370000200341e4036a2017360200200341e0036a2008360200200341003a009c03200341073a0098032003200329032837009d0320034198036a21020b4100210641c8ecc5004100200210722009102e4101210a0c070b102d000b411e4101102c000b41204101102c000b411a4101102c000b200c4101102c000b2009102f2009102e410021064101210a410121090c040b4100210a200341003602a0032003420137039803200920034198036a10bc01200328029c03210720032802a0032108200328029803210220034190026a41186a2206420037030020034190026a41106a2205420037030020034190026a41086a220b420037030020034200370390022002200820034190026a1000200341e8006a41186a22082006290300370300200341e8006a41106a220c2005290300370300200341e8006a41086a2205200b290300370300200320032903900237036802402007450d002002102e0b20034198036a200941880110f6041a20034190026a410d6a200341f0016a41086a29030037000020034190026a41156a200341f0016a41106a29030037000020034190026a411d6a200341f0016a41186a29030037000041012106200341013a009402200320032903f00137009502200341023a009002200320034198036a20034190026a1095022003280200210220034198036a410d6a200529030037000020034198036a41156a200c29030037000020034198036a411d6a2008290300370000200341bd036a2002453a0000200341053a009c03200341073a0098032003200329036837009d0341c8ecc500410020034198036a10722009102e0b41012109410021070c020b2009102f2009102e410121064100210a410121090c010b20034198036a41086a22074200370300200342003703980341d2c1c200411b20034198036a100320034190026a41086a2007290300370300200320032903980337039002200341003602a0032003420137039803200220034198036a104702402002450d0020024105742107200621020340200220034198036a104a200241206a2102200741606a22070d000b0b200328029c03210220034190026a4110200328029803220720032802a003100402402002450d002007102e0b4101210a02402005450d002006102e0b4100210941012106410021070b02402004410771417f6a220241024b0d0002400240024020020e03000102000b2009450d02200141086a280200450d02200141046a280200102e0c020b200a450d01200141046a2802002202102f2002102e0c010b2006450d00200141086a2802002202102f2002102e0b2000200836020420002007360200200341b0046a24000ba65c02157f037e230041b0046b2203240002400240024002400240024002400240024002400240024002400240024020012d000022040e0500010a0302000b200341ac036a41013602002003420137029c03200341cc91c500360298032003411c36029402200341c491c50036029002200320034190026a3602a80320034198036a41b4e7c200106a000b200141086a2802002105200141046a2802002106024020022d000120022d000072450d00418df0c200210741282108410021094101210a02402005450d002006102e0b4101210b0c0d0b20062001410c6a280200220c105d20034198036a41086a22024200370300200342003703980341edc1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a100821020240024002402003280298032207417f460d002002450d002003200736026c2003200236026820034198036a200341e8006a1030200328029803220d450d02200341a0036a280200210a200328029c03210e2007450d012002102e0c010b4101210d4100210a4100210e0b200d4100200a1b210920064100200c1b2108200d41206a200d200a1b2107200641206a2006200c1b21022006200c4105746a210f200d200a4105746a21104100211141002112410121134100211441002115410121160340024002400240024002400240024002402009450d0003402008450d02024020092008460d0020092008412010f804220a0d040b410020072007201046220a1b2109410020022002200f46220b1b21082007200741206a200a1b21072002200241206a200b1b210220090d000b0b4100210920080d05201320112006200c10df0102402012450d002013102e0b02402015450d002016102e0b0240200e450d00200d102e0b20034198036a41086a22024200370300200342003703980341edc1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602a0032003420137039803200c20034198036a10470240200c450d00200c4105742107200621020340200220034198036a104a200241206a2102200741606a22070d000b0b200328029c03210220034190026a4110200328029803220720032802a003100402402002450d002007102e0b4101210a20050d020c140b20034198036a41186a220a200941186a29000037030020034198036a41106a220b200941106a29000037030020034198036a41086a2217200941086a2900003703002003200929000037039803024020122011470d00201141016a22082011490d0b20114101742209200820082009491b221241ffffff3f712012470d0b201241057422084100480d0b0240024020110d002008102921130c010b201320114105742008102a21130b2013450d030b201320114105746a2208200329039803370000200841186a200a290300370000200841106a200b290300370000200841086a20172903003700002007200741206a200720104622091b210a410021084100200720091b21090c050b200a417f4a0d0320034198036a41186a220a200941186a29000037030020034198036a41106a220b200941106a29000037030020034198036a41086a2217200941086a2900003703002003200929000037039803024020122011470d00201141016a22092011490d0a20114101742212200920092012491b221241ffffff3f712012470d0a201241057422094100480d0a0240024020110d002009102921130c010b201320114105742009102a21130b2013450d030b201320114105746a2209200329039803370000200941186a200a290300370000200941106a200b290300370000200941086a20172903003700002007200741206a200720104622091b210a4100200720091b21090c040b2006102e0c110b20084101102c000b20094101102c000b20034198036a41186a220a200841186a29000037030020034198036a41106a220b200841106a29000037030020034198036a41086a2217200841086a29000037030020032008290000370398030240024020152014470d00201441016a22082014490d0720144101742215200820082015491b221541ffffff3f712015470d07201541057422084100480d070240024020140d002008102921160c010b201620144105742008102a21160b2016450d010b201620144105746a2208200329039803370000200841186a200a290300370000200841106a200b290300370000200841086a2017290300370000410020022002200f46220a1b2108201441016a21142002200241206a200a1b21020c020b20084101102c000b201141016a2111200a21070c000b0b41eff0c2004133200341a8046a4184f4c2001053000b200141216a2d0000210e200141246a2802002105200341286a41186a200141196a290000370300200341286a41106a200141116a290000370300200341286a41086a200141096a290000370300200320012900013703282002411a6a2901002118200241196a2d0000210f200241186a2d00002110200241166a2f01002114200241156a2d00002111200241146a2d00002115200241126a2f01002116200241116a2d00002117200241106a2d000021122002410e6a2f010021132002410d6a2d00002106200241046a2d0000210c200241026a2f0100210d41b5f0c2002107412a21080240024020022d0000450d00410121094100210a4100210b0c010b410121094100210a4100210b20022d00014101470d002002410c6a2d0000210b2002410a6a2f0100210a200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021090b200a41ffff0371410874200841ff017172200b411874722108024020090d00200320183703602003200f3a005f200320103a005e200320143b015c200320113a005b200320153a005a200320163b0158200320173a0057200320123a0056200320133b0154200320063a00532003200836004f2003200736004b2003200c3a004a2003200d3b014820034198036a41086a22024200370300200342003703980341edc1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a1008210202400240024002402003280298032207417f460d002002450d002003200736026c2003200236026820034198036a200341e8006a10302003280298032208450d02200341a0036a2802002109200328029c03210a02402007450d002002102e0b20082009200341c8006a108a0321020240200a450d002008102e0b2002450d010c030b41014100200341c8006a108a030d020b41cae8c2002107411221080c020b41eff0c2004133200341a8046a4184f4c2001053000b20034198036a200341286a108d03024020032802a00322090d0041b7e8c2002107411321080c010b200341b0036a2802002110200341ac036a280200210b4110210820032802a403211441dce8c2002107024020052003280298032217470d00200341b4036a2802002111200328029c032112200920034198036a41106a28020022154105746a210a200921024100210802400240024003400240200a20026b41e0004b0d002002200a470d02410021160c040b200341c8006a2002460d0220082002200341c8006a412010f80422074100476a21082007450d02200241206a2207200341c8006a460d0220082007200341c8006a412010f80422074100476a21082007450d02200241c0006a2207200341c8006a460d0220082007200341c8006a412010f80422074100476a21082007450d02200241e0006a2207200341c8006a460d0220024180016a210220082007200341c8006a412010f80422074100476a210820070d000c020b0b200920154105746a210a0340200341c8006a2002460d0120082002200341c8006a412010f80422074100476a21082007450d0141002116200a200241206a2202470d000c020b0b410121160b200b20114105746a210f200b21024100210702400240024003400240200f20026b41e0004b0d002002200f470d024100210a0c040b200341c8006a2002460d0220072002200341c8006a412010f804220a4100476a2107200a450d02200241206a220a200341c8006a460d022007200a200341c8006a412010f804220a4100476a2107200a450d02200241c0006a220a200341c8006a460d022007200a200341c8006a412010f804220a4100476a2107200a450d02200241e0006a220a200341c8006a460d0220024180016a21022007200a200341c8006a412010f804220a4100476a2107200a0d000c020b0b0340200341c8006a2002460d0120072002200341c8006a412010f804220a4100476a2107200a450d014100210a200f200241206a2202470d000c020b0b4101210a0b024002400240024002400240024002400240200e41ff01710d00200a450d010c080b20160d0720034198036a41186a220f200341c8006a41186a29030037030020034198036a41106a2216200341c8006a41106a29030037030020034198036a41086a2213200341c8006a41086a2903003703002003200329034837039803024020142015460d00201421080c020b201441016a22022014490d0b20144101742208200220022008491b220841ffffff3f712008470d0b200841057422024100480d0b0240024020140d002002102921090c010b200920144105742002102a21090b20090d0120024101102c000b20034198036a41186a220a200341c8006a41186a29030037030020034198036a41106a220f200341c8006a41106a29030037030020034198036a41086a2213200341c8006a41086a29030037030020032003290348370398030240024020102011460d00201021070c010b201041016a22022010490d0b20104101742207200220022007491b220741ffffff3f712007470d0b200741057422024100480d0b0240024020100d0020021029210b0c010b200b20104105742002102a210b0b200b0d0020024101102c000b200b20114105746a2202200329039803370000200241186a200a290300370000200241106a200f290300370000200241086a2013290300370000201141016a2111024002402016450d00201520084d0d0120092015417f6a22154105746a22022900002118200229000821192002290010211a200920084105746a220841186a200241186a2900003700002008201a37001020082019370008200820183700000b20142108200721100c020b4184e9c200200820151038000b200920154105746a2202200329039803370000200241186a200f290300370000200241106a2016290300370000200241086a2013290300370000201541016a2115200a450d00201120074d0d01200b2011417f6a22114105746a22022900002118200229000821192002290010211a200b20074105746a220741186a200241186a2900003700002007201a37001020072019370008200720183700000b200341bd036a2003290328370000200341a5036a200341c8006a41086a290300370000200341ad036a200341c8006a41106a290300370000200341b5036a200341c8006a41186a290300370000200341c5036a200341286a41086a290300370000200341cd036a200341286a41106a290300370000200341d5036a200341286a41186a290300370000200341013a009c03200341063a0098032003200329034837009d03200341e4036a2011360200200341e0036a2015360200200341dd036a200e3a000041c8ecc500410020034198036a107220034198036a41086a22024200370300200342003703980341edc1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082107200328029803220a417f460d022007450d022003200a36026c2003200736026820034198036a200341e8006a10302003280298032214450d01200341a0036a2802002102200328029c03210f0240200a450d002007102e0b200f450d032014102e0c030b4184e9c200200720111038000b41eff0c2004133200341a8046a4184f4c2001053000b410021020b024002400240024002400240024002400240201520124f220a0d004100200220116b2207200720024b1b2012490d00200341b4036a201136020020034198036a41186a201036020020034198036a41106a2015360200200341a4036a20083602002003200b3602ac03200320093602a0032003201236029c032003201736029803411a10292202450d01200241186a41002f00dec9423b0000200241106a41002900d6c942370000200241086a41002900cec942370000200241002900c6c9423700002003429a808080a003370294022003200236029002200341286a20034190026a10462003280294022107200328029802210a200328029002210220034190026a41186a220f420037030020034190026a41106a2214420037030020034190026a41086a2211420037030020034200370390022002200a20034190026a1000200341f0016a41186a200f290300370300200341f0016a41106a2014290300370300200341f0016a41086a201129030037030020032003290390023703f00120034120360294022003200341f0016a3602900220034198036a20034190026a108e0302402007450d002002102e0b02402008450d002009102e0b20100d050c060b0240200a0d00200341a5036a200341306a290300370000200341ad036a200341386a290300370000200341b5036a200341c0006a290300370000200341033a009c03200341063a0098032003200329032837009d0341c8ecc500410020034198036a10720c040b200341a5036a200341286a41086a290300370000200341ad036a200341286a41106a290300370000200341b5036a200341286a41186a290300370000200341023a009c03200341063a0098032003200329032837009d0341c8ecc500410020034198036a1072411e10292207450d01200741166a410029008ee842370000200741106a4100290088e842370000200741086a4100290080e842370000200741002900f8e7423700002003429e808080e00337029c032003200736029803200341286a20034198036a1046200328029c03211420032802a003210a200328029803210720034190026a41186a220f420037030020034190026a41106a2211420037030020034190026a41086a2215420037030020034200370390022007200a20034190026a1000200341f0016a41186a200f290300370300200341f0016a41106a2011290300370300200341f0016a41086a201529030037030020032003290390023703f0012003410036029803200341f0016a412020034198036a1008210f024002402003280298032211417f470d004113210a0c010b0240200f0d004113210a0c010b200320113602a4042003200f3602a00420034198036a200341a0046a10b80120032d009803220a4113460d0320034190026a20034198036a41017241870110f6041a02402011450d00200f102e0b200341f0016a412010060b200341e8006a20034190026a41870110f6041a0240200a4113470d002014450d042007102e0c040b20034190026a200341e8006a41870110f6041a02402014450d002007102e0b2003200a3a00980320034198036a41017220034190026a41870110f6041a200341f4006a2002360200200341e8006a41086a2012360200200341003a006c200341013a0068200341206a20034198036a200341e8006a10950220032802202102200341a5036a200341286a41086a290300370000200341ad036a200341386a290300370000200341b5036a200341c0006a290300370000200341bd036a2002453a0000200341043a009c03200341063a0098032003200329032837009d0341c8ecc500410020034198036a10720c030b411a4101102c000b411e4101102c000b41eff0c2004133200341a8046a4184f4c2001053000b411a10292202450d02200241186a41002f00dec9423b0000200241106a41002900d6c942370000200241086a41002900cec942370000200241002900c6c9423700002003429a808080a00337029c032003200236029803200341286a20034198036a1046200328029c03210a20032802a003210f200328029803210720034190026a41186a2214420037030020034190026a41106a2211420037030020034190026a41086a2202420037030020034200370390022007200f20034190026a1000200341f0016a41186a2014290300370300200341f0016a41106a2011290300370300200341f0016a41086a200229030037030020032003290390023703f001200341f0016a412010060240200a450d002007102e0b20034198036a41086a22074200370300200342003703980341a9c9c200411d20034198036a100320022007290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082107024002402003280298032202417f460d002003200236026c2003200736026820034198036a200341e8006a1030200328029803220a450d05200329029c03211802402002450d002007102e0b2003201837026c2003200a3602680c010b20034100360270200342013703680b200341e8006a200341286a103720034198036a41086a22024200370300200342003703980341a9c9c200411d20034198036a100320034190026a41086a20022903003703002003200329039803370390022003280268210a20032802702102200341003602a0032003420137039803200220034198036a104702402002450d0020024105742107200a21020340200220034198036a1046200241206a2102200741606a22070d000b0b200328029c03210220034190026a4110200328029803220720032802a003100402402002450d002007102e0b0240200328026c450d00200a102e0b02402008450d002009102e0b2010450d010b200b102e0b410021070c040b411a4101102c000b41eff0c2004133200341a8046a4184f4c2001053000b41ece8c2002107411621080b02402014450d002009102e0b2010450d00200b102e0b4101210a4101210b410121090c0b0b200141086a2802002109200141046a280200210e2002411a6a2901002118200241196a2d00002110200241186a2d00002114200241166a2f01002111200241156a2d00002115200241146a2d00002116200241126a2f01002117200241116a2d00002112200241106a2d000021132002410e6a2f010021062002410d6a2d0000210c200241046a2d0000210d200241026a2f01002105412a210841b5f0c20021070240024020022d0000450d004101210a4100210b4100210f0c010b4101210a4100210b4100210f20022d00014101470d002002410c6a2d0000210b2002410a6a2f0100210f200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d00004118747221074100210a0b200f41ffff0371410874200b41187472200841ff0171722108200a0d0520032018370340200320103a003f200320143a003e200320113b013c200320153a003b200320163a003a200320173b0138200320123a0037200320133a0036200320063b01342003200c3a00332003200836002f2003200736002b2003200d3a002a200320053b012820034198036a41086a22024200370300200342003703980341edc1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a1008210202400240024002402003280298032207417f460d002002450d002003200736026c2003200236026820034198036a200341e8006a10302003280298032208450d02200341a0036a280200210a200328029c03210b02402007450d002002102e0b2008200a200341286a108a0321020240200b450d002008102e0b2002450d010c030b41014100200341286a108a030d020b41c4e7c2002107411521080c070b41eff0c2004133200341a8046a4184f4c2001053000b200341003602a0032003420137039803200920034198036a10bc01200328029c03210720032802a0032108200328029803210220034190026a41186a220a420037030020034190026a41106a220b420037030020034190026a41086a220f420037030020034200370390022002200820034190026a1000200341c8006a41186a2208200a290300370300200341c8006a41106a220a200b290300370300200341c8006a41086a220b200f290300370300200320032903900237034802402007450d002002102e0b20034198036a41186a200829030037030020034198036a41106a200a29030037030020034198036a41086a200b290300370300200320032903483703980302400240024002400240024002400240411e10292202450d00200241166a410029008ee842370000200241106a4100290088e842370000200241086a4100290080e842370000200241002900f8e7423700002003429e808080e00337029402200320023602900220034198036a20034190026a104620032802940221072003280298022108200328029002210220034190026a41186a220a420037030020034190026a41106a220b420037030020034190026a41086a220f420037030020034200370390022002200820034190026a1000200341f0016a41186a200a290300370300200341f0016a41106a200b290300370300200341f0016a41086a200f29030037030020032003290390023703f001200341f0016a412041c8ecc500410041001005210802402007450d002002102e0b2008417f470d010240200e4102490d00200341186a4196e8c2004121107d200328021c210f20032802182110200341106a4196e8c2004121107d200328021021072003280214210820034198036a41086a2202420037030020034200370398034196e8c200412120034198036a100320034190026a41086a220a20022903003703002003200329039803370390022003200841016a410120071b3602980320034190026a411020034198036a4104100420024200370300200342003703980341a9c9c200411d20034198036a1003200a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082102200328029803220b417f460d042002450d042003200b36026c2003200236026820034198036a200341e8006a1030200328029803220a450d0320034198036a41086a22142802002107200328029c0321080240200b450d002002102e0b20034198036a41186a200341c8006a41186a29030037030020034198036a41106a200341c8006a41106a2903003703002014200341c8006a41086a290300370300200320032903483703980320034198036a210220072008470d070c060b20034198036a41086a22024200370300200342003703980341edc1c200411b20034198036a100320034190026a41086a200229030037030020032003290398033703900241002102200341003602980320034190026a411020034198036a1008210802402003280298032207417f460d002003200736026c2003200836026820034198036a200341e8006a1030200328029803220b450d05200341a0036a2802002102200328029c03210a02402007450d002008102e0b200a450d00200b102e0b20034198036a200941880110f6041a2003419c026a200236020020034190026a41086a4101360200200341003a009402200341013a009002200341086a20034198036a20034190026a10950220032802082102200341a5036a200341c8006a41086a290300370000200341ad036a200341d8006a290300370000200341b5036a200341e0006a290300370000200341bd036a2002453a0000200341043a009c03200341063a0098032003200329034837009d0320034198036a21020c070b411e4101102c000b41d9e7c2002107411f21080c0b0b41eff0c2004133200341a8046a4184f4c2001053000b20034198036a41186a200341c8006a41186a29030037030020034198036a41106a200341c8006a41106a29030037030020034198036a41086a200341c8006a41086a29030037030020032003290348370398034101210a4100210820034198036a21020c010b41eff0c2004133200341a8046a4184f4c2001053000b200841016a22072008490d022008410174220b20072007200b491b220b41ffffff3f71200b470d02200b41057422144100480d020240024020080d0020141029210a0c010b200a20084105742014102a210a0b20082107200b2108200a450d060b200a200741057422146a220b2002290000370000200b41186a200241186a290000370000200b41106a200241106a290000370000200b41086a200241086a29000037000020034198036a41086a22024200370300200342003703980341a9c9c200411d20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602a0032003420137039803200741016a220220034198036a1047024020022007490d00201441206a2107200a21020340200220034198036a1046200241206a2102200741606a22070d000b0b200328029c03210220034190026a4110200328029803220720032802a003100402402002450d002007102e0b02402008450d00200a102e0b200341e8006a41186a200341c8006a41186a290300370300200341e8006a41106a200341c8006a41106a290300370300200341e8006a41086a200341c8006a41086a2903003703002003200329034837036820034198036a200941880110f6041a411e10292202450d02200241166a410029008ee842370000200241106a4100290088e842370000200241086a4100290080e842370000200241002900f8e7423700002003429e808080e003370294022003200236029002200341e8006a20034190026a104620032802940221072003280298022108200328029002210220034190026a41186a220a420037030020034190026a41106a220b420037030020034190026a41086a2214420037030020034200370390022002200820034190026a1000200341f0016a41186a200a290300370300200341f0016a41106a200b290300370300200341f0016a41086a201429030037030020032003290390023703f0012003410036029802200342013703900220034198036a20034190026a10bc012003280294022108200341f0016a4120200328029002220a200328029802100402402008450d00200a102e0b02402007450d002002102e0b20034198036a102f412010292202450d0320022003290328370000200241186a200341286a41186a290300370000200241106a200341286a41106a290300370000200241086a200341286a41086a290300370000200341e8006a41186a200341c8006a41186a290300370300200341e8006a41106a200341c8006a41106a290300370300200341e8006a41086a200341c8006a41086a29030037030020032003290348370368200341b4036a4100360200200341a4036a428180808010370200200342013702ac03200320023602a0032003200e36029c032003200f410020101b220836029803411a10292207450d04200741186a41002f00dec9423b0000200741106a41002900d6c942370000200741086a41002900cec942370000200741002900c6c9423700002003429a808080a003370294022003200736029002200341e8006a20034190026a1046200328029402210a200328029802210b200328029002210720034190026a41186a220f420037030020034190026a41106a2210420037030020034190026a41086a2214420037030020034200370390022007200b20034190026a1000200341f0016a41186a200f290300370300200341f0016a41106a2010290300370300200341f0016a41086a201429030037030020032003290390023703f00120034120360294022003200341f0016a3602900220034198036a20034190026a108e030240200a450d002007102e0b2002102e200341a5036a200341286a41086a290300370000200341ad036a200341286a41106a290300370000200341b5036a200341286a41186a290300370000200341bd036a2003290348370000200341c5036a200341c8006a41086a290300370000200341cd036a200341c8006a41106a290300370000200341d5036a200341c8006a41186a290300370000200341e4036a200e360200200341e0036a2008360200200341003a009c03200341063a0098032003200329032837009d0320034198036a21020b4100210b41c8ecc5004100200210722009102e4101210a0c070b102d000b411e4101102c000b41204101102c000b411a4101102c000b20144101102c000b2009102f2009102e4100210b4101210a410121090c040b200141046a280200210941b5f0c2002107412a210820022d00000d0120022d00014101470d01200241196a2d00002107200241186a2d00002108200241166a2f0100210a200241156a2d0000210b200241146a2d0000210f200241126a2f01002110200241116a2d00002114200241106a2d000021112002410e6a2f010021152002410d6a2d000021162002410c6a2d000021172002410a6a2f01002112200241096a2d00002113200241086a2d00002106200241066a2f0100210c200241056a2d0000210d200241046a2d00002105200241026a2f0100210e20032002411a6a29010037038802200320073a008702200320083a0086022003200a3b0184022003200b3a0083022003200f3a008202200320103b018002200320143a00ff01200320113a00fe01200320153b01fc01200320163a00fb01200320053a00f2012003200e3b01f001200320132012410874201741187472723600f7012003200d200c410874722006411874723600f30120034198036a41086a22024200370300200342003703980341edc1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a1008210702400240024002402003280298032202417f460d002003200236026c2003200736026820034198036a200341e8006a10302003280298032208450d02200341a0036a280200210a200328029c03210b02402002450d002007102e0b2008200a200341f0016a108a0321020240200b450d002008102e0b2002450d010c030b41014100200341f0016a108a030d020b41c4e7c2002107411521080c030b41eff0c2004133200341a8046a4184f4c2001053000b4100210a200341003602a0032003420137039803200920034198036a10bc01200328029c03210720032802a0032108200328029803210220034190026a41186a220b420037030020034190026a41106a220f420037030020034190026a41086a2210420037030020034200370390022002200820034190026a1000200341e8006a41186a2208200b290300370300200341e8006a41106a2214200f290300370300200341e8006a41086a220f2010290300370300200320032903900237036802402007450d002002102e0b20034198036a200941880110f6041a20034190026a410d6a200341f0016a41086a29030037000020034190026a41156a200341f0016a41106a29030037000020034190026a411d6a200341f0016a41186a2903003700004101210b200341013a009402200320032903f00137009502200341013a009002200320034198036a20034190026a1095022003280200210220034198036a410d6a200f29030037000020034198036a41156a201429030037000020034198036a411d6a2008290300370000200341bd036a2002453a0000200341053a009c03200341063a0098032003200329036837009d0341c8ecc500410020034198036a10722009102e0b41012109410021070c020b2009102f2009102e4101210b4100210a410121090c010b410021094101210b410021070b02402004410771417f6a220241024b0d0002400240024020020e03000102000b2009450d02200141086a280200450d02200141046a280200102e0c020b200a450d01200141046a2802002202102f2002102e0c010b200b450d00200141086a2802002202102f2002102e0b2000200836020420002007360200200341b0046a24000bd3ac0107017f027e017f017e157f017e017f230041d0076b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e12000102030405060708090b0c0d0e0f101112000b200341c4036a4101360200200342013702b403200341cc91c5003602b0032003411c36028401200341c491c50036028001200320034180016a3602c003200341b0036a41d491c500106a000b200141106a2903002104200141086a2903002105200141046a28020021062002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d00002111200241046a2d00002112200241026a2f01002113024002400240024020022d0000450d002003200737028c05200320083a008b05200320093a008a052003200a3b018805410121020c010b2002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703880541012102201a41ff01714101460d010b412a21164100211441b5f0c200211a410021150c010b2018410874201972201741187472211a410021020b201541ffff0371410874201441187472201641ff017172211420020d452003200737039801200320083a009701200320093a0096012003200a3b0194012003200b3a0093012003200c3a0092012003200d3b0190012003200e3a008f012003200f3a008e01200320103b018c01200320113a008b0120032014360087012003201a36008301200320123a008201200320133b0180010240200542808084fea6dee1115441002004501b450d0041e491c500211a410d21140c460b200341106a20034180016a2005200410930102402003280210450d0041f191c500211a411a21140c460b200341086a41dc98c5004119107d200328020c211a200328020821164108211420034188056a41086a22154200370300200342003703880541dc98c500411920034188056a1003200341a8076a41086a2208201529030037030020032003290388053703a807410021022003201a410020161b221641016a3602b003200341a8076a4110200341b0036a4104100441201029221a450d11201a200329038001370000200341c4036a428180808010370200201a41186a20034180016a41186a2209290300370000201a41106a20034180016a41106a290300370000201a41086a20034180016a41086a290300370000200320053703b0032003201a3602c003200320043703b8032016200341b0036a10fe0320154200370300200342003703880541c7c9c400411520034188056a10032008201529030037030020032003290388053703a807200341b0036a200341a8076a10b0030240024020032802b003221a0d00410021150c010b200341b8036a280200210220032802b4032115201a21140b200341b0036a200610fd03200341e0006a41186a2009290300370300200341e0006a41106a220820034180016a41106a290300370300200341e0006a41086a220920034180016a41086a2903003703002003200329038001370360024020152002470d00200241016a221a2002490d3a20024101742215201a201a2015491b2215ad42b0017e2207422088a70d3a2007a7221a4100480d3a0240024020020d00201a102921140c010b2014200241b0016c201a102a21140b2014450d130b2014200241b0016c220a6a200341b0036a41880110f604221a201636028801201a200329036037028c01201a4194016a2009290300370200201a419c016a2008290300370200201a41a4016a200341f8006a29030037020020034188056a41086a221a4200370300200342003703880541c7c9c400411520034188056a1003200341a8076a41086a201a29030037030020032003290388053703a807200341103602b4032003200341a8076a3602b0032014200241016a221a200341b0036a10ff010240201a2002490d00200a41b0016a211a2014210203402002102f200241b0016a2102201a41d07e6a221a0d000b0b02402015450d002014102e0b200341c8036a2004370300200341c0036a2005370300200341bc036a201636020041002115200341b8036a41003a0000200341053a00b00341c8ecc5004100200341b0036a10722006102f2006102e4101210641012116410121084100211a0c460b200141046a280200210a2002411a6a2901002107200241196a2d00002116200241186a2d00002108200241166a2f01002109200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d00002111200241046a2d00002112200241026a2f01002113024002400240024020022d0000450d002003200737028c05200320163a008b05200320083a008a05200320093b018805410121020c010b2002410c6a2d000021142002410a6a2f01002106200241096a2d00002115200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703880541012102201a41ff01714101460d010b412a21154100211441b5f0c200211a410021060c010b2018410874201972201741187472211a410021020b200641ffff0371410874201441187472201541ff017172211420020d412003200737039801200320163a009701200320083a009601200320093b0194012003200b3a0093012003200c3a0092012003200d3b0190012003200e3a008f012003200f3a008e01200320103b018c01200320113a008b0120032014360087012003201a36008301200320123a008201200320133b018001200341b0036a200a10f103024020032802c00322020d00418b92c500211a41242114410121060c430b200341cc036a2802002115200341b0036a41186a280200211a20032802c4032106200341186a20034180016a20032902b403220742208620033502b003842204200341bc036a350200422086200742208884220710930120032802180d40200341e0006a41186a20034180016a41186a290300370300200341e0006a41106a220820034180016a41106a290300370300200341e0006a41086a220920034180016a41086a290300370300200320032903800137036002402006201a460d00200621160c3e0b200641016a22142006490d3820064101742216201420142016491b221641ffffff3f712016470d38201641057422144100480d380240024020060d002014102921020c010b200220064105742014102a21020b20020d3d20144101102c000b2002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002115024020022d0000450d002003200737028c052003201a3a008b05200320143a008a05200320153b0188050c3c0b200241156a2d00002116200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002117200241026a2f01002118200141026a2d00002119200141046a280200211b20022d0001210220012d0001211c200320073703880541012106200241ff01714101460d060c3b0b2002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002106024020022d0000450d002003200737028c052003201a3a008b05200320143a008a05200320063b0188050c3b0b200141026a2d00002118200141046a280200211920012d0001211b200241156a2d00002115200241146a2d00002116200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211720022d000121022003200737038805200241ff01714101470d3a20032007370398012003201a3a009701200320143a009601200320063b019401200320153a009301200320163a009201200320083b019001200320093a008f012003200a3a008e012003200b3b018c012003200c3a008b01200320133a008201200320173b0180012003200e410874200d41187472200f72360087012003201141087420127220104118747236008301200341b0036a20034180016a10ff0320032d00b0034101470d39200341bc036a2d00002102200341bd036a2900002107200341c5036a280000211a20032f00b103211420032d00b303210620032902b40321042003200341c9036a2900003703c8032003201a3602c403200320073702bc03200320023a00bb03200320043700b303200320063a00b203200320143b01b003200341b0036a2019201b41ff01714100472018108004211a41222114410121060c400b41bbb7c200211a410e211420022d0000417f6a220941024b0d3e200141046a280200210a410121064101211641012108410121150240024020090e03004401000b200241046a2d00000d3f41012106410121164101210841012115200241086a28020041036c2002410c6a280200410174490d430b200341b0036a200a108103024020032d00c0044103470d0041e596c500211a410d2114410121060c400b20032802b003210220034198026a200341b0036a41047241940110f6041a200320023602800120034180016a41047220034198026a41940110f6041a200341003602b803200342013703b00320034180016a200341b0036a10bc0120032802b403211a20032802b803211420032802b0032102200341a8076a41186a22064200370300200341a8076a41106a22154200370300200341a8076a41086a22164200370300200342003703a80720022014200341a8076a100020034198026a41186a2214200629030037030020034198026a41106a2206201529030037030020034198026a41086a22152016290300370300200320032903a807370398020240201a450d002002102e0b200341b0036a41186a2014290300370300200341b0036a41106a2006290300370300200341b0036a41086a201529030037030020032003290398023703b003411710292202450d0f2002410f6a41002900e39245370000200241086a41002900dc9245370000200241002900d4924537000020034297808080f0023702c406200320023602c006200341b0036a200341c0066a104620032802c406211a20032802c806211420032802c0062102200341a8076a41186a22064200370300200341a8076a41106a22154200370300200341a8076a41086a22164200370300200342003703a80720022014200341a8076a100020034188076a41186a200629030037030020034188076a41106a201529030037030020034188076a41086a2016290300370300200320032903a8073703880720034188076a412041c8ecc50041004100100521140240201a450d002002102e0b2014417f460d3720034180016a102f41f296c500211a41252114410121060c3f0b200141046a280200210641bbb7c200211a410e211420022d0000417f6a221541024b0d350240024020150e03003701000b200241086a2802004101742002410c6a280200490d36200241046a28020041ff01710d360b20034188056a41086a2202420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a221a200229030037030020032003290388053703a807200341a8076a411041c8ecc500410041001005417f460d30418593c500211a411521140c350b200141046a280200211a0240024020022d0000417f6a221441024b0d00024020140e03000102000b200241046a2d00000d00200241086a2802004102742002410c6a28020041036c4f0d010b201a102f201a102e41bbb7c200211a410e21144100211641012106410121080c3f0b200341b0036a201a41880110f6041a200341023a00b80420034188056a41086a2202420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a200229030037030020032003290388053703a80720034100360288012003420137038001200341b0036a20034180016a10bc01024020032d00b804220241024b0d00024002400240024020020e03000102000b410021140c020b410121140c010b410221140b200320143a00cf07024002402003280284012003280288012202460d0020032802800121060c010b200241016a22142002490d3520024101742206201420142006491b22144100480d350240024020020d002014102921060c010b20032802800120022014102a21060b2006450d102003201436028401200320063602800120032d00cf07211420032802880121020b2003200241016a36028801200620026a20143a00000b2003280284012102200341a8076a41102003280280012214200328028801100402402002450d002014102e0b200341b0036a102f201a102e41002116410121060c300b200141046a280200211a0240024020022d0000417f6a221441024b0d00024020140e03000102000b200241086a2802002002410c6a280200490d00200241046a28020041ff0171450d010b201a102f201a102e41bbb7c200211a410e21144100210841012106410121160c3e0b200341b0036a201a41880110f6041a200341013a00b80420034188056a41086a2202420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a200229030037030020032003290388053703a80720034100360288012003420137038001200341b0036a20034180016a10bc01024020032d00b804220241024b0d00024002400240024020020e03000102000b410021140c020b410121140c010b410221140b200320143a00cf07024002402003280284012003280288012202460d0020032802800121060c010b200241016a22142002490d3420024101742206201420142006491b22144100480d340240024020020d002014102921060c010b20032802800120022014102a21060b2006450d102003201436028401200320063602800120032d00cf07211420032802880121020b2003200241016a36028801200620026a20143a00000b2003280284012102200341a8076a41102003280280012214200328028801100402402002450d002014102e0b200341b0036a102f201a102e4100210841012106410121160c300b200141286a2802002108200141246a2802002116200341d8066a200141196a290000370300200341d0066a200141116a290000370300200341c0066a41086a200141096a290000370300200320012900013703c0064101210641bbb7c200211a410e211420022d0000417e6a221541014b0d3b0240024020150e020001000b200241046a2d00000d3c200241086a28020041036c2002410c6a280200410174490d3c0b20034188056a41086a2202420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a200229030037030020032003290388053703a807200341b0036a200341a8076a10b103024020032d00b80422024103470d0041d093c500211a411021140c3c0b20032802b003211a20034198026a200341b0036a41047241840110f6041a2003201a3602800120034180016a41047220034198026a41840110f6041a20020d2b41a693c500211a412a21140c2c0b200320073703c8032003201a3a00c703200320143a00c603200320153b01c403200320163a00c303200320083a00c203200320093b01c0032003200a3a00bf032003200b3a00be032003200c3b01bc032003200d3a00bb03200320173a00b203200320183b01b0032003200f410874200e411874722010723600b703200320124108742013722011411874723600b303200341b0036a201b201c41ff01714100472019108004211a412221140c3a0b20034190066a200141196a290000370300200341f8056a41106a200141116a290000370300200341f8056a41086a200141096a290000370300200320012900013703f80541bbb7c200211a410e211420022d00004102470d38200241236a2d00002115200241216a2f000021162002411f6a2d000021082002411d6a2f000021092002410f6a2d0000210a2002410d6a2f0000210b2002410b6a2d0000210c200241096a2f0000210d200241076a2d0000210e200241056a2f0000210f200241246a3502002105200241206a310000211d200241116a2900002107200241106a2d000021102002410c6a2d00002111200241086a2d00002112200241046a2d000021062003200241196a28000036029005200320073703880520064101470d382003200329028c0522043d01d006200320103a00cb06200320044238883c00d706200320044230883c00d606200320044220883d01d406200320044218883c00d306200320044210883c00d206200320073d01cc06200320074218883c00cf062003200b200a411074724108742011723600c7062003200d200c411074724108742012723600c3062003200f200e4110747222023b01c006200320024110763a00c20620032007a74110763a00ce062003201d4218862009200841107472ad42ffffff0783842016201541107472ad42ffffff0783422086842005423886843703d80620034188056a41086a2202420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a221a200229030037030020032003290388053703a807200341b0036a200341a8076a10b1030240024020032d00b8044103460d0020034180016a200341b0036a41880110f6041a200341b0036a20034180016a41880110f6041a200341003602a0022003420137039802200341b0036a20034198026a10bc01200328029c02211420032802a00221062003280298022102200341a8076a41186a22154200370300200341a8076a41106a22164200370300201a4200370300200342003703a80720022006200341a8076a100020034198026a41186a201529030037030020034198026a41106a201629030037030020034198026a41086a201a290300370300200320032903a8073703980202402014450d002002102e0b200341f8056a20034198026a412010f8042102200341b0036a102f2002450d0141102114418794c500211a410121060c3b0b4114211441f393c500211a410121060c3a0b200341b0036a200341f8056a10810420032802b40322150d264100210241012115420021070c270b4101210620022d000120022d0000720d24200141046a2802001085030c340b4101210620022d000120022d0000720d232001410c6a2802002115200141086a280200210220034180016a200141046a28020022161086032003280280012114024002400240200328028801221a20024d0d00201420024190016c6a22082d00004113460d01201420024190016c6a4188016a2802002015470d012008102f200841133a00002003280284012115411710292202450d0d2002410f6a410029008fc944370000200241086a4100290088c94437000020024100290080c94437000020024117412e102a2202450d0e20022016360017200341a8076a41186a22164200370300200341a8076a41106a22084200370300200341a8076a41086a22094200370300200342003703a8072002411b200341a8076a100020034188076a41186a201629030037030020034188076a41106a200829030037030020034188076a41086a2009290300370300200320032903a80737038807200341b0036a2014201a10be0120034188076a412020032802b003221620032802b8031004024020032802b403450d002016102e0b2002102e201a4190016c211a201421020340024020022d00004113460d002002102f0b20024190016a2102201a41f07e6a221a0d000b2015450d362014102e0c360b201a450d010b201a4190016c211a201421020340024020022d00004113460d002002102f0b20024190016a2102201a41f07e6a221a0d000b0b0240200328028401450d002014102e0b419797c500211a411221140c370b20034198026a41186a200141196a29000037030020034198026a41106a200141116a29000037030020034198026a41086a200141096a2900003703002003200129000137039802200241166a2f0100211a200241186a2d00002114200241196a2d000021062002411a6a2901002107024020022d0000450d002003200737028c05200320063a008b05200320143a008a052003201a3b0188050c310b200241026a2f01002115200241046a2d00002116200241056a2d00002108200241066a2f01002109200241086a2d0000210a200241096a2d0000210b2002410a6a2f0100210c2002410c6a2d0000210d2002410d6a2d0000210e2002410e6a2f0100210f200241106a2d00002110200241116a2d00002111200241126a2f01002112200241146a2d00002113200241156a2d0000211720022d000121022003200737038805200241ff01714101470d30410f10292202450d0b200241002900bd9445370000200241076a41002900c494453700002003428f808080f0013702b403200320023602b00320034198026a200341b0036a104a20032802b403211820032802b803211920032802b0032102200341a8076a41186a221b4200370300200341a8076a41106a221c4200370300200341a8076a41086a221e4200370300200342003703a80720022019200341a8076a100020034188076a41186a201b29030037030020034188076a41106a201c29030037030020034188076a41086a201e290300370300200320032903a8073703880720034188076a412041c8ecc500410041001005211902402018450d002002102e0b02402019417f460d0041cc94c500211a410f2114410121060c370b20034180016a41186a20034198026a41186a29030037030020034180016a41106a20034198026a41106a29030037030020034180016a41086a20034198026a41086a290300370300200320032903980237038001200320073703c803200320063a00c703200320143a00c6032003201a3b01c403200320173a00c303200320133a00c203200320123b01c003200320113a00bf03200320103a00be032003200f3b01bc032003200e3a00bb032003200c410874200b72200d411874723600b70320032009410874200872200a411874723600b303200320163a00b203200320153b01b003410f10292202450d0c4100211a200241002900bd9445370000200241076a41002900c494453700002003428f808080f0013702c406200320023602c00620034180016a200341c0066a104a20032802c406211420032802c806210620032802c0062102200341a8076a41186a22154200370300200341a8076a41106a22164200370300200341a8076a41086a22084200370300200342003703a80720022006200341a8076a100020034188076a41186a201529030037030020034188076a41106a201629030037030020034188076a41086a2008290300370300200320032903a80737038807200341203602c406200320034188076a3602c006200341b0036a200341c0066a109a0202402014450d002002102e0b410121060c360b2002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002106024020022d0000450d002003200737028c052003201a3a008b05200320143a008a05200320063b0188050c300b200241156a2d00002115200241146a2d00002116200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211720022d000121022003200737038805200241ff01714101470d2f200320073703c8032003201a3a00c703200320143a00c603200320063b01c403200320153a00c303200320163a00c203200320083b01c003200320093a00bf032003200a3a00be032003200b3b01bc032003200c3a00bb03200320133a00b203200320173b01b0032003200e410874200f72200d411874723600b703200320114108742012722010411874723600b303410f10292202450d0c4100211a200241002900bd9445370000200241076a41002900c494453700002003428f808080f001370284012003200236028001200341b0036a20034180016a104a200328028401211420032802880121062003280280012102200341a8076a41186a22154200370300200341a8076a41106a22164200370300200341a8076a41086a22084200370300200342003703a80720022006200341a8076a100020034188076a41186a201529030037030020034188076a41106a201629030037030020034188076a41086a2008290300370300200320032903a8073703880720034188076a4120100602402014450d002002102e0b410121060c320b200341c0066a41186a200141196a290000370300200341c0066a41106a200141116a290000370300200341c0066a41086a200141096a290000370300200320012900013703c0062002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002106024020022d0000450d002003200737028c052003201a3a008b05200320143a008a05200320063b0188050c2f0b200241156a2d00002115200241146a2d00002116200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211720022d000121022003200737038805200241ff01714101470d2e200320073703b0022003201a3a00af02200320143a00ae02200320063b01ac02200320153a00ab02200320163a00aa02200320083b01a802200320093a00a7022003200a3a00a6022003200b3b01a4022003200c3a00a302200320133a009a02200320173b0198022003200e410874200f72200d4118747236009f022003201141087420127220104118747236009b02200341b0036a200341c0066a10ff0320032d00b0034101470d2d200320032902b40337008301200320032d00b3033a008201200320032f00b1033b0180012003200341c9036a290000370398012003200341c5036a280000360294012003200341bd036a29000037028c012003200341bc036a2d00003a008b01024020034180016a20034198026a412010f804450d0041db94c500211a410b2114410121060c350b200341b0036a41186a200341c0066a41186a290300370300200341b0036a41106a200341c0066a41106a290300370300200341b0036a41086a200341c0066a41086a290300370300200320032903c0063703b003410f10292202450d0c4100211a200241002900bd9445370000200241076a41002900c494453700002003428f808080f001370284012003200236028001200341b0036a20034180016a104a200328028401211420032802880121062003280280012102200341a8076a41186a22154200370300200341a8076a41106a22164200370300200341a8076a41086a22084200370300200342003703a80720022006200341a8076a100020034188076a41186a201529030037030020034188076a41106a201629030037030020034188076a41086a2008290300370300200320032903a8073703880720034188076a4120100602402014450d002002102e0b410121060c340b200141216a2d0000210a200341c0006a41186a200141196a290000370300200341c0006a41106a200141116a290000370300200341c0006a41086a200141096a290000370300200320012900013703402002411a6a2901002107200241196a2d00002116200241186a2d00002108200241166a2f01002109200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d00002111200241046a2d00002112200241026a2f01002113024002400240024020022d0000450d002003200737028c05200320163a008b05200320083a008a05200320093b018805410121020c010b2002410c6a2d000021142002410a6a2f01002106200241096a2d00002115200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703880541012102201a41ff01714101460d010b41b5f0c200211a41002106412a2115410021140c010b2018410874201972201741187472211a410021020b200641ffff0371410874201541ff017172201441187472211420020d32200320143600cf042003201a3600cb04200320123a00ca04200320133b01c8042003200e3a00d7042003200f3a00d604200320103b01d404200320113a00d304200320163a00df04200320083a00de04200320093b01dc042003200b3a00db042003200c3a00da042003200d3b01d804200320073703e004200341e8046a41186a2007370300200341e8046a41106a20032903d804370300200341e8046a41086a200341c8046a41086a290300370300200320032903c8043703e80420034188056a41186a200341c0006a41186a29030037030020034188056a41106a200341c0006a41106a29030037030020034188056a41086a200341c0006a41086a2903003703002003200a3a00a8052003200329034037038805411510292202450d0c200241002900bec8443700002002410d6a41002900cbc844370000200241086a41002900c6c84437000020034295808080d0023702b403200320023602b003200341e8046a200341b0036a104a20032802b403210820032802b803210220032802b003211a200341a8076a41186a22064200370300200341a8076a41106a22164200370300200341a8076a41086a22154200370300200342003703a807201a2002200341a8076a100020034188076a41186a2209200629030037030020034188076a41106a201629030037030020034188076a41086a220a2015290300370300200320032903a8073703880720034198026a20034188076a10b2030240024020032d00b90222164102470d0020064200370300200341a8076a41106a2216420037030020154200370300200342003703a80741aac9c400411d200341a8076a10002009200629030037030020034188076a41106a22062016290300370300200a2015290300370300200320032903a80737038807200341f8056a20034188076a412010dc01024020032d00f8050d00200341a8076a41186a2215420037030020164200370300200341a8076a41086a22094200370300200342003703a80741aac9c400411d200341a8076a100020034188076a41186a20152903003703002006201629030037030020034188076a41086a2009290300370300200320032903a80737038807200341203602b403200320034188076a3602b003200341e8046a200341b0036a109a0241002106410021160c020b200341d8056a41186a20034191066a290000370300200341d8056a41106a20034189066a290000370300200341d8056a41086a20034181066a290000370300200320032900f9053703d805411510292206450d0f200641002900bec8443700002006410d6a41002900cbc844370000200641086a41002900c6c84437000020034295808080d0023702b403200320063602b003200341d8056a200341b0036a104a20032802b403210a20032802b803211620032802b0032115200341a8076a41186a22094200370300200341a8076a41106a22064200370300200341a8076a41086a220b4200370300200342003703a80720152016200341a8076a100020034188076a41186a200929030037030020034188076a41106a220c200629030037030020034188076a41086a200b290300370300200320032903a80737038807200341b0036a20034188076a10b20320032d00d1034102460d1020034180016a200341b0036a41e30010f6041a200341c0066a41206a220b20034180016a41206a22092d00003a0000200341c0066a41186a220d20034180016a41186a220e290300370300200341c0066a41106a220f20034180016a41106a2210290300370300200341c0066a41086a221120034180016a41086a221229030037030020032003290380013703c006200341b0036a200341a1016a41c20010f6041a2009200b2d00003a0000200e200d2903003703002010200f29030037030020122011290300370300200341a8016a200341d2036a410020032d00d1034101461b360200200320032903c006370380012003200341e8046a3602a401200341a8076a41186a220b420037030020064200370300200341a8076a41086a220d4200370300200342003703a80720152016200341a8076a100020034188076a41186a200b290300370300200c200629030037030020034188076a41086a200d290300370300200320032903a80737038807200341003602b007200342013703a80720034180016a200341a8076a104a024020092d0000220641064b0d000240024002400240024002400240024020060e0700010203040506000b410021160c060b410121160c050b410221160c040b410321160c030b410421160c020b410521160c010b410621160b200320163a00cf070240024020032802ac0720032802b0072206460d0020032802a80721090c010b200641016a22162006490d2d20064101742209201620162009491b22164100480d2d0240024020060d002016102921090c010b20032802a80720062016102a21090b2009450d13200320163602ac07200320093602a80720032d00cf07211620032802b00721060b2003200641016a3602b007200920066a20163a00000b0240024020032802a40122090d0041002109200341003a00cf070240024020032802ac0720032802b0072206460d0020032802a80721160c010b200641016a22162006490d2e20064101742209201620162009491b22094100480d2e0240024020060d002009102921160c010b20032802a80720062009102a21160b2016450d15200320093602ac07200320163602a80720032d00cf07210920032802b00721060b2003200641016a3602b007201620066a20093a00000c010b4101210b200341013a00cf070240024020032802ac0720032802b0072206460d0020032802a80721160c010b200641016a22162006490d2d2006410174220b20162016200b491b220b4100480d2d0240024020060d00200b102921160c010b20032802a8072006200b102a21160b2016450d152003200b3602ac07200320163602a80720032d00cf07210b20032802b00721060b2003200641016a3602b007201620066a200b3a00002009200341a8076a104a0b0240024020032802a80122090d0041002109200341003a00cf070240024020032802ac0720032802b0072206460d0020032802a80721160c010b200641016a22162006490d2e20064101742209201620162009491b22094100480d2e0240024020060d002009102921160c010b20032802a80720062009102a21160b2016450d17200320093602ac07200320163602a80720032d00cf07210920032802b00721060b2003200641016a3602b007201620066a20093a00000c010b4101210b200341013a00cf070240024020032802ac0720032802b0072206460d0020032802a80721160c010b200641016a22162006490d2d2006410174220b20162016200b491b220b4100480d2d0240024020060d00200b102921160c010b20032802a8072006200b102a21160b2016450d172003200b3602ac07200320163602a80720032d00cf07210b20032802b00721060b2003200641016a3602b007201620066a200b3a00002009200341a8076a104a0b20032802ac07210620034188076a412020032802a807221620032802b007100402402006450d002016102e0b0240200a450d002015102e0b200341a8076a41186a22064200370300200341a8076a41106a22154200370300200341a8076a41086a22164200370300200342003703a80741aac9c400411d200341a8076a100020034188076a41186a200629030037030020034188076a41106a201529030037030020034188076a41086a2016290300370300200320032903a80737038807200341203602b403200320034188076a3602b003200341e8046a200341b0036a109a02200341b8056a41086a200341d8056a41086a290300370300200341b8056a41106a200341d8056a41106a290300370300200341b8056a41186a200341d8056a41186a290300370300200320032903d8053703b80541012106410021160c010b200341e0006a41186a200341d2026a290100370300200341e0006a41106a200341ca026a290100370300200341e0006a41086a200341c2026a290100370300200341b8056a41086a200341e3026a290000370300200341b8056a41106a200341eb026a290000370300200341b8056a41186a200341f3026a290000370300200320032901ba023703602003200341db026a2900003703b805200341da026a2d000021060b200341d5036a20063a0000200341d6036a20032903b805370100200341bd036a200341e0006a41086a290300370000200341c5036a200341e0006a41106a290300370000200341cd036a200341e0006a41186a290300370000200341de036a200341b8056a41086a290300370100200341e6036a200341b8056a41106a290300370100200341ee036a200341b8056a41186a290300370100200320163a00b403200320032903603700b503200320034188056a3602b003200341a8076a41186a22064200370300200341a8076a41106a22154200370300200341a8076a41086a22164200370300200342003703a807201a2002200341a8076a100020034188076a41186a200629030037030020034188076a41106a201529030037030020034188076a41086a2016290300370300200320032903a807370388072003410036028801200342013703800120034188056a20034180016a104a024020032d00a805220241064b0d000240024002400240024002400240024020020e0700010203040506000b410021060c060b410121060c050b410221060c040b410321060c030b410421060c020b410521060c010b410621060b200320063a00cf07024002402003280284012003280288012202460d0020032802800121150c010b200241016a22062002490d2b20024101742215200620062015491b22064100480d2b0240024020020d002006102921150c010b20032802800120022006102a21150b2015450d162003200636028401200320153602800120032d00cf07210620032802880121020b2003200241016a36028801201520026a20063a00000b200341b0036a41047220034180016a10de03200328028401210220034188076a41202003280280012206200328028801100402402002450d002006102e0b02402008450d00201a102e0b200342e4cab5fbb6ccdcb0e3003703b005200341b0056a200341c8046a417f108f01200341b0036a41086a41083a0000200341b9036a20032903c804370000200341c1036a200341c8046a41086a290300370000200341c9036a200341c8046a41106a290300370000200341d1036a200341c8046a41186a290300370000200341d9036a2003290340370000200341e1036a200341c0006a41086a290300370000200341e9036a200341c0006a41106a290300370000200341f1036a200341c0006a41186a290300370000200341053a00b0034100211a41c8ecc5004100200341b0036a1072410121060c330b2002411a6a2901002107200241196a2d00002116200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d00002110200241046a2d00002111200241026a2f01002112024002400240024020022d0000450d002003200737028c05200320163a008b05200320083a008a05200320093b018805410121020c010b2002410c6a2d000021142002410a6a2f01002106200241096a2d00002115200241086a2d00002113200241066a2f01002117200241056a2d0000211820022d0001211a200320073703880541012102201a41ff01714101460d010b41b5f0c200211a41002106412a2115410021140c010b2017410874201872201341187472211a410021020b200641ffff0371410874201541ff017172201441187472211420020d31200320073703f005200320163a00ef05200320083a00ee05200320093b01ec052003200a3a00eb052003200b3a00ea052003200c3b01e8052003200d3a00e7052003200e3a00e6052003200f3b01e405200320103a00e305200320143600df052003201a3600db05200320113a00da05200320123b01d805411510292202450d14200241002900bec844370000410d21142002410d6a41002900cbc844370000200241086a41002900c6c84437000020034295808080d0023702b403200320023602b003200341d8056a200341b0036a104a20032802b403211a20032802b803210620032802b0032102200341a8076a41186a22154200370300200341a8076a41106a22164200370300200341a8076a41086a22084200370300200342003703a80720022006200341a8076a100020034188076a41186a201529030037030020034188076a41106a201629030037030020034188076a41086a2008290300370300200320032903a8073703880720034188076a412041c8ecc50041004100100521060240201a450d002002102e0b02402006417f470d0041d896c500211a410121060c330b411510292202450d15200241002900bec8443700002002410d6a41002900cbc844370000200241086a41002900c6c84437000020034295808080d0023702b403200320023602b003200341d8056a200341b0036a104a20032802b403210620032802b803210220032802b003211a200341a8076a41186a22144200370300200341a8076a41106a22154200370300200341a8076a41086a22164200370300200342003703a807201a2002200341a8076a100020034188076a41186a201429030037030020034188076a41106a201529030037030020034188076a41086a2016290300370300200320032903a80737038807200341b0036a20034188076a10b203024020032d00d10322024102460d0020034188076a412010060b20034188056a41186a200341b0036a41186a29030037030020034188056a41106a200341b0036a41106a29030037030020034188056a41086a200341b0036a41086a290300370300200320032903b0033703880520032d00d0032114200341f8056a200341d2036a41c10010f6041a02402006450d00201a102e0b200341b8056a41086a221a20034188056a41086a290300370300200341b8056a41106a220620034188056a41106a290300370300200341b8056a41186a221520034188056a41186a29030037030020032003290388053703b805200341c0066a200341f8056a41c10010f6041a20024102460d1c200341e0006a41186a2015290300370300200341e0006a41106a2006290300370300200341e0006a41086a201a290300370300200320032903b805370360200320023a00980220034198026a410172200341c0066a41c10010f6042108200341ba026a21060240024020032d00b9024101460d004100211a0c010b411510292202450d17200241002900bec8443700002002410d6a41002900cbc844370000200241086a41002900c6c84437000020034295808080d0023702b403200320023602b0032006200341b0036a104a20032802b803210a20032802b403211620032802b003211a20032d00980221020b02400240200241ff01714101470d00411510292202450d19200241002900bec8443700002002410d6a41002900cbc844370000200241086a41002900c6c84437000020034295808080d0023702b403200320023602b0032008200341b0036a104a20032802b403211520032802b00322020d010b20032d00b9022102200341a8076a41186a22084200370300200341a8076a41106a22094200370300200341a8076a41086a220b4200370300200342003703a80741aac9c400411d200341a8076a100020034188076a41186a200829030037030020034188076a41106a200929030037030020034188076a41086a200b290300370300200320032903a80737038807024020024101460d0020034188076a412010060c1c0b200341203602b403200320034188076a3602b0032006200341b0036a109a020c1b0b20032802b803210b200341a8076a41186a22084200370300200341a8076a41106a22094200370300200341a8076a41086a22064200370300200342003703a8072002200b200341a8076a100020034188076a41186a220c200829030037030020034188076a41106a220d200929030037030020034188076a41086a2006290300370300200320032903a80737038807200341b0036a20034188076a10b20320032d00d1034102460d1820034180016a200341b0036a41c20010f6041a20034180016a41c2006a200341b9026a2206290000370100200341ca016a200641086a290000370100200341d2016a200641106a290000370100200341da016a200641186a290000370100200341e2016a200641206a2d00003a00002008420037030020094200370300200341a8076a41086a22064200370300200342003703a8072002200b200341a8076a1000200c2008290300370300200d200929030037030020034188076a41086a2006290300370300200320032903a80737038807200341003602b803200342013703b00320034180016a200341b0036a104a024020032d00a001220641064b0d000240024002400240024002400240024020060e0700010203040506000b410021080c060b410121080c050b410221080c040b410321080c030b410421080c020b410521080c010b410621080b200320083a00a8070240024020032802b40320032802b8032206460d0020032802b00321090c010b200641016a22092006490d2a2006410174220b20092009200b491b220b4100480d2a0240024020060d00200b102921090c010b20032802b0032006200b102a21090b2009450d1b2003200b3602b403200320093602b00320032802b80321060b2003200641016a3602b803200920066a20083a00000b200341a1016a200341b0036a10de0320032802b403210620034188076a412020032802b003220820032802b803100402402006450d002008102e0b4101210b024020150d00410021150c1c0b2002102e0c1b0b41204101102c000b201a4108102c000b41174101102c000b20144101102c000b20144101102c000b41174101102c000b412e4101102c000b410f4101102c000b410f4101102c000b410f4101102c000b410f4101102c000b41154101102c000b41154101102c000b41e694c500419f01109b01000b20164101102c000b20094101102c000b200b4101102c000b20094101102c000b200b4101102c000b20064101102c000b41154101102c000b41154101102c000b41154101102c000b41154101102c000b418596c50041d300109b01000b200b4101102c000b410021024100210b0b02400240024002400240201a0d00410021060c010b200341a8076a41186a22064200370300200341a8076a41106a22084200370300200341a8076a41086a22094200370300200342003703a807201a200a200341a8076a100020034188076a41186a220c200629030037030020034188076a41106a220d200829030037030020034188076a41086a220e2009290300370300200320032903a80737038807200341b0036a20034188076a10b20320032d00d1034102460d0120034180016a200341b0036a41e30010f6041a200341a9016a20034198026a41086a290300370000200341b1016a20034198026a41106a290300370000200341b9016a20034198026a41186a290300370000200341c1016a20034198026a41206a2d00003a000020032003290398023700a101200642003703002008420037030020094200370300200342003703a807201a200a200341a8076a1000200c2006290300370300200d2008290300370300200e2009290300370300200320032903a80737038807200341003602b803200342013703b00320034180016a200341b0036a104a024020032d00a001220641064b0d000240024002400240024002400240024020060e0700010203040506000b410021080c060b410121080c050b410221080c040b410321080c030b410421080c020b410521080c010b410621080b200320083a00a8070240024020032802b40320032802b8032206460d0020032802b00321090c010b200641016a22092006490d122006410174220a20092009200a491b220a4100480d120240024020060d00200a102921090c010b20032802b0032006200a102a21090b2009450d042003200a3602b403200320093602b00320032802b80321060b2003200641016a3602b803200920066a20083a00000b200341a1016a200341b0036a10de0320032802b403210620034188076a412020032802b003220820032802b803100402402006450d002008102e0b410121062016450d00201a102e0b2015450d02200b200245720d022002102e0c020b418596c50041d300109b01000b200a4101102c000b02402016450d00201a452006720d00201a102e0b201441ff01714107470d010b410021140b200341386a41b0f3c200410d107d200342e4cab5fbb6ccdcb0e300370380014100211a20034180016a200341d8056a427f427f200328023c410020032802381b201441187441187541027441c098c5006a2802004180af1a6c6a4102109101200341b0036a41086a41093a0000200341b0036a41096a20032903d805370000200341c1036a200341d8056a41086a290300370000200341c9036a200341e8056a290300370000200341d1036a200341d8056a41186a290300370000200341053a00b00341c8ecc5004100200341b0036a1072410121060c140b418df0c200211a412821140c130b410021020240024020032903b8032207422088a7221a41014b0d00201a0e020201020b0340201a410176221420026a22062002201520064105746a200341c0066a412010f8044101481b2102201a20146b221a41014b0d000b0b201520024105746a200341c0066a412010f804221a450d01201a411f7620026a21020b200341b0036a41186a200341c0066a41186a290300370300200341b0036a41106a200341c0066a41106a290300370300200341b0036a41086a200341c0066a41086a290300370300200320032903c0063703b003024002400240024020022007422088a7221a4b0d000240201a2007a7470d00201a41016a2214201a490d0c201a4101742206201420142006491b221441ffffff3f712014470d0c201441057422064100480d0c02400240201a0d002006102921150c010b2015201a4105742006102a21150b2015450d022014ad21070b201520024105746a221441206a2014201a20026b41057410f7041a201441186a200341b0036a41186a290300370000201441106a200341b0036a41106a290300370000201441086a200341b0036a41086a290300370000201420032903b003370000200341306a41b0f3c200410d107d2003280234210620032802302116411310292202450d022002410f6a41002800ef9345360000200241086a41002900e89345370000200241002900e0934537000020034293808080b0023702b403200320023602b003200341f8056a200341b0036a104620032802b403210820032802b803210220032802b0032114200341a8076a41186a22094200370300200341a8076a41106a220a4200370300200341a8076a41086a220b4200370300200342003703a80720142002200341a8076a100020034188076a41186a200929030037030020034188076a41106a200a29030037030020034188076a41086a200b290300370300200320032903a80737038807410410292202450d0320034284808080c0003702b403200320023602b003200220064180ce186a4180ce1820161b2206360000201a41016a2202200341b0036a104702402002201a490d00201a41057441206a211a2015210203402002200341b0036a104a200241206a2102201a41606a221a0d000b0b20032802b403210220034188076a412020032802b003221a20032802b803100402402002450d00201a102e0b02402008450d002014102e0b02402007a7450d002015102e0b200341b0036a41086a410a3a0000200341b9036a20032903c006370000200341d9036a20032903f805370000200341c1036a200341c0066a41086a290300370000200341c9036a200341c0066a41106a290300370000200341d1036a200341c0066a41186a290300370000200341e1036a200341f8056a41086a290300370000200341e9036a200341f8056a41106a290300370000200341f1036a200341f8056a41186a290300370000200341053a00b003200341fc036a20063602004100211a41c8ecc5004100200341b0036a107220034188056a41086a2202420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a200229030037030020032003290388053703a807200341a8076a41101006410121060c150b41c0c6c5001058000b20064101102c000b41134101102c000b41044101102c000b419794c500211a412621142007a7450d0f2015102e410121060c100b200341003602b803200342013703b00320034180016a200341b0036a10bc0120032802b403211420032802b803211520032802b003211a200341a8076a41186a22094200370300200341a8076a41106a220a4200370300200341a8076a41086a220b4200370300200342003703a807201a2015200341a8076a1000200341b0036a41186a2009290300370300200341b0036a41106a200a290300370300200341b0036a41086a200b290300370300200320032903a8073703b00302402014450d00201a102e0b0240200341c0066a200341b0036a412010f804450d00419a93c500211a410c21140c010b20034188056a41086a221a420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a201a29030037030020032003290388053703a807200341a8076a41101006200341286a41b0f3c200410d107d200328022c211420032802282115200341b0036a20034180016a41880110f6041a4100211a20034198026a2014410020151b201641c0d102201641c0d1024b1b6a200341b0036a2002200810f00302402003280298024101470d00200328029c022202450d0020034198026a41086a28020021142002211a0c100b0c0f0b20034180016a102f0c0e0b200341003602b803200342013703b0032006200341b0036a10bc0120032802b403211420032802b803211520032802b0032102200341a8076a41186a22164200370300200341a8076a41106a22084200370300201a4200370300200342003703a80720022015200341a8076a100020034180016a41186a2215201629030037030020034180016a41106a200829030037030020034180016a41086a201a290300370300200320032903a8073703800102402014450d002002102e0b200341b0036a41186a2015290300370300200341b0036a41106a20034180016a41106a290300370300200341b0036a41086a20034180016a41086a29030037030020032003290380013703b00320034198026a200341b0036a1081040240200328029c022202450d00200328029802211a200341206a41b0f3c200410d107d2003280224410020032802201b2114024020032802a002450d002002102e0b2014201a4f0d0041eb92c500211a411a21140c050b200341b0036a200641880110f7041a200341003a00b80420034188056a41086a2202420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a200229030037030020032003290388053703a807200341003602a0022003420137039802200341b0036a20034198026a10bc01024020032d00b804220241024b0d00024002400240024020020e03000102000b4100211a0c020b4101211a0c010b4102211a0b2003201a3a00cf0702400240200328029c0220032802a0022202460d0020032802980221140c010b200241016a221a2002490d0520024101742214201a201a2014491b221a4100480d050240024020020d00201a102921140c010b2003280298022002201a102a21140b2014450d042003201a36029c02200320143602980220032d00cf07211a20032802a00221020b2003200241016a3602a002201420026a201a3a00000b200328029c022102200341a8076a4110200328029802221a20032802a002100402402002450d00201a102e0b200341b0036a102f2006102e41002106410121160b410121080b410121154100211a0c0e0b201a4101102c000b102d000b2006102f2006102e4101211641002106410121080c090b200341b0036a41186a20034198026a41186a290300370300200341b0036a41106a20034198026a41106a290300370300200341b0036a41086a20034198026a41086a29030037030020032003290398023703b003200341013a00f8050240411710292202450d004100211a2002410f6a41002900e39245370000200241086a41002900dc9245370000200241002900d4924537000020034297808080f0023702c406200320023602c006200341b0036a200341c0066a104620032802c406211420032802c806210620032802c0062102200341a8076a41186a22154200370300200341a8076a41106a22164200370300200341a8076a41086a22084200370300200342003703a80720022006200341a8076a100020034188076a41186a201529030037030020034188076a41106a201629030037030020034188076a41086a2008290300370300200320032903a8073703880720034188076a4120200341f8056a4101100402402014450d002002102e0b200a10850320034180016a102f410121060c050b41174101102c000b41c992c500211a410b2114410121060c060b41b5f0c200211a412a2114410121060c050b2002201a4105746a22142003290360370000201441186a200341e0006a41186a290300370000201441106a2008290300370000201441086a200929030037000041012106200341b0036a41186a201a41016a360200200341c4036a2016360200200320073703b803200320043703b003200320153602cc03200320023602c003200a200341b0036a10fe030b4100211a0b4101211641012108410121150c050b41af92c500211a411a21142006450d002002102e410121060c010b410121060b41012116410121080b410121150c010b2006102f2006102e410021154101210641012116410121080b0240024020012d0000417f6a2202410f4b0d00024002400240024020020e1000040404040102030404040405040505000b2015450d04200141046a2202280200102f2002280200102e0c040b2006450d03200141046a2202280200102f2002280200102e0c030b2016450d02200141046a2202280200102f2002280200102e0c020b2008450d01200141046a2202280200102f2002280200102e0c010b200241074b0d00024002400240024020020e080004040404010203000b200141046a2202280200102f2002280200102e0c030b200141046a2202280200102f2002280200102e0c020b200141046a2202280200102f2002280200102e0c010b200141046a2202280200102f2002280200102e0b200020143602042000201a360200200341d0076a24000bdda90106017f037e107f017e117f057e230041b0056b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0f000102030405060708090a0b0c0d0e000b20034184036a4101360200200342013702f402200341cc91c5003602f0022003411c3602cc01200341c491c5003602c8012003200341c8016a36028003200341f0026a4194c0c400106a000b200141306a2903002104200141286a29030021052001411d6a29000021062001411c6a2d000021072001411b6a2d00002108200141196a2f00002109200141186a2d0000210a200141176a2d0000210b200141156a2f0000210c200141146a2d0000210d200141136a2d0000210e200141116a2f0000210f200141106a2d000021102001410c6a2802002111200141086a2802002112200141076a2d00002113200141056a2f00002114200141046a2d0000211520012d000121162002411a6a2901002117200241196a2d00002118200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d0000211c200241126a2f0100211d200241116a2d0000211e200241106a2d0000211f2002410e6a2f010021202002410d6a2d00002121200241046a2d00002122200241026a2f01002123412a212441b5f0c20021250240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021272002410a6a2f01002128200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202841ffff0371410874202741187472202441ff017172212420260d3b200320173703e803200320183a00e703200320193a00e6032003201a3b01e4032003201b3a00e3032003201c3a00e2032003201d3b01e0032003201e3a00df032003201f3a00de03200320203b01dc03200320213a00db03200320243600d703200320253600d303200320223a00d203200320233b01d003410e10292202450d0d200241002900d9e743370000200241066a41002900dfe7433700002003428e808080e0013702f402200320023602f002200341d0036a200341f0026a104a20032802f402212520032802f802212420032802f0022102200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220022024200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a8023703880520034188056a412041c8ecc500410041001005212402402025450d002002102e0b02402024417f460d0041eec0c4002125411421240c3c0b0240201541ff01714101470d00200341f0026a201241067610bb0120032802f00221250240024020032802f8022012413f7122024b0d00410021020c010b202520024105746a2202290018210620022d0017210720022d0016210820022f0014210920022d0013210a20022d0012210b20022f0010210c20022d000f210d20022d000e210e20022f000c210f20022d000b2110200228000721112002280003211220022d0002211320022f00002114410121020b024020032802f402450d002025102e0b2002450d3b0b200320063703e001200320073a00df01200320083a00de01200320093b01dc012003200a3a00db012003200b3a00da012003200c3b01d8012003200d3a00d7012003200e3a00d6012003200f3b01d401200320103a00d301200320113600cf01200320123600cb01200320133a00ca01200320143b01c801410e10292202450d0e200241002900b1e843370000200241066a41002900b7e8433700002003428e808080e0013702f402200320023602f002200341c8016a200341f0026a104a20032802f402212520032802f802212420032802f0022102200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220022024200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a8023703880520034188056a412041c8ecc500410041001005212402402025450d002002102e0b2024417f470d3902402005428080e983b1de165441002004501b450d0041bdc0c4002125413121240c3c0b200341f0026a41186a200341c8016a41186a290300370300200341f0026a41106a200341c8016a41106a290300370300200341f0026a41086a200341c8016a41086a290300370300200320032903c8013703f002410e10292202450d0f200241002900d9e743370000200241066a41002900dfe7433700002003428e808080e0013702ac02200320023602a802200341d0036a200341a8026a104a20032802ac02212520032802b002212420032802a8022102200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220022024200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a80237038805200341203602ac02200320034188056a3602a802200341f0026a200341a8026a109a0202402025450d002002102e0b410d10292202450d10200241002900bfe843370000200241056a41002900c4e8433700002003428d808080d0013702f402200320023602f002200341d0036a200341f0026a104a20032802f402212420032802f802210220032802f0022125200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220252002200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a80237038805024002400240024002400240201641037122024103460d0020020e03010203010b20034188056a41204101410010040c040b200341003a00ac050c020b200341013a00ac050c010b200341023a00ac050b410110292202450d12200220032d00ac053a000020034188056a41202002410110042002102e0b02402024450d002025102e0b411410292202450d12200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702f402200320023602f002200341d0036a200341f0026a104a20032802f4022102200341086a20032802f002222420032802f802106e200341086a41106a2903004200200328020822251b21172003290310420020251b210602402002450d002024102e0b20034198036a4100360200200341a4036a200341d0036a41086a290300370200200341ac036a200341d0036a41106a290300370200200341b4036a200341d0036a41186a290300370200200341f0026a41186a201720042006200554201720045420172004511b22021b2217370300200320032903d00337029c03200342083703900320032006200520021b220637038003200320173703f802200320063703f002200341c8016a200341f0026a10ec0320034194036a280200450d38200328029003102e0c380b20022d00000d3620022d00014101470d36200141106a2903002117200141086a2903002106200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002118200241116a2d00002119200241106a2d0000211a2002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f0100211220032002411a6a2901003703b804200320253a00b704200320243a00b604200320263b01b404200320273a00b304200320283a00b204200320183b01b004200320193a00af042003201a3a00ae042003201b3b01ac042003201c3a00ab04200320233a00a204200320123b01a0042003201f201e410874201d41187472723600a704200320222021410874722020411874723600a304200341f0026a200341a0046a108202024020032d00f0024101460d004192c1c4002125410b21240c3b0b200320032902f4023700ab02200320032d00f3023a00aa02200320032f00f1023b01a802200320034189036a2900003703c002200320034185036a2800003602bc022003200341fd026a2900003702b4022003200341f0026a410c6a22022d00003a00b302200341f0026a200341a8026a1083022003280290032224450d3520034188056a41086a200341f0026a41346a2902002204370300200341d0036a41086a22262004370300200341d0036a41106a2227200341f0026a413c6a290200370300200341d0036a41186a2228200341f0026a41c4006a29020037030020032003419c036a290200220437038805200320043703d003200341bc036a2802002118200341f0026a41286a28020021192002350200210420032802f002210220032902f402210520032903800321292003280294032125200341c8016a41186a200341f0026a41186a290300222a370300200341c8016a410c6a20043e0200200341c8016a41286a2019360200200341ec016a2025360200200320293703d801200320053702cc01200320243602e801200320023602c801200341c8016a41c4006a2028290300370200200341c8016a413c6a2027290300370200200341c8016a41346a2026290300370200200320032903d0033702f4012003201836029402411410292202450d12200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702f402200320023602f002200341a0046a200341f0026a104a20032802f4022102200341206a20032802f002222620032802f802106e200341206a41106a2903004200200328022022241b21042003290328420020241b210502402002450d002026102e0b200520032903c801222b7d222c2005562004200341d0016a290300222d7d2005202b54ad7d220520045620052004511b450d330c340b200141106a2903002106200141086a29030021042002411a6a2901002117200241196a2d00002118200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d0000211c200241126a2f0100211d200241116a2d0000211e200241106a2d0000211f2002410e6a2f010021202002410d6a2d00002121200241046a2d00002122200241026a2f01002123412a212441b5f0c20021250240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021272002410a6a2f01002128200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202841ffff0371410874202741187472202441ff017172212420260d39200320173703c002200320183a00bf02200320193a00be022003201a3b01bc022003201b3a00bb022003201c3a00ba022003201d3b01b8022003201e3a00b7022003201f3a00b602200320203b01b402200320213a00b302200320243600af02200320253600ab02200320223a00aa02200320233b01a802200341f0026a200341a8026a1083022003280290032226450d3420034188056a41086a200341f0026a41346a2902002217370300200341d0036a41086a22242017370300200341e0036a2227200341f0026a413c6a290200370300200341d0036a41186a2228200341f0026a41c4006a29020037030020032003419c036a290200221737038805200320173703d003200341bc036a2802002118200341f0026a41286a2802002125200341f0026a410c6a350200212920032802f002211920032902f402212b20032903800321172003280294032102200341c8016a41186a200341f0026a41186a2903002205370300200341c8016a410c6a20293e0200200341c8016a41286a2025360200200341ec016a2002360200200320173703d8012003202b3702cc01200320263602e801200320193602c801200341c8016a41c4006a2028290300370200200341c8016a413c6a2027290300370200200341c8016a41346a2024290300370200200320032903d0033702f401200320183602940202400240024002402025411f4b0d00201720042017200454200520065420052006511b22241b22042005200620241b220684500d03200341c8016a41186a4200200520067d2017200454ad7d2229201720047d222b428080e983b1de165441002029501b22241b37030020034200202b20241b3703d801200341386a41e49ac5004112107d200328023c21272003280238212820252002470d02200241016a22252002490d3520024101742218202520252018491b2218ad42187e2229422088a70d352029a7222541004e0d010c350b419dc1c4002125412321242002450d3c2026102e0c3c0b0240024020020d002025102921260c010b2026200241186c2025102a21260b2026450d14200320183602ec01200320263602e80120032802f00121250b2026202541186c6a22022005200620241b37030820022017200420241b3703002002202741a0056a41a00520281b360210200320032802f00141016a3602f001200341a8026a200341c8016a10ec0320032802ec0121020b2002450d3620032802e801102e0c360b41b5f0c2002125412a212420022d00000d3820022d00014101470d38200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002118200241116a2d00002119200241106a2d0000211a2002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f0100211220032002411a6a2901003703e803200320253a00e703200320243a00e603200320263b01e403200320273a00e303200320283a00e203200320183b01e003200320193a00df032003201a3a00de032003201b3b01dc032003201c3a00db03200320233a00d203200320123b01d0032003201f201e410874201d41187472723600d703200320222021410874722020411874723600d303200341f0026a200341d0036a1083022003280290032218450d33200341d0006a41086a200341a4036a290200370300200341d0006a41106a200341ac036a290200370300200341d0006a41186a200341b4036a29020037030020032003419c036a290200370350200341f0026a41186a290300212920034198036a280200211a200341fc026a3502002117200329038003212b200328029403211b20033502f002210420032902f4022106200341c8006a41e49ac5004112107d410021282017422086200642208884211720042006422086842106024002400240201a41186c2202450d00200328024c410020032802481b2126201820026a2127201a41186c41686a2125201821020340200241086a2903002105200229030021042026200241106a2802002224490d024200201720057d2006200454ad7d2205200620047d2204200656200520175620052017511b22241b21174200200420241b2106202541686a2125200241186a22022027470d000b0b410821190240201b0d00410021240c020b2018102e410021240c010b411810292219450d132019200437030020192024360210201920053703080240024020250d0041012128410121240c010b200241186a211c201a41186c20186a41686a211d41012128410121240340201c210202400340200241086a2903002105200229030021042026200241106a2802002225490d014200201720057d2006200454ad7d2205200620047d2204200656200520175620052017511b22251b21174200200420251b2106200241186a22022027470d000c030b0b024020242028470d00202841016a22242028490d342028410174221a20242024201a491b2224ad42187e222c422088a70d34202ca7221a4100480d340240024020280d00201a102921190c010b2019202841186c201a102a21190b2019450d170b200241186a211c2019202841186c6a221a2005370308201a2004370300201a2025360210202841016a2128201d2002470d000b0b201b450d002018102e0b20034198036a202836020020034194036a20243602002003202b37038003200341f0026a41186a2029370300200341b4036a200341d0006a41186a290300370200200341ac036a200341e0006a290300370200200341a4036a200341d8006a290300370200200320063703f0022003200329035037029c032003201936029003200320173703f8020240202b2029844200520d002028450d280b200341d0036a200341f0026a10ec030c2f0b200141106a2903002106200141086a2903002104200141186a28020021122002411a6a2901002117200241196a2d00002118200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d0000211c200241126a2f0100211d200241116a2d0000211e200241106a2d0000211f2002410e6a2f010021202002410d6a2d00002121200241046a2d00002122200241026a2f0100212341b5f0c2002125412a21240240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021282002410a6a2f01002127200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202741ffff0371410874202441ff017172202841187472212420260d372003201737038801200320183a008701200320193a0086012003201a3b0184012003201b3a0083012003201c3a0082012003201d3b0180012003201e3a007f2003201f3a007e200320203b017c200320213a007b2003202436007720032025360073200320223a0072200320233b0170200341f0026a200341f0006a1083022003280290032202450d3220034188056a41086a200341f0026a41346a2902002217370300200341c8016a41086a22252017370300200341d8016a2224200341f0026a413c6a290200370300200341c8016a41186a2227200341f0026a41c4006a2902003703002003200341f0026a412c6a290200221737038805200320173703c801200341bc036a2802002128200341f0026a41286a2802002118200341f0026a410c6a350200211720032802f002211920032902f402210520032903800321292003280294032126200341d0036a41186a200341f0026a41186a290300370300200341d0036a410c6a20173e0200200341d0036a41286a2018360200200341f4036a2026360200200320293703e003200320053702d403200320023602f003200320193602d003200341d0036a41c4006a2027290300370200200341d0036a413c6a2024290300370200200341d0036a41346a2025290300370200200320032903c8013702fc032003202836029c0402402012410a4b0d00200341d0036a412c6a222810dc0320032006370398012003200437039001200320123602a001411210292202450d1420024100290090e843370000200241106a41002f00a0e8433b0000200241086a4100290098e84337000020034292808080a0023702f402200320023602f0022028200341f0026a104a20032802f402211920032802f802212720032802f0022102200341a8026a41186a22254200370300200341a8026a41106a22244200370300200341a8026a41086a22264200370300200342003703a80220022027200341a8026a100020034188056a41186a221a202529030037030020034188056a41106a221b202429030037030020034188056a41086a221c2026290300370300200320032903a80237038805200341c8016a20034188056a10ad030240024020032d00e00122184102470d00202542003703002024420037030020264200370300200342003703a80241f8e8c300411a200341a8026a1000201a2025290300370300201b2024290300370300201c2026290300370300200320032903a80237038805200341a0046a20034188056a412010dc01024020032d00a0040d00200341a8026a41186a22254200370300200341a8026a41106a22244200370300200341a8026a41086a22264200370300200342003703a80241f8e8c300411a200341a8026a100020034188056a41186a202529030037030020034188056a41106a202429030037030020034188056a41086a2026290300370300200320032903a80237038805200341203602f402200320034188056a3602f0022028200341f0026a109a0241002125410021180c020b200341c8046a41186a200341b9046a290000370300200341c8046a41106a200341b1046a290000370300200341c8046a41086a200341a9046a290000370300200320032900a1043703c804411210292225450d1720254100290090e843370000202541106a41002f00a0e8433b0000202541086a4100290098e84337000020034292808080a0023702f402200320253602f002200341c8046a200341f0026a104a20032802f402212620032802f802212520032802f0022124200341a8026a41186a22184200370300200341a8026a41106a221a4200370300200341a8026a41086a221b4200370300200342003703a80220242025200341a8026a100020034188056a41186a201829030037030020034188056a41106a201a29030037030020034188056a41086a201b290300370300200320032903a80237038805200341f0026a20034188056a10ad0320032d0088034102460d18200341f0026a41086a2903002117200328028003211820032903f0022106200341a8026a20034184036a41c60010f6041a200341f0026a200341ac026a41c20010f6041a20034184056a20034192036a410020032d0091034101461b360200200320173703f004200320063703e8042003202836028005200320183602f804200341a8026a41186a22184200370300200341a8026a41106a221a4200370300200341a8026a41086a221b4200370300200342003703a80220242025200341a8026a100020034188056a41186a201829030037030020034188056a41106a201a29030037030020034188056a41086a201b290300370300200320032903a80237038805200341003602b002200342013703a802200341e8046a41106a200341a8026a10662003200341e8046a3602ac05200341ac056a200341a8026a106b02400240200328028005221a0d004100211a200341003a00ac050240024020032802ac0220032802b0022225460d0020032802a80221180c010b202541016a22182025490d352025410174221a20182018201a491b221a4100480d350240024020250d00201a102921180c010b20032802a8022025201a102a21180b2018450d1c2003201a3602ac02200320183602a80220032d00ac05211a20032802b00221250b2003202541016a3602b002201820256a201a3a00000c010b200341013a00ac050240024020032802ac0220032802b0022225460d004101211b20032802a80221180c010b202541016a22182025490d342025410174221b20182018201b491b221b4100480d340240024020250d00201b102921180c010b20032802a8022025201b102a21180b2018450d1c2003201b3602ac02200320183602a80220032d00ac05211b20032802b00221250b2003202541016a3602b002201820256a201b3a0000201a200341a8026a104a0b02400240200328028405221a0d004100211a200341003a00ac050240024020032802ac0220032802b0022225460d0020032802a80221180c010b202541016a22182025490d352025410174221a20182018201a491b221a4100480d350240024020250d00201a102921180c010b20032802a8022025201a102a21180b2018450d1e2003201a3602ac02200320183602a80220032d00ac05211a20032802b00221250b2003202541016a3602b002201820256a201a3a00000c010b4101211b200341013a00ac050240024020032802ac0220032802b0022225460d0020032802a80221180c010b202541016a22182025490d342025410174221b20182018201b491b221b4100480d340240024020250d00201b102921180c010b20032802a8022025201b102a21180b2018450d1e2003201b3602ac02200320183602a80220032d00ac05211b20032802b00221250b2003202541016a3602b002201820256a201b3a0000201a200341a8026a104a0b20032802ac02212520034188056a412020032802a802221820032802b002100402402025450d002018102e0b02402026450d002024102e0b200341a8026a41186a22254200370300200341a8026a41106a22244200370300200341a8026a41086a22264200370300200342003703a80241f8e8c300411a200341a8026a100020034188056a41186a202529030037030020034188056a41106a202429030037030020034188056a41086a2026290300370300200320032903a80237038805200341203602f402200320034188056a3602f0022028200341f0026a109a02200341a8016a41086a200341c8046a41086a290300370300200341a8016a41106a200341c8046a41106a290300370300200341a8016a41186a200341c8046a41186a290300370300200320032903c8043703a80141012125410021180c010b200341d0006a41186a200341f9016a290000370300200341d0006a41106a200341f1016a290000370300200341d0006a41086a200341e9016a290000370300200341a8016a41086a2003418a026a290100370300200341a8016a41106a20034192026a290100370300200341a8016a41186a2003419a026a2901003703002003200341e1016a290000370350200320034182026a2901003703a80120034181026a2d000021250b20034195036a20253a000020034196036a20032903a801370100200341fd026a200341d0006a41086a29030037000020034185036a200341d0006a41106a2903003700002003418d036a200341d0006a41186a2903003700002003419e036a200341a8016a41086a290300370100200341a6036a200341a8016a41106a290300370100200341ae036a200341a8016a41186a290300370100200320183a00f402200320032903503700f502200320034190016a3602f002200341a8026a41186a22254200370300200341a8026a41106a22244200370300200341a8026a41086a22264200370300200342003703a80220022027200341a8026a100020034188056a41186a202529030037030020034188056a41106a202429030037030020034188056a41086a2026290300370300200320032903a80237038805200341003602d001200342013703c80120032802f002222541106a200341c8016a1066200320253602a802200341a8026a200341c8016a106b0240024020032d00f4024101460d00200341003a00ac050240024020032802cc0120032802d0012225460d004100212620032802c80121240c010b202541016a22242025490d3320254101742226202420242026491b22264100480d330240024020250d002026102921240c010b20032802c80120252026102a21240b2024450d1e200320263602cc01200320243602c80120032d00ac05212620032802d00121250b2003202541016a3602d001202420256a20263a00000c010b200341013a00ac050240024020032802cc0120032802d0012225460d004101212620032802c80121240c010b202541016a22242025490d3220254101742226202420242026491b22264100480d320240024020250d002026102921240c010b20032802c80120252026102a21240b2024450d1e200320263602cc01200320243602c80120032d00ac05212620032802d00121250b2003202541016a3602d001202420256a20263a0000200341f0026a410572200341c8016a104a0b0240024020032d0095034101460d0041002126200341003a00ac050240024020032802cc0120032802d0012225460d0020032802c80121240c010b202541016a22242025490d3320254101742226202420242026491b22264100480d330240024020250d002026102921240c010b20032802c80120252026102a21240b2024450d20200320263602cc01200320243602c80120032d00ac05212620032802d00121250b2003202541016a3602d001202420256a20263a00000c010b200341013a00ac050240024020032802cc0120032802d0012225460d004101212620032802c80121240c010b202541016a22242025490d3220254101742226202420242026491b22264100480d320240024020250d002026102921240c010b20032802c80120252026102a21240b2024450d20200320263602cc01200320243602c80120032d00ac05212620032802d00121250b2003202541016a3602d001202420256a20263a000020034196036a200341c8016a104a0b20032802cc01212520034188056a412020032802c801222420032802d001100402402025450d002024102e0b02402019450d002002102e0b20032802f403450d3520032802f003102e0c350b41c0c1c4002125411b21242026450d372002102e0c370b2001410c6a2802002118200141086a280200211d200141046a280200211c2002411a6a2901002117200241196a2d00002119200241186a2d0000211a200241166a2f0100211b200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d00002112200241046a2d00002107200241026a2f0100210841b5f0c2002125412a21240240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021282002410a6a2f01002127200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202741ffff0371410874202441ff017172202841187472212420260d2c200320173703e004200320193a00df042003201a3a00de042003201b3b01dc042003201e3a00db042003201f3a00da04200320203b01d804200320213a00d704200320223a00d604200320233b01d404200320123a00d304200320243600cf04200320253600cb04200320073a00ca04200320083b01c804200341f0026a200341c8046a108302024020032802900322250d00411021244182c1c40021250c2d0b20034188056a41086a200341f0026a41346a2902002217370300200341c8016a41086a22242017370300200341c8016a41106a2226200341f0026a413c6a290200370300200341c8016a41186a2227200341f0026a41c4006a2902003703002003200341f0026a412c6a290200221737038805200320173703c801200341bc036a2802002128200341f0026a41286a2802002119200341f0026a410c6a350200211720032802f002211a20032902f402210620032903800321042003280294032102200341d0036a41186a200341f0026a41186a290300370300200341d0036a410c6a20173e0200200341d0036a41286a2019360200200341d0036a41246a2002360200200320043703e003200320063702d403200320253602f0032003201a3602d003200341d0036a41c4006a2027290300370200200341d0036a413c6a2026290300370200200341d0036a41346a2024290300370200200320032903c8013702fc032003202836029c0420180d2a41dbc1c400212541172124410121260c2b0b20022d00000d3120022d00014101470d31200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002118200241116a2d00002119200241106a2d0000211a2002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f0100211220032002411a6a2901003703c002200320253a00bf02200320243a00be02200320263b01bc02200320273a00bb02200320283a00ba02200320183b01b802200320193a00b7022003201a3a00b6022003201b3b01b4022003201c3a00b302200320233a00aa02200320123b01a8022003201f201e41087472201d411874723600af02200320222021410874722020411874723600ab02200341f0026a200341a8026a1083022003280290032202450d3020034188056a41086a200341f0026a41346a2902002217370300200341d0036a41086a22252017370300200341e0036a2224200341f0026a413c6a290200370300200341d0036a41186a2226200341f0026a41c4006a2902003703002003200341f0026a412c6a290200221737038805200320173703d003200341bc036a2802002127200341f0026a410c6a350200211720032802f002212820032902f402210620032903800321042003290294032105200341c8016a41186a200341f0026a41186a290300370300200341c8016a410c6a20173e0200200341ec016a22182005370200200320043703d801200320063702cc01200320023602e801200320283602c801200341c8016a41c4006a2026290300370200200341c8016a413c6a2024290300370200200341c8016a41346a2025290300370200200320032903d0033702f4012003202736029402200341c8016a412c6a220210db03200210dc032018280200450d3220032802e801102e0c320b20022d00000d3020022d00014101470d3020012d00012107200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002118200241116a2d00002119200241106a2d0000211a2002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f0100211220032002411a6a2901003703b804200320253a00b704200320243a00b604200320263b01b404200320273a00b304200320283a00b204200320183b01b004200320193a00af042003201a3a00ae042003201b3b01ac042003201c3a00ab04200320233a00a204200320123b01a0042003201f201e41087472201d411874723600a704200320222021410874722020411874723600a304200341f0026a200341a0046a1083022003280290032202450d2f20034188056a41086a200341f0026a41346a2902002217370300200341d0036a41086a22252017370300200341d0036a41106a2224200341f0026a413c6a290200370300200341d0036a41186a2226200341f0026a41c4006a2902003703002003200341f0026a412c6a290200221737038805200320173703d003200341bc036a2802002127200341f0026a410c6a350200211720032802f002212820032902f402210620032903800321042003290294032105200341c8016a41186a200341f0026a41186a290300370300200341c8016a410c6a20173e0200200341ec016a2005370200200320043703d801200320063702cc01200320023602e801200320283602c801200341c8016a41c4006a2026290300370200200341c8016a413c6a2024290300370200200341c8016a41346a2025290300370200200320032903d0033702f4012003202736029402410d10292202450d1b200241002900bfe843370000200241056a41002900c4e8433700002003428d808080d0013702f402200320023602f002200341c8016a412c6a200341f0026a104a20032802f402212420032802f802210220032802f0022125200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220252002200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a80237038805024002400240024002400240200741037122024103460d0020020e03010203010b20034188056a41204101410010040c040b200341003a00ac050c020b200341013a00ac050c010b200341023a00ac050b410110292202450d1d200220032d00ac053a000020034188056a41202002410110042002102e0b02402024450d002025102e0b20032802ec01450d3120032802e801102e0c310b2001411d6a29000021062001411c6a2d000021072001411b6a2d00002108200141196a2f00002109200141186a2d0000210a200141176a2d0000210b200141156a2f0000210c200141146a2d0000210d200141136a2d0000210e200141116a2f0000210f200141106a2d000021102001410c6a2802002111200141086a2802002118200141076a2d00002113200141056a2f00002114200141046a2d000021152002411a6a2901002117200241196a2d00002119200241186a2d0000211a200241166a2f0100211b200241156a2d0000211c200241146a2d0000211d200241126a2f0100211e200241116a2d0000211f200241106a2d000021202002410e6a2f010021212002410d6a2d00002122200241046a2d00002123200241026a2f0100211241b5f0c2002125412a21240240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021282002410a6a2f01002127200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202741ffff0371410874202441ff017172202841187472212420260d33200320173703e004200320193a00df042003201a3a00de042003201b3b01dc042003201c3a00db042003201d3a00da042003201e3b01d8042003201f3a00d704200320203a00d604200320213b01d404200320223a00d304200320243600cf04200320253600cb04200320233a00ca04200320123b01c804200341f0026a200341c8046a10820241012126024020032d00f0024101460d004192c1c4002125410b2124410121270c350b200320032902f4023700eb04200320032d00f3023a00ea04200320032f00f1023b01e804200320034189036a29000037038005200320034185036a2800003602fc042003200341fd026a2900003702f4042003200341fc026a2d00003a00f3040240201541ff01714101470d00200341f0026a201841067610bb0120032802f00221250240024020032802f8022018413f7122024b0d00410021020c010b202520024105746a2202290018210620022d0017210720022d0016210820022f0014210920022d0013210a20022d0012210b20022f0010210c20022d000f210d20022d000e210e20022f000c210f20022d000b2110200228000721112002280003211820022d0002211320022f00002114410121020b024020032802f402450d002025102e0b2002450d330b200320063703b804200320073a00b704200320083a00b604200320093b01b4042003200a3a00b3042003200b3a00b2042003200c3b01b0042003200d3a00af042003200e3a00ae042003200f3b01ac04200320103a00ab04200320113600a704200320183600a304200320133a00a204200320143b01a004410e10292202450d1c200241002900b1e843370000200241066a41002900b7e8433700002003428e808080e0013702f402200320023602f002200341a0046a200341f0026a104a20032802f402212520032802f802212420032802f0022102200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220022024200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a8023703880520034188056a412041c8ecc500410041001005212402402025450d002002102e0b2024417f470d31200341a0046a200341e8046a412010f804450d30410e10292202450d1d200241002900d9e743370000200241066a41002900dfe7433700002003428e808080e0013702f402200320023602f002200341c8046a200341f0026a104a20032802f402212520032802f802212420032802f0022102200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220022024200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a80237038805200341203602f402200320034188056a3602f002200341a0046a200341f0026a109a0202402025450d002002102e0b410e10292202450d1e200241002900b1e843370000200241066a41002900b7e8433700002003428e808080e0013702f402200320023602f002200341e8046a200341f0026a104a20032802f402212520032802f802212420032802f0022102200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220022024200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a80237038805200341f0026a20034188056a10ae0302402003280290032224450d0020034188056a41201006200341d0036a41186a200341f0026a41186a290300370300200341d0036a41106a200341f0026a41106a290300370300200341d0036a41086a200341f0026a41086a290300370300200341c8016a41086a2003419c036a2226290200370300200341c8016a41106a200341a4036a2227290200370300200341c8016a41186a200341ac036a2228290200370300200341c8016a41206a2218200341b4036a2219290200370300200341f0016a221a200341bc036a221b280200360200200320032903f0023703d00320032003290294033703c80102402025450d002002102e0b20034194036a20032903c801370200200341f0026a41186a200341d0036a41186a290300370300200341f0026a41106a200341d0036a41106a290300370300200341f0026a41086a200341d0036a41086a2903003703002026200341c8016a41086a2903003702002027200341c8016a41106a2903003702002028200341c8016a41186a29030037020020192018290300370200201b201a280200360200200320032903d0033703f0022003202436029003410e10292202450d20200241002900b1e843370000200241066a41002900b7e8433700002003428e808080e0013702ac02200320023602a802200341a0046a200341a8026a104a20032802ac02212520032802b002212420032802a8022102200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220022024200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a80237038805200341203602ac02200320034188056a3602a802200341f0026a200341a8026a10ef0302402025450d002002102e0b200328029403450d31200328029003102e0c310b2025450d302002102e0c300b4101212620022d000120022d0000720d25200141046a2802002102200341f0026a41086a22254200370300200342003703f00241989ac5004116200341f0026a1003200341c8016a41086a2025290300370300200320032903f0023703c801200320023602f002200341c8016a4110200341f0026a410410040c230b20022d000120022d0000720d23200341f0026a41086a22024200370300200342003703f00241b29bc5004110200341f0026a1003200341c8016a41086a2002290300370300200320032903f0023703c801200341023a00ac0541012126410110292202450d1e200220032d00ac053a0000200341c8016a41102002410110042002102e0c220b20022d000120022d0000720d22200341f0026a41086a22024200370300200342003703f00241b29bc5004110200341f0026a1003200341c8016a41086a2002290300370300200320032903f0023703c80141012126200341013a00ac05410110292202450d1e200220032d00ac053a0000200341c8016a41102002410110042002102e0c210b4101212620022d000120022d0000720d22200141046a2802002102200341f0026a41086a22254200370300200342003703f00241cb9ac5004119200341f0026a1003200341c8016a41086a2025290300370300200320032903f0023703c801200320023602f002200341c8016a4110200341f0026a410410040c200b200141086a2802002128200141046a2802002118024020022d000120022d000072450d00418df0c20021254128212441002127410121262028450d302018102e0c300b2001410c6a2802002102200341f0026a41086a22254200370300200342003703f00241f2c1c4004115200341f0026a1003200341c8016a41086a2025290300370300200320032903f0023703c801200341003602f802200342013703f0022002200341f0026a104702402002450d00200241057421252018210203402002200341f0026a104a200241206a2102202541606a22250d000b0b20032802f4022102200341c8016a411020032802f002222520032802f802100402402002450d002025102e0b410121262028450d1e2018102e0c1e0b410e4101102c000b410e4101102c000b410e4101102c000b410d4101102c000b41014101102c000b41144101102c000b41144101102c000b20254108102c000b41184108102c000b201a4108102c000b41124101102c000b41124101102c000b41e694c500419f01109b01000b201a4101102c000b201b4101102c000b201a4101102c000b201b4101102c000b20264101102c000b20264101102c000b20264101102c000b20264101102c000b410d4101102c000b41014101102c000b410e4101102c000b410e4101102c000b410e4101102c000b410e4101102c000b41014101102c000b41014101102c000b200341c8016a41186a2003419c036a220241186a290000370300200341c8016a41106a200241106a290000370300200341c8016a41086a200241086a290000370300200342f3e885db96cddbb32037038805200320022900003703c801200341c0006a41b0f3c200410d107d20032003280244410020032802401b3602e804200341a8026a200341c8016a107c20032802ac02212520032802a802210220032802b0022124200341bc026a20034188056a3602002003200220244105746a3602b402200320023602b002200320253602ac02200320023602a8022003200341e8046a3602b802200341a0046a200341a8026a1044200341a8026a41086a200341a0046a41086a280200360200200320032903a0043703a802200341c8016a200341a8026a109001200341c8016a10750c070b41002127410021250c100b41002125410121270c0f0b418df0c2002125412821240c0d0b418df0c200212541282124410121270c0d0b2003410036028805200341103602b0042003201c201841246c6a3602ac042003201c3602a8042003201d3602a4042003201c3602a004200320034188056a3602b404200341f0026a200341a0046a10e301024002400240024002400240024002400240024020032d00f0024101460d0020032802ac04212620032802a804210202400340024020262002470d00200221240c020b20022d00002125200241246a2224210220254102470d000b0b200320243602a8044100212841012118024020032802a4040d00410021020c020b20032802a004102e410021020c010b412010292218450d01201820032900f102370000201841186a20034189036a290000370000201841106a20034181036a290000370000201841086a200341f9026a290000370000200341c8016a41106a200341a0046a41106a290300370300200341c8016a41086a200341a0046a41086a290300370300200320032903a0043703c801200341f0026a200341c8016a10e3010240024020032d00f0020d0041012102410121280c010b200341f0026a4101722125410221274120212641012102410121280340200341a8026a41186a2219202541186a290000370300200341a8026a41106a221a202541106a290000370300200341a8026a41086a221b202541086a290000370300200320252900003703a802024020022028470d00200241016a22242002490d0f2027202420242027491b222841ffffff3f712028470d0f202841057422244100480d0f0240024020020d002024102921180c010b201820262024102a21180b2018450d0b0b201820266a222420032903a802370000202441186a2019290300370000202441106a201a290300370000202441086a201b290300370000202741026a2127202641206a2126200241016a2102200341f0026a200341c8016a10e30120032d00f0020d000b0b20032802d401212620032802d001212502400340024020262025470d00202521270c020b20252d00002124202541246a2227212520244102470d000b0b200320273602d00120032802cc01450d0020032802c801102e0b02402003280288052225450d00200328028c05212402402028450d002018102e0b4100212620032802f40321020c090b200341d0036a412c6a221910db03200320023602782003202836027420032018360270411210292202450d01200241002900fee743370000200241106a41002f008ee8433b0000200241086a4100290086e84337000020034292808080a0023702f402200320023602f0022019200341f0026a104a20032802f402211820032802f802212620032802f0022124200341a8026a41186a22024200370300200341a8026a41106a22254200370300200341a8026a41086a22274200370300200342003703a80220242026200341a8026a100020034188056a41186a221a200229030037030020034188056a41106a221b202529030037030020034188056a41086a221c2027290300370300200320032903a80237038805200341c8016a20034188056a10ab030240024020032d00d40122284102470d00200242003703002025420037030020274200370300200342003703a80241dee8c300411a200341a8026a1000201a2002290300370300201b2025290300370300201c2027290300370300200320032903a80237038805200341a0046a20034188056a412010dc01024020032d00a0040d00200341a8026a41186a22024200370300200341a8026a41106a22254200370300200341a8026a41086a22274200370300200342003703a80241dee8c300411a200341a8026a100020034188056a41186a200229030037030020034188056a41106a202529030037030020034188056a41086a2027290300370300200320032903a80237038805200341203602f402200320034188056a3602f0022019200341f0026a109a0241002102410021280c020b200341e8046a41186a200341b9046a290000370300200341e8046a41106a200341b1046a290000370300200341e8046a41086a200341a9046a290000370300200320032900a1043703e804411210292202450d04200241002900fee743370000200241106a41002f008ee8433b0000200241086a4100290086e84337000020034292808080a0023702f402200320023602f002200341e8046a200341f0026a104a20032802f402211b20032802f802212520032802f0022127200341a8026a41186a22024200370300200341a8026a41106a22284200370300200341a8026a41086a221a4200370300200342003703a80220272025200341a8026a100020034188056a41186a200229030037030020034188056a41106a202829030037030020034188056a41086a201a290300370300200320032903a80237038805200341f0026a20034188056a10ab0320032d00fc024102460d0520032802f402211c20032802f002211a20032802f8022102200341a8026a200341fc026a41c20010f6041a200341f0026a200341a8026a41c20010f6041a20032d009103211d200341a8026a41186a22284200370300200341a8026a41106a221e4200370300200341a8026a41086a221f4200370300200342003703a80220272025200341a8026a100020034188056a41186a202829030037030020034188056a41106a201e29030037030020034188056a41086a201f290300370300200320032903a80237038805200341003602b002200342013703a8022002200341a8026a104702402002450d0020024105742125201a210203402002200341a8026a104a200241206a2102202541606a22250d000b0b41012128200341013a00ac050240024020032802ac0220032802b0022202460d0020032802a80221250c010b200241016a22252002490d0e20024101742228202520252028491b22284100480d0e0240024020020d002028102921250c010b20032802a80220022028102a21250b2025450d07200320283602ac02200320253602a80220032d00ac05212820032802b00221020b2003200241016a3602b002202520026a20283a00002019200341a8026a104a02400240201d41ff01714101460d0041002128200341003a00ac050240024020032802ac0220032802b0022202460d0020032802a80221250c010b200241016a22252002490d1020024101742228202520252028491b22284100480d100240024020020d002028102921250c010b20032802a80220022028102a21250b2025450d0a200320283602ac02200320253602a80220032d00ac05212820032802b00221020b2003200241016a3602b002202520026a20283a00000c010b200341013a00ac050240024020032802ac0220032802b0022202460d004101212820032802a80221250c010b200241016a22252002490d0f20024101742228202520252028491b22284100480d0f0240024020020d002028102921250c010b20032802a80220022028102a21250b2025450d0a200320283602ac02200320253602a80220032d00ac05212820032802b00221020b2003200241016a3602b002202520026a20283a000020034192036a200341a8026a104a0b20032802ac02210220034188056a412020032802a802222520032802b002100402402002450d002025102e0b0240201c450d00201a102e0b0240201b450d002027102e0b200341a8026a41186a22024200370300200341a8026a41106a22254200370300200341a8026a41086a22274200370300200342003703a80241dee8c300411a200341a8026a100020034188056a41186a200229030037030020034188056a41106a202529030037030020034188056a41086a2027290300370300200320032903a80237038805200341203602f402200320034188056a3602f0022019200341f0026a109a02200341a8016a41086a200341e8046a41086a290300370300200341a8016a41106a200341e8046a41106a290300370300200341a8016a41186a200341e8046a41186a290300370300200320032903e8043703a80141012102410021280c010b200341d0006a41086a200341dd016a290000370300200341d0006a41106a200341e5016a290000370300200341d0006a41186a200341ed016a290000370300200341a8016a41086a200341fe016a290100370300200341a8016a41106a20034186026a290100370300200341a8016a41186a2003418e026a2901003703002003200341d5016a2900003703502003200341f6016a2901003703a801200341f5016a2d0000210220032802cc01450d0020032802c801102e0b20034195036a20023a000020034196036a20032903a801370100200341fd026a200341d0006a41086a29030037000020034185036a200341d0006a41106a2903003700002003418d036a200341d0006a41186a2903003700002003419e036a200341a8016a41086a290300370100200341a6036a200341a8016a41106a290300370100200341ae036a200341a8016a41186a290300370100200320283a00f402200320032903503700f5022003200341f0006a3602f002200341a8026a41186a22024200370300200341a8026a41106a22254200370300200341a8026a41086a22274200370300200342003703a80220242026200341a8026a100020034188056a41186a200229030037030020034188056a41106a202529030037030020034188056a41086a2027290300370300200320032903a80237038805200341003602d001200342013703c8012003280270210220032802782225200341c8016a1047200341f0026a410472212602402025450d002025410574212503402002200341c8016a104a200241206a2102202541606a22250d000b0b2026200341c8016a10de0320032802cc01210220034188056a412020032802c801222520032802d001100402402002450d002025102e0b02402018450d002024102e0b02402003280274450d002003280270102e0b024020032802f403450d0020032802f003102e0b4100212641012127410021250c140b41204101102c000b41124101102c000b41124101102c000b41e694c500419f01109b01000b20284101102c000b20284101102c000b20284101102c000b20244101102c000b02402002450d0020032802f003102e0b20260d0041012127410021260c0b0b4101212741002126201d450d0a201c102e0c0a0b0240200328029403450d00200328029003102e0b410021250c080b102d000b20032006202c202c200656200520175620052017511b22021b220620297c22043703d801200341e0016a2017200520021b2217202a7c2004200654ad7c37030020032006202b7c22043703c80120032017202d7c2004200654ad7c3703d001200341a8026a200341c8016a10ec0320032802ec0121250b2025450d0220032802e801102e0c020b4182c1c4002125411021240c040b41b5f0c2002125412a21240c030b4100212541012126410121270c030b41a4c0c4002125411921240c010b41ccc4c2002125411521240b41012126410121270b0240024020012d00002202410e4b0d00410120027441beff00710d01024020024106460d002002410e470d012027450d02200141086a280200450d02200141046a280200102e0c020b2026450d01200141086a280200450d01200141046a280200102e0c010b200141086a280200450d00200141046a280200102e0b2000202436020420002025360200200341b0056a24000b4d01017f230041206b22002400200041146a410136020020004201370204200041cc91c5003602002000411c36021c200041c491c5003602182000200041186a360210200041bcc4c200106a000ba60701057f230041106b22032400200341003602082003420137030020022003104702400240024002400240024002402002450d00200241c4006c210403400240024020012d00004101460d0002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0a20024101742206200520052006491b22064100480d0a0240024020020d002006102921050c010b200328020020022006102a21050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a0000200141046a28020021060240024020032802042205200328020822026b4104490d00200328020021050c010b200241046a22072002490d0a20054101742202200720072002491b22024100480d0a0240024020050d002002102921050c010b200328020020052002102a21050b2005450d062003200236020420032005360200200328020821020b2003200241046a360208200520026a20063600000c010b02400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0920024101742206200520052006491b22064100480d090240024020020d002006102921050c010b200328020020022006102a21050b2005450d062003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a0000200141016a200310460240200141216a2d00004101460d0002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0a20024101742206200520052006491b22064100480d0a0240024020020d002006102921050c010b200328020020022006102a21050b2005450d082003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a00000c010b02400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0920024101742206200520052006491b22064100480d090240024020020d002006102921050c010b200328020020022006102a21050b2005450d082003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a0000200141226a2003104a0b200141c4006a2101200441bc7f6a22040d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b20064101102c000b20024101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b3400200041bceac10036020420004100360200200041146a4103360200200041106a41e0ebc100360200200041086a42083702000b130020004101360204200041c4eac1003602000b5101027f230041106b2202240002404104102922030d0041044101102c000b2002420437020420022003360200410020021047200041086a200228020836020020002002290300370200200241106a24000bb01102077f027e230041106b2202240020024100360208200242013703004104200210470240024002400240024002400240024002400240024002400240024002400240024020022802042203200228020822046b4104490d00200441046a2105200228020021030c010b200441046a22052004490d0f20034101742206200520052006491b22064100480d0f0240024020030d002006102921030c010b200228020020032006102a21030b2003450d0120022006360204200220033602000b20022005360208200320046a41eede91ab06360000410e200210470240024020022802042203200228020822066b410e490d002006410e6a2104200228020021050c010b2006410e6a22042006490d0f20034101742205200420042005491b22074100480d0f0240024020030d002007102921050c010b200228020020032007102a21050b2005450d022002200736020420022005360200200721030b20022004360208200520066a220641002900a9f041370000200641066a41002900aff0413700000240200320046b41034b0d00200441046a22062004490d0f20034101742207200620062007491b22064100480d0f0240024020030d002006102921050c010b200520032006102a21050b2005450d0320022006360204200220053602000b2002200441046a360208200520046a410a3600000240024020022802042205200228020822046b4104490d00200228020021050c010b200441046a22032004490d0f20054101742206200320032006491b22034100480d0f0240024020050d002003102921050c010b200228020020052003102a21050b2005450d0420022003360204200220053602000b2002200441046a360208200520046a4191013600000240024020022802042205200228020822046b4104490d00200228020021050c010b200441046a22032004490d0f20054101742206200320032006491b22034100480d0f0240024020050d002003102921050c010b200228020020052003102a21050b2005450d0520022003360204200220053602000b2002200441046a360208200520046a41910136000041092002104741b8f0c1002104034002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0720022006360204200220033602000b2002200541016a360208200320056a20042d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0820022006360204200220033602000b2002200541016a360208200320056a200441016a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0920022006360204200220033602000b2002200541016a360208200320056a200441026a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0a20022006360204200220033602000b2002200541016a360208200320056a200441036a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0b20022006360204200220033602000b2002200541016a360208200320056a200441046a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0c20022006360204200220033602000b2002200541016a360208200320056a200441056a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0d20022006360204200220033602000b2002200541016a360208200320056a200441066a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0e20022006360204200220033602000b2002200541016a360208200320056a200441076a2d00003a0000200441086a28020021060240024020022802042203200228020822056b4104490d00200228020021030c010b200541046a22072005490d1020034101742208200720072008491b22074100480d100240024020030d002007102921030c010b200228020020032007102a21030b2003450d0f20022007360204200220033602000b2002200541046a360208200320056a20063600002004410c6a220441a4f1c100470d000b200235020821092002350200210a200241106a2400200a2009422086840f0b20064101102c000b20074101102c000b20064101102c000b20034101102c000b20034101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20074101102c000b102d000bc61802097f017e230041800a6b22022400024002402001450d00200220003602080c010b200241c8ecc5003602080b2002200136020c200241e0076a200241086a10aa020240024002400240024020022802e407450d00200241106a200241e0076a41fc0010f6041a20024190016a200241106a41fc0010f6041a20024190016a10ab0202400240024002402002280290012201450d00200241e0076a2001417f6a10ba01200241e0076a200241a0016a412010f8040d004100210320022802800221000240024020024188026a280200220141a0026c0d0041042104410021050c010b2001410c6c220610292204450d04200121050b02402001450d00200141a0026c2106200141057441606a2107200421010340200220003602b004200241e0076a200241b0046a10ac02200141086a200241e0076a41086a280200360200200120022903e0073702002001410c6a2101200041a0026a2100200641e07d6a22060d000b200741057641016a21030b41002106024002402003410c6c22010d0041042108410021090c010b2001410c6e220941037422004100480d02200010292208450d030b0240200420016a220a2004460d00410021062008210120042100034020002802002107200141046a200041086a28020036020020012007360200200141086a2101200641016a21062000410c6a2200200a470d000b0b200220063602b804200220093602b404200220083602b004200241e0076a200241b0046a10ad0202402009450d002008102e0b02402003450d002003410c6c21002004210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b02402005450d002004102e0b0240200241e0016a2201200241e0076a412010f804450d0041a8e5c500410e100920014120100d200241e0076a4120100d0b02402001200241e0076a412010f8040d0020024184026a2802002104200228028002210a200228028802210620024190026a20024190016a41f00010f6041a200a200641a0026c6a21002002280290022103200a210102402006450d00200241b0046a41f0006a2107200a2101024002400340200241f8066a200141e80010f6041a200141e8006a290300210b20024180036a200141f0006a41b00110f6041a200b4203510d02200241b0046a200241f8066a41e80010f6041a2002200b37039805200720024180036a41b00110f6041a2002200241b0046a3602d006200241e0076a200241d0066a10ac0220022802e8072106024020022802e407450d0020022802e007102e0b200241e0076a200241b0046a41a00210f6041a200241003602e006200241d0066a200241e0076a2006200241e0066a10ae0220022802d0064101460d01024020022802d4062206450d00200620022802d80610090b200141a0026a22012000470d000b200021010c020b024020022802d4060e050b00000c0a0b0b41e8a7c2001058000b200141a0026a21010b20012000460d06200241f8086a2106200241e0076a41f0006a2107034020024180036a200141e80010f6041a200141e8006a290300210b200241e0076a200141f0006a41b00110f6041a200b4203510d07200241f8066a20024180036a41e80010f6041a200241b0046a200241e0076a41b00110f6041a200241e0076a200241f8066a41e80010f6041a2002200b3703c8082007200241b0046a41b00110f6041a2006102f200141a0026a22012000470d000c070b0b4188a7c2001058000b41f0a6c2001058000b102d000b20004104102c000b20064104102c000b2002418c036a411c360200200241c4046a4102360200200242023702b404200241d4f1c1003602b0042002411c36028403200241ccf1c100360280032002410036029401200241c8ecc50036029001200220024180036a3602c004200220024190016a36028803200241b0046a41e4f1c100106a000b02402004450d00200a102e0b10af022003109501200241e0076a10b002200220024190026a410c6a28020022043602f00620022802940221072002200241e0076a410c6a28020022013602f406024020042001470d0002402004450d0020022802e407210a41002106034002400240024002400240024002400240200720066a22012d00002203200a20066a22002d0000470d000240024002400240024020030e050400010203040b02402007200a460d00200141016a280000200041016a280000470d050b200141106a2802002203200041106a280200470d04200141086a2802002208200041086a2802002209460d0920082009200310f8040d040c090b02402007200a460d00200141016a280000200041016a280000470d040b200141106a2802002203200041106a280200470d03200141086a2802002208200041086a2802002209460d0720082009200310f8040d030c070b02402007200a460d00200141016a280000200041016a280000470d030b200141106a2802002203200041106a280200470d02200141086a2802002208200041086a2802002209460d0520082009200310f8040d020c050b2001410c6a28020022032000410c6a280200470d01200141046a2802002208200041046a2802002209460d0320082009200310f8040d010c030b2007200a460d07200141016a200041016a412010f804450d010b41c882c00041141009200241b0046a2001104520022802b004220320022802b804100d024020022802b404450d002003102e0b200241b0046a2000104520022802b004220320022802b804100d024020022802b404450d002003102e0b20012d000020002d00002203470d05024020030e050005040302000b2007200a460d060b200141016a200041016a412010f8040d040c050b2001410c6a28020022032000410c6a280200470d03200141046a2802002201200041046a2802002200460d0420012000200310f804450d040c030b02402007200a460d00200141016a280000200041016a280000470d030b200141106a2802002203200041106a280200470d02200141086a2802002201200041086a2802002200460d0320012000200310f8040d020c030b02402007200a460d00200141016a280000200041016a280000470d020b200141106a2802002203200041106a280200470d01200141086a2802002201200041086a2802002200460d0220012000200310f8040d010c020b02402007200a460d00200141016a280000200041016a280000470d010b200141106a2802002203200041106a280200470d00200141086a2802002201200041086a2802002200460d0120012000200310f804450d010b4198a8c2001058000b200641246a21062004417f6a22040d000b0b024020024190026a41306a2201200241e0076a41306a2200412010f804450d0041a8e5c500410e100920014120100d20004120100d0b024020012000412010f804450d0041b0a8c2001058000b024020022802ec072200450d0020022802e4072101200041246c210003400240024020012d0000220641034b0d0002400240024020060e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b0240200241e8076a280200450d0020022802e407102e0b0240200228029c022200450d002002280294022101200041246c210003400240024020012d0000220641034b0d0002400240024020060e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b024020024198026a280200450d00200228029402102e0b200241800a6a240042010f0b20024180036a41146a411d36020020024180036a410c6a4120360200200241f8066a41146a41033602002002200241f0066a3602e0062002200241f4066a3602d006200241b0046a41146a4100360200200242033702fc062002419ce7c5003602f8062002412036028403200241c8ecc5003602c004200242013702b40420024180a8c2003602b004200220024180036a360288072002200241b0046a360290032002200241d0066a360288032002200241e0066a36028003200241f8066a4188a8c200106a000b41d0a7c2001058000b41b8a7c2001058000b41a0a7c2001058000bea05030c7f017e017f230041b0056b2202240020024190036a2001103c0240024020022802940322030d00200041003602040c010b2002419c036a280200210420022802980321052002280290032106200241106a200241a0036a41e00010f6041a200241086a20011031024020022802080d000240024002400240200128020441a0026e220741a0026c2208417f4c0d00200228020c21090240024020080d004108210a0c010b20081029220a450d020b024002402009450d004100210b410021084100210c034020024190036a200110b70120022903f8034203510d02200c41016a210d200241f0006a20024190036a41a00210f6041a0240200c2007470d00200b200d200d200b491b2207ad42a0027e220e422088a70d07200ea7220f4100480d0702400240200c0d00200f1029210a0c010b200a2008200f102a210a0b200a450d060b200a20086a200241f0006a41a00210f6041a200b41026a210b200841a0026a2108200d210c2009200d470d000b0b200a450d0520024190036a200241106a41e00010f6041a2000410c6a2004360200200020053602082000200336020420002006360200200041106a20024190036a41e00010f6041a200041f8006a2009360200200041f4006a2007360200200041f0006a200a3602000c060b0240200c450d00200a4198016a210d0340200d102f200d41a0026a210d200841e07d6a22080d000b0b2007450d04200a102e0c040b1032000b20084108102c000b200f4108102c000b102d000b2000410036020402402004450d00200441246c210d2003210803400240024020082d0000220c41034b0d00024002400240200c0e0404000102040b2008410c6a280200450d03200841086a280200102e0c030b2008410c6a280200450d02200841086a280200102e0c020b2008410c6a280200450d01200841086a280200102e0c010b200841086a280200450d00200841046a280200102e0b200841246a2108200d415c6a220d0d000b0b2005450d002003102e0b200241b0056a24000bb9cb01070c7f017e0b7f0e7e017f027e167f230041c00c6b220124000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402000410c6a28020041246c22020d004100210341002104410421050c010b200028020421064104210541002103410021040340024020062d00004101470d00200641106a2802002207417f4c0d16200641016a28000021080240024020070d00410121090c010b200641086a280200210a200710292209450d042009200a200710f6041a0b200141a00b6a41086a220b200141a8056a41086a290200370300200120012902a8053703a00b024020032004470d00200341016a220a2003490d1c2003410174220c200a200a200c491b2204ad42247e220d422088a70d1c200da7220a4100480d1c0240024020030d00200a102921050c010b2005200341246c200a102a21050b2005450d050b2005200341246c6a220a2007360210200a200736020c200a2009360208200a2008360001200a41013a0000200a20012903a00b370214200a411c6a200b290300370200200341016a21030b200641246a21062002415c6a22020d000b0b200141003602a00b41dff0c2004110200141a00b6a41041004200141f0086a41086a22064200370300200142003703f00841b0f3c200410d200141f0086a1003200141d8076a41086a220a2006290300370300200120012903f0083703d80720012000280200220e3602a00b200141d8076a4110200141a00b6a4104100420064200370300200142003703f00841d2f3c200410d200141f0086a1003200a2006290300370300200120012903f0083703d807200141003602b005200142013703a8052003200141a8056a10470240024020030d0020012802b005210a20012802ac05210820012802a80521070c010b200341246c210c20012802ac05210820012802b0052106200521020340200141a00b6a2002104520012802a00b210b02400240200820066b20012802a80b2209490d00200620096a210a20012802a80521070c010b200620096a220a2006490d1b20084101742207200a200a2007491b220f4100480d1b0240024020080d00200f102921070c010b20012802a8052008200f102a21070b2007450d052001200f3602ac05200120073602a805200f21080b2001200a3602b005200720066a200b200910f6041a024020012802a40b450d00200b102e0b200241246a2102200a2106200c415c6a220c0d000b0b200041106a2102200141d8076a41102007200a100402402008450d002007102e0b200141f0086a41086a22064200370300200142003703f008418cf5c2004111200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d8072001200141d8076a3602a00b200141103602a40b2002200141a00b6a10b802411010292206450d03200641086a41002900e7f342370000200641002900dff342370000200641104120102a220a450d04200a200e417f6a360010200141f0086a41186a22074200370300200141f0086a41106a22094200370300200141f0086a41086a22064200370300200142003703f008200a4114200141f0086a100020014198046a41186a200729030037030020014198046a41106a200929030037030020014198046a41086a2006290300370300200120012903f00837039804200141203602a40b200120014198046a3602a00b2002200141a00b6a10b802200a102e20064200370300200142003703f00841bdf3c2004115200141f0086a1003200141d8076a41086a220a2006290300370300200120012903f0083703d807200141103602a40b2001200141d8076a3602a00b200041d0006a200141a00b6a10b80220064200370300200142003703f008419df5c2004115200141f0086a1003200a2006290300370300200120012903f0083703d807200141a00b6a200141d8076a10fe02024020012802a40b22060d00200141013602a8054100210a41002107410021020c070b200120063602a80520012c00a00b210220012802a80b2107200141ac0b6a280200220a41d100490d06200141a00b6a41186a2208200041286a290000370300200141a00b6a41106a220b200041206a290000370300200141a00b6a41086a220c200041186a290000370300200120002900103703a00b200a20024d0d05200620024105746a220920012903a00b370000200941186a2008290300370000200941106a200b290300370000200941086a200c290300370000200241187441808080086a41187541d1006f21020c070b20074101102c000b200a4104102c000b200f4101102c000b41104101102c000b41204101102c000b41b4f5c2002002200a1038000b200141a00b6a41186a200041286a290000370300200141b00b6a200041206a290000370300200141a80b6a200041186a290000370300200120002900103703a00b02400240200a2007460d0020012802a80521060c010b200a41016a2206200a490d12200a4101742207200620062007491b220741ffffff3f712007470d12200741057422094100480d1202400240200a0d002009102921060c010b20012802a805200a4105742009102a21060b2006450d02200120063602a8050b2006200a4105746a220920012903a00b370000200941186a200141a00b6a41186a290300370000200941106a200141a00b6a41106a290300370000200941086a200141a00b6a41086a290300370000200a41016a210a0b200141f0086a41086a22094200370300200142003703f008419df5c2004115200141f0086a1003200141d8076a41086a2009290300370300200120012903f0083703d807410110292209450d01200920023a000020014281808080103702a40b200120093602a00b200a200141a00b6a1047200a410574210a03402006200141a00b6a1046200641206a2106200a41606a220a0d000b20012802a40b2106200141d8076a411020012802a00b220a20012802a80b100402402006450d00200a102e0b02402007450d0020012802a805102e0b200141f0086a41086a22064200370300200142003703f00841c4f5c200410d200141f0086a1003200141d8076a41086a220a2006290300370300200120012903f0083703d807200141d8076a4110100620064200370300200142003703f0084197e5c5004111200141f0086a1003200a2006290300370300200120012903f0083703d807200141d8076a4110100641121029220a450d02200a41106a41002f00e1f5423b0000200a41086a41002900d9f542370000200a41002900d1f542370000200141f0086a41186a22074200370300200141f0086a41106a2202420037030020064200370300200142003703f008200a4112200141f0086a100020014198046a41186a2209200729030037030020014198046a41106a200229030037030020014198046a41086a2006290300370300200120012903f00837039804412010292206450d032006200129039804370000200641186a2009290300370000200641106a20014198046a41106a290300370000200641086a20014198046a41086a290300370000200a102e2006412010182006102e20002802002110107f200141f0086a41086a22064200370300200142003703f008419893c2004111200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141003602a00b200141d8076a4110200141a00b6a100821060240024020012802a00b220a417f460d002006450d002001200a3602ac05200120063602a805200141a00b6a200141a8056a103d20012802a00b2208450d0620012902a40b210d200a450d012006102e0c010b410421084200210d0b20104105490d082010417b6a21022008200d422088a7220b41c4006c22066a21090240200641cd014f0d00410021062008210a0c070b200841d0016a210a4100210603400240200a41b07e6a22072d00004101460d00200a41b47e6a28020020024f0d090b0240200741c4006a2d00004101460d00200a41f87e6a2802002002490d00200641016a21060c090b024020074188016a2d00004101460d00200a41bc7f6a2802002002490d00200641026a21060c090b02400240200741cc016a2d00004101460d00200a28020020024f0d010b200a4190026a210a200641046a2106200920074190026a6b41cc014d0d070c010b0b200641036a21060c070b20094101102c000b41014101102c000b41124101102c000b41204101102c000b41eff0c2004133200141c0066a4184f4c2001053000b200a41b07e6a210a0b200a2009460d002008200b41c4006c6a210703400240200a2d00004101460d00200a41046a28020020024f0d020b200641016a21062007200a41c4006a220a470d000b0b2006200b4b0d01200d42ffffffff0f83210d200b20066b220a450d002006450d0020082008200641c4006c6a200a41c4006c10f7041a0b200141003a00a00b200141f0086a41086a22064200370300200142003703f00841d49bc5004117200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141d8076a4110200141a00b6a41011004200141a00b6a1088010240412410292206450d00200620012903a00b37000020064114360220200641186a200141a00b6a41186a290300370000200641106a200141a00b6a41106a290300370000200641086a200141a00b6a41086a29030037000020014281808080103702ac05200120063602a805200141a8056a1097020240200da7450d002008102e0b10d902024020104180ce18700d000240024041a199c500411f109c01220641ff01714102460d0020064101710d010b201010ff02450d0120101080031a0c010b2010108003450d00201010ff021a0b20014190046a418e99c5004113107d2001280294042106200128029004210a20014188046a41f598c5004119107d0240024002400240024020064100200a1b2206200128028c0441002001280288041b22074f0d00200141b10c6a21022001418c0a6a21080340200141a00b6a2006108103024020012d00b00c220a4103460d002008200141a00b6a41900110f6041a2001200241036a28000036008b052001200228000036028805200141f0086a200141880a6a41940110f6041a200621090b200141d8076a200141f0086a41940110f6041a2001200128008b053600eb0420012001280288053602e8040240200a4103470d002007200641016a2206470d010c020b0b200141c0066a200141d8076a41940110f6041a200120012800eb043600c304200120012802e8043602c004200120093602a00b200141a00b6a410472200141c0066a41940110f6041a200141a00b6a4198016a200a3a0000200141b90c6a220220012802c004360000200141bc0c6a20012800c30436000002400240200141b00c6a2802002010460d00200141a80b6a102f4103210a410121020c010b200141a8056a200141a00b6a41980110f6041a2001200241036a28000036009b042001200228000036029804410021020b200a4103470d010b410821114100210a410021120c010b200141a00b6a200141a8056a41980110f6041a2001200128009b0436008b0a20012001280298043602880a41a00110292211450d022011200141a00b6a41980110f6042209200a3a009801200920012802880a360099012009419c016a200128008b0a3600004101210a02402002450d00410121120c010b02400240200641016a220620074f0d00200141b10c6a21092001418c0a6a210c0340200141a00b6a2006108103024020012d00b00c22024103460d00200c200141a00b6a41900110f6041a2001200941036a28000036008b052001200928000036028805200141f0086a200141880a6a41940110f6041a2006210b0b200141d8076a200141f0086a41940110f6041a2001200128008b053600eb0420012001280288053602e80420024103470d022007200641016a2206470d000b0b410121120c010b200141c0066a200141d8076a41940110f6041a200120012800eb043600c304200120012802e8043602c0042001200b3602a00b200141a00b6a410472200141c0066a41940110f6041a200141a00b6a4198016a20023a0000200141b90c6a220a20012802c004360000200141bc0c6a20012800c30436000002400240200141b00c6a2802002010460d00200141a80b6a102f410321024101210c0c010b200141a8056a200141a00b6a41980110f6041a2001200a41036a28000036009b042001200a280000360298044100210c0b024020024103470d004101210a410121120c010b200641016a2106200141a00b6a4104722100200141a80b6a2113200141a00b6a4199016a210f200141b10c6a21094101210a410121120340200141a00b6a200141a8056a41980110f6041a2001200128009b0436008b0a20012001280298043602880a02402012200a470d00200a41016a220b200a490d0d200a410174220e200b200b200e491b2212ad42a0017e220d422088a70d0d200da7220b4100480d0d02400240200a0d00200b102921110c010b2011200a41a0016c200b102a21110b2011450d030b2011200a41a0016c6a200141a00b6a41980110f604220b4198016a20023a0000200b4199016a20012802880a360000200b419c016a200128008b0a360000200a41016a210a200c41ff01710d01200620074f0d010340200141a00b6a2006108103024020012d00b00c22024103460d002008200141a00b6a41900110f6041a2001200941036a28000036008b052001200928000036028805200141f0086a200141880a6a41940110f6041a2006210b0b200141d8076a200141f0086a41940110f6041a2001200128008b053600eb0420012001280288053602e804024020024103470d002007200641016a2206470d010c030b0b200141c0066a200141d8076a41940110f6041a200120012800eb043600c304200120012802e8043602c0042001200b3602a00b2000200141c0066a41940110f6041a200f20012802c004360000200f41036a220b20012800c304360000200120023a00b80c0240024020012802b00c2010460d002013102f410321024101210c0c010b200141a8056a200141a00b6a41980110f6041a2001200b28000036009b042001200f280000360298044100210c0b200641016a210620024103470d000b0b2011200a41a0016c6a21140240200a0d00201121150c050b200141a00b6a4104722106200141b9066a2116200141880a6a41046a2117200141f0026a41106a21182011211503402015220a2802002102200141a00b6a200a41046a41940110f6041a2001200a4199016a2800003602a8052001200a419c016a2800003600ab05200a41a0016a2115200a4198016a2d0000220a4103460d05200141880a6a200141a00b6a41940110f6041a200120012800ab053600bb04200120012802a8053602b804200141a8056a201741900110f6041a201620012802b804360000201641036a20012800bb043600002001200a3a00b806200141f0086a200210820320012802f008210b0240024020012802f808220a0d00420021194200211a4200211b4200211c4200211d4200211e0c010b200a41057421094200211d200b210a4200211e4200211b4200211c420021194200211a0340200141f8036a200a108401200141f8036a41086a290300211f20012903f803210d2006200a290000370000200641086a200a41086a290000370000200641106a200a41106a290000370000200641186a200a41186a290000370000200120023602a00b200141f0036a200141a00b6a10830320012d00f00341017121070240024020012d00f10322080d00200141b0036a200d201f420a420010fc0420012903b0032220210d200141b0036a41086a2903002221211f0c010b200141d0036a201f42002008ad2220420010fb04200141e0036a200d42002020420010fb04200141c0036a42004200200d420010fb04427f200141e0036a41086a290300222020012903d00320012903c0037c7c222120012903d80320012903c8038442005220212020547222081b2121427f20012903e00320081b21200b200a41206a210a4200202120071b201c7c4200202020071b2222201b7c221b202254ad7c211c2021420020071b201a7c2020420020071b222020197c2219202054ad7c211a201f201e7c200d201d7c221d200d54ad7c211e200941606a22090d000b0b024020012802f408450d00200b102e0b200141f0086a200210820320012802f00821000240024020012802f808220a0d004200212242002123420021244200212542002121420021260c010b200a4105742109420021212000210a420021264200212442002125420021224200212303402006200a290000370000200641086a200a41086a2207290000370000200641106a200a41106a2208290000370000200641186a200a41186a220b290000370000200120023602a00b200141a8036a200141a00b6a10830320012d00a803210c20012d00a903210f200141a00b6a41186a200b290000370300200141a00b6a41106a2008290000370300200141a00b6a41086a20072900003703002001200a2900003703a00b20014188036a2002200141a00b6a200f411010840320014188036a41186a29030020267c200129039803220d20217c2221200d54ad7c2126420020014188036a41086a290300220d200c41017122071b20257c4200200129038803221f20071b222020247c2224202054ad7c2125200d420020071b20237c201f420020071b220d20227c2222200d54ad7c2123200a41206a210a200941606a22090d000b0b024020012802f408450d002000102e0b200141f0086a41086a22274200370300200142003703f00841c28cc0004116200141f0086a1003200141d8076a41086a22072027290300370300200120012903f0083703d807200141f0026a200141d8076a1097012018290300420020012802f002220a1b210d20012903f8024200200a1b211f024002402021201d7c22204202882026201e7c2020202154ad7c2221423e8684221d2020852021420288221e20218584500d00201d201e84500d004100210a02400340200141e0026a20202021200a41046a41fe007110fa04200a41026a210a20012903e002221d202085200141e0026a41086a290300221e20218584500d01201d201e844200520d000b0b200141d0026a20202021200a41fe007110fa0420012903d002200141d0026a41086a29030084211d4200211e0240200a0d00201d420052ad211d0c020b201d420052ad211d0340200141b0026a202020214100200a417e6a22092009200a4b1b220a41ff007110fa04200141c0026a201d42018622284201842226201e420186201d423f8884221e2026201e10fb042028202620012903c00220012903b00256200141c0026a41086a290300221d200141b0026a41086a290300222956201d2029511b1b211d200a0d000c020b0b4200211e2020202184420052ad211d0b02400240201f420288200d423e86842220201f85200d4202882221200d8584500d002020202184500d004100210a02400340200141a0026a201f200d200a41046a41fe007110fa04200a41026a210a20012903a0022220201f85200141a0026a41086a2903002221200d8584500d0120202021844200520d000b0b20014190026a201f200d200a41fe007110fa0420012903900220014190026a41086a290300842120420021210240200a0d002020420052ad21200c020b2020420052ad21200340200141f0016a201f200d4100200a417e6a22092009200a4b1b220a41ff007110fa0420014180026a20204201862228420184222620214201862020423f888422212026202110fb042028202620012903800220012903f0015620014180026a41086a2903002220200141f0016a41086a29030022295620202029511b1b2120200a0d000c020b0b42002121201f200d84420052ad21200b02400240024002400240201d201e8450450d004100210e0c010b2025201c7c2024201b7c221f202454ad7c21242023201a7c202220197c220d202254ad7c212202400240024020012d00b8060e03010200010b200d201f56202220245620222024511b210e0c020b0340200141a0016a201f2024201d201e10fc04202022192021221a844200510d04200141a0016a41086a290300212020012903a001212620014190016a200d20222019201a10fc044101210e2026200129039001221b54202020014190016a41086a2903002221542020202151220a1b0d020240201b2026542021202054200a1b450d004100210e0c030b20014180016a20262020201d201e10fb04200141f0006a201b20212019201a10fb040240200d200129037022207d22212022200141f0006a41086a2903007d200d202054ad7d222684500d00202420014180016a41086a2903007d211b201f200129038001220d54210a201f200d7d2120201d210d201e21222021211d2026211e2019211f201a21242020201b200aad7d222184500d030c010b0b4100210e0c010b0340201e2126201d211920202021844200510d02200141d0016a200d20222019202610fc04200141e0016a201f20242020202110fc044101210e20012903e001221a20012903d001221b54200141e0016a41086a290300221d200141d0016a41086a290300221e54201d201e51220a1b0d010240201b201a54201e201d54200a1b450d004100210e0c020b200141c0016a201a201d2020202110fb04200141b0016a201b201e2019202610fb040240200d20012903b001221d7d221e2022200141b0016a41086a2903007d200d201d54ad7d221a8450450d004100210e0c020b2024200141c0016a41086a2903007d211b201f20012903c001220d54210a201f200d7d211d2020210d20212122201e2120201a21212019211f20262124201d201b200aad7d221e844200520d000b0b200141a00b6a200210820320012802a00b212a20012802a40b212b20012802a80b220a450d02202a200a410574222c6a212d202a210a0340200141f0086a41186a222e200a41186a2209290000220d370300200141f0086a41106a222f200a41106a2208290000221f3703002027200a41086a220b29000022203703002001200a29000022213703f00820014188056a41186a2230200929000037030020014188056a41106a2231200829000037030020014188056a41086a2232200b290000370300200a290000211d20014198046a41086a220c202037030020014198046a41106a220f201f37030020014198046a41186a2200200d3703002001201d370388052001202137039804200a290000210d200641186a223320092900003700002006200d370000200641086a2234200b290000370000200641106a22352008290000370000200120023602a00b200141e8006a200141a00b6a108303410221090240200e20012d0068410171220845734101470d0020012d00692136200141d8076a41186a2000290300370300200141d8076a41106a200f2903003703002007200c29030037030020012001290398043703d807200821090b200141c0066a41086a22372007290300370300200141c0066a41106a2238200141d8076a41106a2213290300370300200141c0066a41186a2239200141d8076a41186a223a290300370300200120012903d8073703c0060240024020094102460d00200a41206a210a0c010b200a41206a210a202c41606a222c0d010c040b0b0340200141c0046a41086a2037290300220d370300200141c0046a41106a2038290300221f370300200141c0046a41186a20392903002220370300200120012903c00622213703c004200141a00b6a41186a2020370300200141a00b6a41106a201f370300200141a00b6a41086a200d370300200120213703a00b200142e4cab5fbb6ccdcb0e3003703e004200141e0046a200141a00b6a203641187441187541027441c098c5006a2802004180af1a6c20106a108f01200a202d460d030340202e200a41186a2209290000220d370300202f200a41106a2208290000221f3703002027200a41086a220b29000022203703002001200a29000022213703f00820302009290000370300203120082900003703002032200b290000370300200a290000211d200c2020370300200f201f3703002000200d3703002001201d370388052001202137039804200120023602a00b200b290000210d2008290000211f200a2900002120203320092900003700002035201f3700002034200d37000020062020370000200141e0006a200141a00b6a108303410221090240200e20012d0060410171220845734101470d0020012d00612136203a20002903003703002013200f2903003703002007200c29030037030020012001290398043703d807200821090b20372007290300370300203820132903003703002039203a290300370300200120012903d8073703c006024020094102470d00202d200a41206a220a470d010c050b0b200a41206a210a0c000b0b41c881c0001058000b41c881c0001058000b0240202b450d00202a102e0b200210850302400240200e0d00200141053a00a80b200141053a00a00b200120023602ac0b41c8ecc5004100200141a00b6a107220274200370300200142003703f008418e99c5004113200141f0086a100320072027290300370300200120012903f0083703d8072001200241016a3602a00b200141d8076a4110200141a00b6a41041004200141a8056a102f0c010b200120023602ac0b200141043a00a80b200141053a00a00b41c8ecc5004100200141a00b6a1072024020012802b406220a450d00200141a00b6a200141a8056a41980110f6041a200141d8076a200a20106a220c108603200141f0086a200141a00b6a41880110f6041a0240024002400240024020012802dc07220b20012802e007220a460d0020012802d80721080c010b200a41016a2209200a490d11200a4101742208200920092008491b220bad4290017e220d422088a70d11200da722094100480d1102400240200a0d002009102921080c010b20012802d807200a4190016c2009102a21080b2008450d012001200b3602dc07200120083602d8070b2008200a4190016c22006a200141f0086a41880110f6042002360288012001200a41016a22093602e00741171029220a450d01200a410f6a410029008fc944370000200a41086a4100290088c944370000200a4100290080c944370000200a4117412e102a220a450d02200a200c360017200141f0086a41186a220c4200370300200141f0086a41106a220f420037030020274200370300200142003703f008200a411b200141f0086a100020014188056a41186a200c29030037030020014188056a41106a200f29030037030020014188056a41086a2027290300370300200120012903f00837038805200141f0086a2008200910be0120014188056a412020012802f008220c20012802f8081004024020012802f408450d00200c102e0b200a102e02402009450d0020004190016a21092008210a03400240200a2d00004113460d00200a102f0b200a4190016a210a200941f07e6a22090d000b0b0240200b450d002008102e0b20274200370300200142003703f008418e99c5004113200141f0086a100320072027290300370300200120012903f0083703d8072001200241016a3602a00b200141d8076a4110200141a00b6a410410040c040b20094108102c000b41174101102c000b412e4101102c000b200141a00b6a200141a8056a41880110f6041a200141003b01f008200141d8006a200141a00b6a200141f0086a10950220012001280258453a00a90b200141073a00a80b200141053a00a00b200120023602ac0b41c8ecc5004100200141a00b6a107220274200370300200142003703f008418e99c5004113200141f0086a100320072027290300370300200120012903f0083703d8072001200241016a3602a00b200141d8076a4110200141a00b6a410410040b20152014470d000b201421150c040b200b4108102c000b41a0014108102c000b41244104102c000b418cc6c5001058000b024020152014460d00200141a80b6a2107200141a00b6a4199016a210a0340200141a00b6a201541980110f6041a20154198016a2d0000210620012015419c016a28000036008b0a200120154199016a2800003602880a20064103460d01200141a8056a200141a00b6a41980110f6041a2001200128008b0a3600f308200120012802880a3602f008200141a00b6a200141a8056a41980110f6041a200a20012802f008360000200a41036a20012800f308360000200120063a00b80c2007102f201541a0016a22152014470d000b0b02402012450d002011102e0b024002400240411710292206450d002006410f6a410029008fc944370000200641086a4100290088c94437000020064100290080c94437000020064117412e102a2206450d0120062010360017200141f0086a41186a220a4200370300200141f0086a41106a22074200370300200141f0086a41086a22024200370300200142003703f0082006411b200141f0086a100020014188056a41186a200a29030037030020014188056a41106a200729030037030020014188056a41086a2002290300370300200120012903f00837038805200141a00b6a20014188056a108703024020012802a00b220b450d0020014188056a412010060b200141a00b6a41086a280200210a20012802a40b210f2006102e200b4108200b1b220c200a4100200b1b4190016c220a6a2102200c21060240200a450d00200a41f07e6a2107200141a00b6a4101722108200c21060240034020062d0000210a200141a8056a200641016a41870110f6041a200a4114460d01200141a00b6a200141a8056a41870110f6041a024002400240200a4113470d0020070d01200221060c050b20064188016a2800002109200141880a6a200141a00b6a41870110f6041a2001200a3a00a00b2008200141880a6a41870110f6041a200141003b01a805200141d0006a200141a00b6a200141a8056a1095022001280250210a200120093602ac0b2001200a453a00a90b200141073a00a80b200141053a00a00b41c8ecc5004100200141a00b6a10722007450d010b20064190016a2106200741f07e6a21070c010b0b200221060c010b20064190016a21060b20062002460d02200141a00b6a4101722107034020062d0000210a200141a00b6a200641016a418f0110f6041a200a4114460d03200141a8056a200141a00b6a418f0110f6041a2001200a3a00a00b2007200141a8056a418f0110f6041a0240200a4113460d00200141a00b6a102f0b20064190016a22062002470d000c030b0b41174101102c000b412e4101102c000b0240200b450d00200f450d00200c102e0b024002400240024002400240024002400240024020104180e101700d00200141c8006a41abd9c5004114107d2001280248450d00200128024c220a450d00200141f0086a41086a22064200370300200142003703f00841edf8c000410f200141f0086a1003200141d8076a41086a22092006290300370300200120012903f0083703d807200141a00b6a200141d8076a10de010240024020012802a00b22070d004104210741002102410021080c010b200141a00b6a41086a280200210220012802a40b21080b20064200370300200142003703f00841fcf8c0004114200141f0086a100320092006290300370300200120012903f0083703d807200141a00b6a200141d8076a10dd010240024020012802a80b220c0d00200141c0006a41b0f3c200410d107d4100210b2001280244410020012802401b2106200221090c010b20012802a40b220b20026a200141b00b6a2802006b210920012802a00b210620012802ac0b450d00200c102e0b024002400240024002402009200a490d000240200b200a4f0d00200b200a6b220620026a220a20064f0d022007200a41246c6a28022021060c010b200141386a41a0f9c0004114107d200128023c410020012802381b20066a21060b200641ffe0016a220620064180e101706b210602402008450d002007102e0b20062010470d04200141f0086a41086a22064200370300200142003703f00841edf8c000410f200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141a00b6a200141d8076a10de010240024020012802a00b220f0d004104210f41002113410021370c010b200141a00b6a41086a280200211320012802a40b21370b200141306a41abd9c5004114107d2001280234213820012802302139200141286a41b0f3c200410d107d200128022c410020012802281b210e0240024002400240200f200f201341246c6a220a460d00200f41206a280200200e4d0d010b4101210941002107410021020c010b200141a00b6a41186a2206200f41186a290200370300200141a00b6a41106a2207200f41106a290200370300200141a00b6a41086a2202200f41086a2902003703002001200f2902003703a00b412010292209450d01200920012903a00b370000200941186a2006290300370000200941106a2007290300370000200941086a20022903003700000240200f41246a2206200a470d0041012107410121020c010b200f201341246c6a213a412021084101210a4101210703400240200641206a280200200e4d0d00200a21020c020b200141c0046a41186a220b200641186a290200370300200141c0046a41106a220c200641106a290200370300200141c0046a41086a2200200641086a290200370300200120062902003703c004024002402007200a460d00200a21020c010b200a41016a2202200a490d17200a4101742227200220022027491b220241ffffff3f712002470d17200241057422274100480d1702400240200a0d002027102921090c010b2009200a4105742027102a21090b20090d0020274101102c000b200920086a220a20012903c004370000200a41186a200b290300370000200a41106a200c290300370000200a41086a2000290300370000200841206a2108200741016a21072002210a203a200641246a2206470d000b0b024002400240024002402038410020391b2208201320076b220a4d0d00200141206a41b4f9c000411c107d2001280224210b2001280220210c200141f0086a41086a22064200370300200142003703f00841fcf8c0004114200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807410810292206450d0120014288808080c0003702a40b200120063602a00b2006200b4100200c1b200e6a3600000240024020012802a40b220b20012802a80b22066b4104490d0020012802a00b210b0c010b200641046a220c2006490d1a200b4101742206200c200c2006491b22064100480d1a02400240200b0d0020061029210b0c010b20012802a00b200b2006102a210b0b200b450d03200120063602a40b2001200b3602a00b20012802a80b21060b2001200641046a3602a80b200b20066a2008200a6b22003600002007200141a00b6a104702402007450d002007410574210a2009210603402006200141a00b6a104a200641206a2106200a41606a220a0d000b0b20012802a40b2106200141d8076a411020012802a00b220a20012802a80b100402402006450d00200a102e0b02402002450d002009102e0b200141c0056a4200370300200141b8056a4200370300200141b0056a4200370300200142003703a805200041066a220ead42307e220d422088a70d14200da72206417f4c0d140240024020060d004108213a4108210a0c010b20061029223a450d04203a210a0b200141a00b6a41186a220b200141a8056a41186a290300370300200141a00b6a41106a220c200141a8056a41106a290300370300200141a00b6a41086a200141a8056a41086a290300370300200120012903a8053703a00b200e4102490d04200820076a20136b41056a2107200a21060340200141c0046a41186a2202200b290300370300200141c0046a41106a2209200c290300370300200141c0046a41086a2208200141a00b6a41086a290300370300200120012903a00b3703c0042006420037030820064200370300200641106a20012903c004370300200641186a2008290300370300200641206a2009290300370300200641286a2002290300370300200641306a21062007417f6a22070d000b200041056a21070c070b2002450d082009102e0c080b41084101102c000b20064101102c000b20064108102c000b41002107200a2106200e0d020c030b41204101102c000b4190f9c000200a20021038000b2006420037030820064200370300200620012903a00b370310200641186a200141a80b6a290300370300200641206a200141b00b6a290300370300200641286a200141a00b6a41186a290300370300200741016a21070b200141f0086a41086a22064200370300200142003703f00841d0f9c0004113200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141003602a80b200142013703a00b2007200141a00b6a104702402007450d00200a200741306c6a21090340200a41086a290300210d200a290300211f0240024020012802a40b220720012802a80b22066b4110490d0020012802a00b21070c010b200641106a22022006490d1320074101742206200220022006491b22064100480d130240024020070d002006102921070c010b20012802a00b20072006102a21070b2007450d05200120063602a40b200120073602a00b20012802a80b21060b200720066a2207200d3700082007201f3700002001200641106a3602a80b200a41106a200141a00b6a104a200a41306a220a2009470d000b0b20012802a40b2106200141d8076a411020012802a00b220a20012802a80b100402402006450d00200a102e0b0240200e450d00203a102e0b200141083a00a00b200141a00b6a41086a2000360200200141023a00a40b41c8ecc5004100200141a00b6a10720b2037450d00200f102e0b200141f0086a41086a22064200370300200142003703f00841fcf8c0004114200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141a00b6a200141d8076a10dd0120012802a80b2218450d1120012802ac0b211120012802a00b2010470d10200141f0086a41086a22064200370300200142003703f00841fcf8c0004114200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141a00b6a200141d8076a10dd01024020012802a80b223b450d00200141d8076a411010060b0240203b0d0002402011450d002018102e0b4199fac000410f100941a8fac000413510090c120b20012902ac0b211d20012802a40b211442002121200141f0086a41086a22064200370300200142003703f00841d0f9c0004113200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141a00b6a200141d8076a10e0010240024020012802a00b222a450d00200141d8076a4110100620012902a40b21210c010b4108212a0b200141186a41b0f3c200410d107d200128021c21392001280218212c200141106a41a0f9c0004114107d2001280210212f20012802142130202a2021422088a7223c41306c6a210e0240024020140d0041002100410021094100210a0c010b2014417f6a21094100210a0240202a200e460d000240202a203c41306c6a220641506a220e290300200e41086a2903008450450d00410121000c020b20014188056a41186a200641606a220641186a29000037030020014188056a41106a200641106a29000037030020014188056a41086a200641086a29000037030020012006290000370388054101210a0b410021000b200141a90b6a20014188056a41086a290300370000200141b10b6a20014188056a41106a290300370000200141b90b6a20014188056a41186a2903003700002001200a3a00a00b20012001290388053700a10b200141a00b6a4101722106200a450d0620064280809aa6eaafe3014200109401200141e8046a41086a200641086a290000370300200141e8046a41106a200641106a290000370300200141e8046a41186a200641186a290000370300200120062900003703e80420012d00a00b4101470d07412010292236450d01203620012903e804370000203641186a200141e8046a41186a290300370000203641106a200141e8046a41106a290300370000203641086a200141e8046a41086a290300370000200141a00b6a41017221064102210241202107410121354101212d0340024002400240024020090d00410021090c010b2009417f6a2109200041ff01710d000240202a200e470d00410021000c010b200e41506a2208290300200841086a290300844200520d01410121002008210e0b200620012903c004370000200641086a200141c0046a41086a290300370000200641106a200141c0046a41106a290300370000200641186a200141c0046a41186a2903003700004100210a200141003a00a00b0c010b200141c0046a41186a200e41606a220a41186a290000220d370300200141c0046a41106a200a41106a290000221f370300200141c0046a41086a200a41086a29000022203703002001200a29000022223703c00420062022370000200641086a2020370000200641106a201f370000200641186a200d370000200141013a00a00b20064280809aa6eaafe30142001094014100210020012d00a00b210a2008210e0b200141c0066a41186a2208200641186a290000370300200141c0066a41106a220b200641106a290000370300200141c0066a41086a220c200641086a290000370300200120062900003703c0060240200a41ff0171450d00200141a00b6a41186a220f2008290300370300200141a00b6a41106a2208200b290300370300200141a00b6a41086a220b200c290300370300200120012903c0063703a00b02402035202d470d00203541016a220a2035490d112002200a200a2002491b222d41ffffff3f71202d470d11202d410574220a4100480d110240024020350d00200a102921360c010b20362007200a102a21360b2036450d080b203620076a220a20012903a00b370000200a41186a200f290300370000200a41106a2008290300370000200a41086a200b290300370000200241026a2102200741206a2107203541016a21350c010b0b203620076a21372035450d08200141a00b6a41086a21022036210f0340200141d8076a200f10c501024020012802d8074101470d0020012802e0072107200141880a6a10c70120012802880a2138024020012802900a2206450d00200641216c210a203841016a21062007410876210941012007411f7174210020074105764107712208417f73210e034002402006417f6a2d00004101470d00200141a00b6a41186a200641186a290000370300200141a00b6a41106a200641106a2900003703002002200641086a290000370300200120062900003703a00b200120093602c00b200141a8056a200141a00b6a10c9010240200820012802b00522074f0d002007200e6a220b20074f0d0820012802a805220c200b4102746a2802002000712107024020012802ac05450d00200c102e0b2007450d01200141a00b6a200610ca01024020012903a00b4201510d00411310292207450d0a20074100290086fa403700002007410f6a4100280095fa40360000200741086a410029008efa4037000020014293808080b0023702ac05200120073602a8052006200141a8056a104a20012802ac05210b20012802b005210c20012802a8052107200141c0046a41186a22134200370300200141c0046a41106a223a4200370300200141c0046a41086a22274200370300200142003703c0042007200c200141c0046a1000200141f0086a41186a2013290300370300200141f0086a41106a203a290300370300200141f0086a41086a2027290300370300200120012903c0043703f008200141f0086a41201006200b450d022007102e0c020b200141086a41bfd9c5004111107d2001200128020c41016a410120012802081b3602cc0b411310292207450d0a20074100290086fa403700002007410f6a4100280095fa40360000200741086a410029008efa4037000020014293808080b0023702ac05200120073602a8052006200141a8056a104a20012802ac05210b20012802b005210c20012802a8052107200141c0046a41186a22134200370300200141c0046a41106a223a4200370300200141c0046a41086a22274200370300200142003703c0042007200c200141c0046a1000200141f0086a41186a2013290300370300200141f0086a41106a203a290300370300200141f0086a41086a2027290300370300200120012903c0043703f008200141203602ac052001200141f0086a3602a8052002200141a8056a10cb01200b450d012007102e0c010b20012802ac05450d0020012802a805102e0b200641216a2106200a415f6a220a0d000b0b200128028c0a450d002038102e0b2037200f41206a220f470d000c090b0b20064101102c000b41204101102c000b4190f9c000200b20071038000b41134101102c000b41134101102c000b200a4101102c000b200141e8046a41186a200641186a290000370300200141e8046a41106a200641106a290000370300200141e8046a41086a200641086a290000370300200120062900003703e8040b4100212d4101213741012136410021350b200141f0086a41086a22064200370300200142003703f00841edf8c000410f200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141a00b6a200141d8076a10de010240024020012802a00b222e0d00410021324104212e410021080c010b200141a00b6a41086a280200210820012802a40b21320b200141013602a00b0240024002400240201d422088a72209450d00410021174100213d024002402009202e200841246c6a2202202e6b41246e2206200620094b1b2206450d002006410574220a4100480d0b200a10292207450d01200120073602a00b2006213d0b202e21062009210720012802a00b223e210a03400240200220066b41ec004b0d0020022006460d06202e200841246c6a210c4101210b02400340200a2006290000370000200a41186a200641186a290000370000200a41106a200641106a290000370000200a41086a200641086a2900003700002007200b2202460d01200241016a210b200a41206a210a200c200641246a2206470d000b0b201720026a21170c060b200a2006290000370000200a41186a200641186a290000370000200a41106a200641106a290000370000200a41086a200641086a290000370000024020074101470d00201741017221170c060b200a2006290024370020200a41386a2006413c6a290000370000200a41306a200641346a290000370000200a41286a2006412c6a29000037000020074102460d04200a2006290048370040200a41d8006a200641e0006a290000370000200a41d0006a200641d8006a290000370000200a41c8006a200641d0006a29000037000020074103460d03200a200629006c370060200a41f8006a20064184016a290000370000200a41f0006a200641fc006a290000370000200a41e8006a200641f4006a290000370000201741046a2117200a4180016a210a20064190016a21062007417c6a22070d000c050b0b200a4101102c000b4100213d20012802a00b213e410021170c020b201741037221170c010b201741027221170b20304100202f1b20394100202c1b6a212f202e200841246c6a21390240024002400240024002400240024002402009450d002039202e460d01200941016a210a200841246c2107202e21060340200141c0046a41186a200641186a290200370300200141c0046a41106a200641106a290200370300200141c0046a41086a200641086a290200370300200120062902003703c004200a417f6a220a450d04200641246a21062007415c6a22070d000b203921060c020b2039202e470d040b202e21060b20362037460d0120014198046a41186a203641186a220a29000037030020014198046a41106a203641106a220729000037030020014198046a41086a203641086a220229000037030020012036290000370398042002290000210d2007290000211f20362900002120200141a8056a41186a200a290000370300200141a8056a41106a201f370300200141a8056a41086a200d370300200120203703a805203641206a210741022102202f21090c040b200641206a2802002109200141a00b6a41186a200141c0046a41186a290300370300200141a00b6a41106a200141c0046a41106a290300370300200141a00b6a41086a200141c0046a41086a290300370300200120012903c0043703a00b200641246a21060c020b02402032450d00202e102e0b41042113410021314100212b4104210b0c030b200141a00b6a41186a202e41186a290200370300200141a00b6a41106a202e41106a290200370300200141a00b6a41086a202e41086a2902003703002001202e2902003703a00b202e41246a2106202e28022021090b200141a8056a41186a200141a00b6a41186a290300370300200141a8056a41106a200141a00b6a41106a290300370300200141a8056a41086a200141a00b6a41086a290300370300200120012903a00b3703a80541002102203621070b417f417f203920066b41246d220a203720076b4105766a22082008200a491b220a41016a22082008200a491b222bad42247e220d422088a70d01200da7220a417f4c0d01024002400240024002400240024002400240200a0d00410421130c010b200a10292213450d010b201320012903a805370200201341186a200141a8056a41186a290300370200201341106a200141a8056a41106a290300370200201341086a200141a8056a41086a2903003702002013200936022002402002450d00024020072037470d00410121310c050b200141f0086a41186a200741186a220a290000370300200141f0086a41106a200741106a2202290000370300200141f0086a41086a200741086a2209290000370300200120072900003703f0082009290000210d2002290000211f20072900002120200141a8056a41186a200a290000370300200141a8056a41106a201f370300200141a8056a41086a200d370300200120203703a805200741206a21070c020b024020062039470d00024020072037460d0020014198046a41186a200741186a220a29000037030020014198046a41106a200741106a220229000037030020014198046a41086a200741086a220929000037030020012007290000370398042009290000210d2002290000211f20072900002120200141a8056a41186a200a290000370300200141a8056a41106a201f370300200141a8056a41086a200d370300200120203703a805200741206a21070c030b410121310c040b200141a00b6a41186a200641186a220a290200370300200141a00b6a41106a200641106a2202290200370300200141a00b6a41086a200641086a2209290200370300200120062902003703a00b200141a8056a41086a2009290200370300200141a8056a41106a2002290200370300200141a8056a41186a200a290200370300200120062902003703a8052006280220210041002108200641246a21060c020b200a4104102c000b41022108202f21000b410221094102210a412421020340200141d8076a41186a220b200141a8056a41186a220e290300370300200141d8076a41106a220c200141a8056a41106a223a290300370300200141d8076a41086a220f200141a8056a41086a2227290300370300200120012903a8053703d8070240200a2231417f6a220a202b470d00200a417f417f203920066b41246d2238203720076b4105766a222c202c2038491b223841016a222c202c2038491b6a2238200a490d0c2009203820382009491b222bad42247e220d422088a70d0c200da7220a4100480d0c0240024020314101470d00200a102921130c010b20132002200a102a21130b2013450d030b201320026a220a20012903d807370200200a41186a200b290300370200200a41106a200c290300370200200a41086a200f290300370200200a41206a20003602000240024002400240200841ff01710e03010200010b20072037460d04200141f0086a41186a200741186a220a290000370300200141f0086a41106a200741106a2208290000370300200141f0086a41086a200741086a220b290000370300200120072900003703f008200b290000210d2008290000211f20072900002120200e200a290000370300203a201f3703002027200d370300200120203703a805200741206a21074101210b41022108202f21000c020b024020392006470d0041022108024020072037470d004100210b0c030b20014198046a41186a200741186a220a29000037030020014198046a41106a200741106a220b29000037030020014198046a41086a200741086a220c2900003703002001200729000037039804200c290000210d200b290000211f20072900002120200e200a290000370300203a201f3703002027200d370300200120203703a805200741206a21074101210b202f21000c020b200141a00b6a41186a200641186a220a290200370300200141a00b6a41106a200641106a2208290200370300200141a00b6a41086a200641086a220b290200370300200120062902003703a00b200b290200210d2008290200211f20062902002120200e200a290200370300203a201f3703002027200d370300200120203703a805200628022021004101210b41002108200641246a21060c010b20392006460d02200e200641186a290200370300203a200641106a2902003703002027200641086a290200370300200120062902003703a8052006280220210041012108200641246a21064101210b0b200941026a2109203141016a210a200241246a2102200b0d000b0b02402032450d00202e102e0b20314115490d012031410176223fad42247e220d422088a70d04200da72206417f4c0d0402400240024020060d00410421344104210b0c010b200610292234450d012034210b0b2013415c6a2110201341b47f6a21124104213a41002115410021082031212c0340202c21024100212c4101210902402002417f6a2216450d000240024002400240024002402013201641246c6a41206a280200200241246c220a20136a41586a2802002206490d002002417e6a210f2012200a6a21074100212c4100210a03400240200f200a470d00200221090c080b200a41016a210a2006200728020022094f210c2007415c6a210720092106200c0d000b200a41016a2109200a417f7320026a21070c010b2012200241096c410274220f6a210a2016210702400340024020074101470d00410021070c020b2007417f6a21072006200a280200220949210c200a415c6a210a20092106200c0d000b0b20022007490d01200220314b0d03200220076b2209410176220c450d002010200f6a21062013200741246c6a210a0340200141a00b6a41206a220f200a41206a2200280200360200200141a00b6a41186a220e200a41186a2227290200370300200141a00b6a41106a2237200a41106a2238290200370300200141a00b6a41086a2239200a41086a222c2902003703002001200a2902003703a00b200641206a222e280200212f200641186a2230290200210d200641106a2232290200211f200641086a22332902002120200a2006290200370200202c20203702002038201f3702002027200d3702002000202f360200202e200f2802003602002030200e2903003702002032203729030037020020332039290300370200200620012903a00b3702002006415c6a2106200a41246a210a200c417f6a220c0d000b0b024020070d002007212c0c050b0240200941094d0d002007212c0c050b200220314b0d012013200741246c6a210f034020022007417f6a222c490d0402402002202c6b22094102490d002013200741246c6a220641206a220a2802002013202c41246c6a220041206a220c280200220e4f0d00200141c0046a41186a2227200041186a2237290200370300200141c0046a41106a2238200041106a2239290200370300200141c0046a41086a222e200041086a222f290200370300200120002902003703c00420002006290200370200202f200641086a2902003702002039200641106a2902003702002037200641186a290200370200200c200a280200360200024020094103490d002016210a200f210c200041e8006a280200200e4f0d0002400340200c220641206a200641c4006a280200360200200641186a2006413c6a290200370200200641106a200641346a290200370200200641086a2006412c6a2902003702002006200641246a220c2902003702002007200a417f6a220a460d01200641e8006a280200200e490d000b0b200641246a21060b200620012903c0043702002006200e360220200641186a2027290300370200200641106a2038290300370200200641086a202e2903003702000b202c450d05200f415c6a210f202c21072009410a4f0d050c000b0b200720021035000b20022007417f6a222c490d010b20022031105e000b202c20021035000b02400240024020152008470d00201541016a22062015490d0e2015410174220a20062006200a491b220641ffffffff01712006470d0e2006410374220a4100480d0e0240024020150d00200a1029213a0c010b203a2015410374200a102a213a0b203a450d01200621150b203a20084103746a220620093602042006202c360200200841016a2227210820274102490d0103400240024002400240203a20272200417f6a22274103746a2206280200450d002000410374203a6a220941746a28020022022006280204220a4d0d0041022108200041024d0d06203a2000417d6a22064103746a2802042207200a20026a4d0d0141032108200041034d0d06200941646a280200200720026a4d0d01200021080c060b20004103490d012006280204210a203a2000417d6a22064103746a28020421070b2007200a490d010b2000417e6a21060b0240024002400240024002402000200641016a222e4d0d00200020064d0d01203a20064103746a2237280204222f20372802006a2206203a202e4103746a22382802002239490d02200620314b0d03203741046a21302013203941246c6a220f2038280204220e41246c220a6a2109200641246c2107200620396b2208200e6b2206200e4f0d0420342009200641246c220a10f6041a200b200a6a210202400240200e4101480d00200641014e0d010b20092106200b210a0c060b201020076a210720092106034020072006415c6a22082002415c6a220c2002417c6a2802002006417c6a2802004922091b220a290200370200200741206a200a41206a280200360200200741186a200a41186a290200370200200741106a200a41106a290200370200200741086a200a41086a2902003702002002200c20091b21020240200f2008200620091b2206490d00200b210a0c070b2007415c6a2107200b210a200b2002490d000c060b0b41f484c000202e20001038000b41f484c000200620001038000b203920061035000b20062031105e000b2034200f200a10f6041a200b200a6a210202400240200e4101480d002008200e4a0d010b200f2106200b210a0c010b201320076a210c200b210a200f2106034020062009200a200941206a280200200a41206a2802004922081b2207290200370200200641206a200741206a280200360200200641186a200741186a290200370200200641106a200741106a290200370200200641086a200741086a290200370200200a200a41246a20081b210a200641246a2106200941246a200920081b2209200c4f0d012002200a4b0d000b0b2006200a2002200a6b220720074124706b10f6041a2030202f200e6a360200203720393602002038203841086a202e417f7320006a41037410f7041a20272108202741014d0d020c000b0b200a4104102c000b202c0d000b02402015450d00203a102e0b203f450d032034102e0c030b20064104102c000b200a4104102c000b20314102490d002031417f6a21072013203141246c6a2109410021080340024002400240203120072206417f6a2207490d00203120076b220a4102490d022013200641246c6a220641206a22022802002013200741246c6a220b41206a220f280200220c4f0d02200141c0046a41186a2200200b41186a220e290200370300200141c0046a41106a223a200b41106a2227290200370300200141c0046a41086a2237200b41086a22382902003703002001200b2902003703c004200b20062902003702002038200641086a2902003702002027200641106a290200370200200e200641186a290200370200200f2002280200360200200a4103490d01200821022009210a200b41e8006a280200200c4f0d010340200a2206415c6a220a2006290200370200200a41206a200641206a280200360200200a41186a200641186a290200370200200a41106a200641106a290200370200200a41086a200641086a2902003702002002417f6a2202450d02200641246a210a200641c4006a280200200c4f0d020c000b0b200720311035000b200620012903c0043702002006200c360220200641186a2000290300370200200641106a203a290300370200200641086a20372903003702000b200841016a21082009415c6a210920070d000b0b2013210b0b200141f0086a41086a22064200370300200142003703f00841edf8c000410f200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141003602a80b200142013703a00b2031200141a00b6a10470240024002402031450d002013203141246c6a21082013210a0340200a200141a00b6a104a200a41206a28020021020240024020012802a40b220720012802a80b22066b4104490d0020012802a00b21070c010b200641046a22092006490d0a20074101742206200920092006491b22064100480d0a0240024020070d002006102921070c010b20012802a00b20072006102a21070b2007450d03200120063602a40b200120073602a00b20012802a80b21060b2001200641046a3602a80b200720066a20023600002008200a41246a220a470d000b0b20012802a40b2106200141d8076a411020012802a00b220a20012802a80b100402402006450d00200a102e0b4100210a0240203141246c22060d0041012102410021090c020b200641246d220941ffffff3f712009470d07200941057422064100480d072006102922020d0120064101102c000b20064101102c000b02402031450d002013203141246c6a21074100210a200221060340201341086a290000210d201341106a290000211f20132900002120200641186a201341186a290000370000200641106a201f370000200641086a200d37000020062020370000200a41016a210a200641206a21062007201341246a2213470d000b0b0240202b450d00200b102e0b2002200a200141c0066a41004120200a676b105f203e20172002200a10df0102402009450d002002102e0b200141f0086a41086a22064200370300200142003703f00841f4f9c0004112200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141003602a00b200141d8076a4110200141a00b6a100821060240024020012802a00b220a417f460d002006450d002001200a3602ac05200120063602a805200141a00b6a200141a8056a1030024020012802a00b2237450d00200141a80b6a280200213a20012802a40b2138200a450d022006102e0c020b41eff0c2004133200141c0066a4184f4c2001053000b41002138410121374100213a0b20014188096a420037030020014180096a4200370300200141f8086a4200370300200142003703f008203a41ffffff3f71203a470d00203a4105742206417f4c0d000240024020060d00410121080c010b200610292208450d020b200141a00b6a41186a2207200141f0086a41186a290300370300200141a00b6a41106a2202200141f0086a41106a290300370300200141a00b6a41086a2209200141f0086a41086a290300370300200120012903f0083703a00b203a4102490d02203a417f6a210a200821060340200620012903a00b370000200641186a2007290300370000200641106a2002290300370000200641086a2009290300370000200641206a2106200a417f6a220a0d000b203a417f6a21130c030b1032000b20064101102c000b4100211320082106203a450d010b200620012903a00b370000200641186a200141a00b6a41186a290300370000200641106a200141a00b6a41106a290300370000200641086a200141a00b6a41086a290300370000201341016a21130b202a203c41306c6a21062021a72100410021270c010b102d000b024002400240024002400240034002402014450d002006202a460d02200641506a2206290300200641086a29030084500d0203402014417f6a2214450d01202a2006460d03200641506a210a200641506a2106200a290300200a41086a2903008450450d000c030b0b2006202a460d0102400340200641506a2207290300210d200741086a290300211f200141a8056a41186a2202200641606a220a41186a290300370300200141a8056a41106a2209200a41106a290300370300200141a8056a41086a220b200a41086a2903003703002001200a2903003703a805200d201f84500d01200141a00b6a41186a220a2002290300370300200141a00b6a41106a22022009290300370300200141a00b6a41086a2209200b290300370300200120012903a8053703a00b20014188056a200141a00b6a10c501200141f0086a41186a220b200a290300370300200141f0086a41106a220c2002290300370300200141f0086a41086a220f2009290300370300200120012903a00b3703f00802402001280288054101460d0020072106202a2007470d010c040b0b200141c0066a41086a220e200f290300370300200141c0066a41106a220f200c290300370300200141c0066a41186a220c200b290300370300200120012903f008220d3703d8072001200d3703c0062001280290052107200a200c2903003703002002200f2903003703002009200e290300370300200120012903c0063703a00b201320074d0d03200641506a2106200820074105746a220720012903a00b370000200741186a200a290300370000200741106a2002290300370000200741086a2009290300370000202741016a2127410021140c010b0b200141d8076a41086a200141880a6a41086a290300370300200141d8076a41106a200141880a6a41106a290300370300200141d8076a41186a200141880a6a41186a290300370300200120012903880a3703d8070b02402000450d00202a102e0b02402013203a203a20134b1b2209450d00203721062008210a41002107034002402006200a460d002006200a412010f804450d00411610292202450d04200241002900d7f8403700002002410e6a41002900e5f840370000200241086a41002900dff84037000020014296808080e0023702a40b200120023602a00b2006200141a00b6a104a20012802a40b210b20012802a80b210c20012802a00b2102200141c0046a41186a220f4200370300200141c0046a41106a22004200370300200141c0046a41086a220e4200370300200142003703c0042002200c200141c0046a1000200141f0086a41186a200f290300370300200141f0086a41106a2000290300370300200141f0086a41086a200e290300370300200120012903c0043703f008200141f0086a41201006200b450d002002102e0b200641206a2106200a41206a210a200741016a22072009490d000b0b200820134105746a21062013210b20134104490d02200141a00b6a41206a210c200141e00b6a210f200141a00b6a41e0006a2100200141a00c6a210e200141b80b6a2107200141b00b6a2102200141a80b6a21092006210a2013210b0340200742003703002002420037030020094200370300200142003703a00b0240200c200a460d00200a41606a200141a00b6a412010f804450d00200b417f6a210a0c050b200742003703002002420037030020094200370300200142003703a00b0240200f200a460d00200a41406a200141a00b6a412010f804450d00200b417e6a210a0c050b200742003703002002420037030020094200370300200142003703a00b02402000200a460d00200a41a07f6a200141a00b6a412010f804450d00200b417d6a210a0c050b200742003703002002420037030020094200370300200142003703a00b200a41807f6a210602400240200e200a460d002006200141a00b6a412010f8040d010b200b417c6a210b2006210a200620086b41e0004b0d010c040b0b200b417c6a210a0c030b41e4f9c000200720131038000b41164101102c000b20062008460d01200b417f6a210a200141a00b6a41206a2107200141b80b6a2102200141b00b6a2109200141a80b6a210b03402002420037030020094200370300200b4200370300200142003703a00b024020072006460d00200641606a200141a00b6a412010f8040d020b200a417f6a210a2008200641606a2206470d000c020b0b200a41016a22062013201320064b1b21130b200141bc0b6a2017360200200141b80b6a203d360200200141b40b6a203e360200200141a00b6a41106a2035360200200141ac0b6a202d360200200141083a00a00b200141a00b6a41086a2036360200200141033a00a40b41c8ecc5004100200141a00b6a1072200141f0086a41086a22064200370300200142003703f00841f4f9c0004112200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141003602a80b200142013703a00b2013200141a00b6a104702402013450d002013410574210a2008210603402006200141a00b6a104a200641206a2106200a41606a220a0d000b0b20012802a40b2106200141d8076a411020012802a00b220a20012802a80b100402402006450d00200a102e0b0240203a450d002008102e0b200141f0086a41086a22064200370300200142003703f00841f6d9c5004116200141f0086a1003200141d8076a41086a220a2006290300370300200120012903f0083703d807200120273602a00b200141d8076a4110200141a00b6a41041004200141bfd9c5004111107d200128020021072001280204210220064200370300200142003703f00841bfd9c5004111200141f0086a1003200a2006290300370300200120012903f0083703d8072001200241016a410120071b3602a00b200141d8076a4110200141a00b6a4104100402402038450d002037102e0b201da7450d00203b102e0b2011450d002018102e0b02402003450d00200341246c210a2005210603400240024020062d0000220741034b0d0002400240024020070e0404000102040b2006410c6a280200450d03200641086a280200102e0c030b2006410c6a280200450d02200641086a280200102e0c020b2006410c6a280200450d01200641086a280200102e0c010b200641086a280200450d00200641046a280200102e0b200641246a2106200a415c6a220a0d000b0b02402004450d002005102e0b200141c00c6a24000bef0e03047f027e077f230041206b2202240002400240024002400240024002400240024002400240024002400240024041a20210292203450d00200242a20237020420022003360200200341003b00002002410236020802400240200128020022032903684202520d0020022802002101024020022802044102470d00200141024104102a2201450d0420024104360204200220013602000b200141033a00022002200228020841016a3602080c010b20022802002101024020022802044102470d00200141024104102a2201450d0420024104360204200220013602000b20014183013a00022002200228020841016a360208200320021049200341246a200210e1020240024020032903684201510d0002400240200228020420022802082201460d00200228020021040c010b200141016a22042001490d1220014101742205200420042005491b22054100480d120240024020010d002005102921040c010b200228020020012005102a21040b2004450d072002200536020420022004360200200228020821010b2002200141016a360208200420016a41003a00000c010b200341f8006a29030020032903702206420c882207420120074201561b8021070240024020022802042204200228020822016b4102490d00200228020021040c010b200141026a22052001490d1120044101742201200520052001491b22014100480d110240024020040d002001102921040c010b200228020020042001102a21040b2004450d072002200136020420022004360200200228020821010b2002200141026a360208200420016a2007a741047420067aa7417f6a22014101200141014b1b2201410f2001410f491b723b00000b20034180016a20021066200220034188016a360210200241106a2002106b0b20034198016a200210bc012002280208210320024100360218200242013703102003417e6a200241106a10472002280208220841014d0d0520022802182105200228021421092002280210210a2002410036020820022802002103024002402008417e6a220b450d004102210c2005450d0d2003200a2d00003a0000410121042002200228020841016a36020820054101460d0d200a20056a210d2003200a2d00013a00012002200228020841016a3602084102210c200a41026a21012005417e6a220e0d014100210e0c0b0b0240024002402002280204220120054f0d0020014101742204200520052004491b22044100480d120240024020010d002004102921030c010b200320012004102a21030b2003450d0a20022004360204200220033602002002280208210c0c010b4100210c2005450d010b2003200c6a2201200a2d00003a0000024020054101470d00200c41016a210c0c010b2005417f6a2104200a41016a2103200141016a21010340200120032d00003a0000200141016a2101200341016a21032004417f6a22040d000b200c20056a210c0b2002200c3602084102210c0c0b0b024002402002280204220320086b200e490d00200228020021030c010b2008200e6a22042008490d0f2003410174220c20042004200c491b22044100480d0f0240024020030d002004102921030c010b200228020020032004102a21030b2003450d0820022004360204200220033602000b200320056a200341026a200b10f7041a0240200520022802082203460d00200520036b210c2005417e6a2104200228020020036a2108410021030340024020042003470d002005210c0c0d0b200820036a20012d00003a00002002200228020841016a360208200141016a2101200c200341016a2203470d000b200d20016b220e0d004100210e410121040c090b200e4100480d0e200e102922040d08200e4101102c000b41a2024101102c000b41044101102c000b41044101102c000b20054101102c000b20014101102c000b418cc6c5001058000b20044101102c000b20044101102c000b2005210c0b0240200d2001460d00200420012d00003a000002400240200141016a200d470d00410121050c010b200a200520016b6a2108200a200520016b6a2105410121030340200420036a200120036a2d00003a00002008200341016a2203470d000b2005450d010b200420056a21080240024020022802042203200b200c6a22016b2005490d00200228020021030c010b200120056a220d2001490d0620034101742201200d200d2001491b22014100480d060240024020030d002001102921030c010b200228020020032001102a21030b2003450d0520022001360204200220033602000b2003200c20056a220d6a2003200c6a200b10f7041a0240200d20022802082203460d00200228020020036a2101200c20056a20036b210520042103034020082003460d01200120032d00003a00002002200228020841016a360208200341016a2103200141016a21012005417f6a22050d000b0b200d210c0b200e450d002004102e0b200b450d010b0240200c20022802082203460d002002280200220120036a2001200c6a200b10f7041a0b2002200b20036a3602080b02402009450d00200a102e0b20002002290300370200200041086a200241086a280200360200200241206a24000f0b20014101102c000b102d000b9104010d7f230041206b2202240002400240024002400240200128020822030d0041012104410421054100210641002107410021080c010b2001280200220920034103746a210a41042105410021014100210641002103410021084101210403402009280200210b02400240200820036b200941046a220c2802002207490d00200720036a210d0c010b200320076a220d2003490d042008410174220e200d200d200e491b220e4100480d040240024020080d00200e102921040c010b20042008200e102a21040b2004450d05200e21080b200420036a200b200710f6041a200c28020021030240024020062001460d00200141016a21070c010b200141016a22072001490d0420014101742206200720072006491b220641ffffffff03712006470d042006410274220b4100480d040240024020010d00200b102921050c010b20052001410274200b102a21050b2005450d030b200520014102746a200336020020072101200d2103200941086a2209200a470d000b0b200241186a22014200370300200241106a22034200370300200241086a22094200370300200242003703002004200520072002101e200041186a2001290300370000200041106a2003290300370000200041086a20092903003700002000200229030037000002402006450d002005102e0b02402008450d002004102e0b200241206a24000f0b200b4104102c000b102d000b200e4101102c000b8e1505027f017e057f017e047f230041b0086b22042400200441b0056a200141a00210f6041a200441d0036a200441b0056a10b901410121050240024002400240024002400240024002400240024020042802d0034101460d00200441d0036a41086a290300210620044180026a200441d0036a41106a41d00110f6041a20042006370328200441286a41086a20044180026a41d00110f6041a024020032802002201450d00200341086a28020021072003280204210841002109200441003602b00541dff0c2004110200441b0056a10082105024020042802b005220a417f460d002005450d00200a4104490d05200528000021092005102e0b411410292205450d05200541106a4100280093e545360000200541086a410029008be54537000020054100290083e545370000200541144128102a2205450d0620052009360014200441d0036a41186a22094200370300200441d0036a41106a220a4200370300200441d0036a41086a220b4200370300200442003703d00320054118200441d0036a1000200441f0076a41186a2009290300370300200441f0076a41106a200a290300370300200441f0076a41086a200b290300370300200420042903d0033703f007200441203602b4052004200441f0076a3602b00520012007200441b0056a1099022005102e02402008450d002001102e0b410021050b200441206a200441286a41d0006a1094022004280220210820042d0024210a200441b0056a200441286a41d80110f6041a41002109024002400240024002400240024002400240024020042903d0054202510d0020044180026a41186a200441b0056a41186a29030037030020044180026a41106a200441b0056a41106a29030037030020044180026a41086a200441b0056a41086a290300370300200420042903b00537038002200441f8056a2903002106200441f0056a290300210c200441e8056a2802002107411310292209450d10200941002900eff3423700002009410f6a41002800fef342360000200941086a41002900f7f34237000020044293808080b0023702d403200420093602d00320044180026a200441d0036a104a20042802d403210b200441186a20042802d003220d20042802d80310c002200428021c410020042802181b21090240200b450d00200d102e0b20092007470d04411310292209450d11200a410171210a200941002900eff3423700002009410f6a41002800fef342360000200941086a41002900f7f34237000020044293808080b0023702d403200420093602d00320044180026a200441d0036a104a20042802d403210b20042802d803210d20042802d0032109200441d0036a41186a220e4200370300200441d0036a41106a220f4200370300200441d0036a41086a22104200370300200442003703d0032009200d200441d0036a1000200441f0076a41186a200e290300370300200441f0076a41106a200f290300370300200441f0076a41086a2010290300370300200420042903d0033703f0072004200741016a3602d003200441f0076a4120200441d0036a410410040240200b450d002009102e0b200441106a41d1e4c5004117107d417f2004280214410020042802101b220920026a220720072009491b2209418080c002418080f001200a1b4b0d02200441d0036a41086a22074200370300200442003703d00341d1e4c5004117200441d0036a1003200441f0076a41086a220e2007290300370300200420042903d0033703f007200420093602d003200441f0076a4110200441d0036a41041004200441086a41b7e4c500411a107d417f200428020c410020042802081b220b418094ebdc034180afd0e502200a1b2209200820092008491b6a220d200d200b491b220b20094b0d0220074200370300200442003703d00341b7e4c500411a200441d0036a1003200e2007290300370300200420042903d0033703f0072004200b3602d003200441f0076a4110200441d0036a41041004200441d0036a200c200620044180026a2008200a200210850120042d00d0034101460d01200441fc036a2802002107200441f8036a280200210b200441f4036a2802002108200441ec036a280200210d200441e8036a280200210a0240200441f0036a2802002209450d002009410c6c2102200a210903400240200941046a280200450d002009280200102e0b2009410c6a2109200241746a22020d000b0b0240200d450d00200a102e0b02402007450d002007410c6c21022008210903400240200941046a280200450d002009280200102e0b2009410c6a2109200241746a22020d000b0b0240200b450d002008102e0b20044190086a41086a20044180026a41086a29030037030020044190086a41106a20044180026a41106a29030037030020044190086a41186a20044180026a41186a290300370300200420042903800237039008410121090b200441d0076a41186a220a20044190086a41186a2202290300370300200441d0076a41106a220b20044190086a41106a2207290300370300200441d0076a41086a220d20044190086a41086a220829030037030020042004290390083703d007200441d0036a200441b0056a41d0006a41880110f6041a2002200a2903003703002007200b2903003703002008200d290300370300200420042903d007370390084102210a02402009450d00200441f0076a41186a2002290300370300200441f0076a41106a2007290300370300200441f0076a41086a200829030037030020042004290390083703f0074101210a0b2004418a026a200441f0076a41086a29030037010020044192026a200441f0076a41106a2903003701002004419a026a200441f0076a41186a2903003701002004200a3a008102200420042903f00737018202200441003a0080022004200441d0036a20044180026a109502200428020421022004200428020022094100473a00b105200441003a00b00541c8ecc5004100200441b0056a1072200441003602b00541dff0c2004110200441b0056a1008210720042802b0052208417f470d07410121070c080b20042d00d103210220044180066a102f41032109024020020e0706020606040500060b410021090c050b20044180066a102f0b410421090c030b20044180066a102f200920074d0d010b410121090c010b410221090b20002009360204200041013602002000410c6a4100360200200041086a41c8ecc50036020020054521000c030b024020070d00410121070c010b20084104490d09200728000021082007102e200841016a21070b200420073602b00541dff0c2004110200441b0056a410410040240024020090d004100210920004100360204200041086a20023602000c010b02402002411b470d0002402009418de3c300460d002009418de3c300411b10f8040d010b20004104360204410121090c010b20002009360204200041086a2002360200410021090b200020093602002001450d0a20050d020c0a0b200041086a20042902d4033702002000420137020020032802002101410021000b20000d0820010d070c080b200341046a280200450d072001102e0c070b41eff0c200413320044180026a4184f4c2001053000b41144101102c000b41284101102c000b41134101102c000b41134101102c000b41eff0c200413320044180026a4184f4c2001053000b200341046a280200450d002001102e0b200441b0086a24000bcb0101047f230041306b22002400410021012000410036021841dff0c2004110200041186a100821020240024020002802182203417f460d002002450d0020034104490d01200228000021012002102e41dff0c200411010060b200041186a41086a220242003703002000420037031841a2e4c5004115200041186a1003200041086a41086a20022903003703002000200029031837030820002001360218200041086a4110200041186a41041004200041306a24000f0b41eff0c2004133200041286a4184f4c2001053000bad1604057f037e067f017e230041a0026b22012400200141b8016a41086a22024200370300200142003703b80141a2e4c5004115200141b8016a1003200141e0016a41086a22032002290300370300200120012903b8013703e001200141e0016a41101006200141306a41b7e4c500411a107d200128023421042001280230210520024200370300200142003703b80141e8e4c500411b200141b8016a1003200141106a4180e59af7002004410020051b220420044180e59af7004922051b20044180e59af70020051b6b2205ad220642002006420010fb0420032002290300370300200120012903b8013703e001200642a8c30180210742ffffffffffffffffff00428080808080808080807f20051b2001290310220620012903182006423f87521b42808090bbbad6adf00d7f2108200141206a200141e0016a1086012001290328420020012802201b210602400240200441ffe49af7004b0d0042ffffffffffffffffff00428080808080808080807f2006200720087d22087d22074200531b20072006427f5522022008427f554720022007427f5547711b22064280ec94a37c20064280ec94a37c551b21060c010b42ffffffffffffffffff00428080808080808080807f2006200720087c22087c22074200531b20072006427f5522022008427f554620022007427f5547711b21060b200141b8016a41086a22024200370300200142003703b80141e8e4c500411b200141b8016a1003200141e0016a41086a22042002290300370300200120012903b8013703e001200120063703b801200141e0016a4110200141b8016a4108100420024200370300200142003703b80141b7e4c500411a200141b8016a100320042002290300370300200120012903b8013703e001200141e0016a4110100620024200370300200142003703b80141d1e4c5004117200141b8016a100320042002290300370300200120012903b8013703e001200141e0016a4110100620024200370300200142003703b80141b0f3c200410d200141b8016a100320042002290300370300200120012903b8013703e001200141086a200141e0016a4110109a01200128020c21032001280208210520024200370300200142003703b801418cf5c2004111200141b8016a100320042002290300370300200120012903b8013703e001200141b8016a200141e0016a411010dc010240024020012d00b8014101470d00200141e0016a4110100620014180026a41186a200141d1016a290000220637030020014180026a41106a200141b8016a41116a290000220737030020014180026a41086a200141c1016a2900002208370300200141386a41086a2008370300200141386a41106a2007370300200141386a41186a2006370300200120012900b901220637038002200120063703380c010b20014180026a41186a200141d1016a29000037030020014180026a41106a200141b8016a41116a29000037030020014180026a41086a200141c1016a290000370300200141386a41086a4200370300200141386a41106a4200370300200141386a41186a4200370300200120012900b90137038002200142003703380b200141b8016a41086a22024200370300200142003703b80141d2f3c200410d200141b8016a1003200141e0016a41086a2002290300370300200120012903b8013703e001200141003602b801200141e0016a4110200141b8016a10082102024002400240024002400240024020012802b8012204417f460d002002450d0020012004360284022001200236028002200141b8016a20014180026a103f20012802b8012209450d0220012902bc01210602402004450d002002102e0b200141e0016a411010062006422088a721022006a7210a0c010b41042109410021024100210a0b2003410020051b210b200141b8016a41086a22044200370300200142003703b80141bdf3c2004115200141b8016a1003200141e0016a41086a2004290300370300200120012903b8013703e001200141b8016a200141e0016a411010dc010240024020012d00b8014101470d00200141e0016a4110100620014180026a41186a200141d1016a290000220637030020014180026a41106a200141c9016a290000220737030020014180026a41086a200141c1016a2900002208370300200141d8006a41086a2008370300200141d8006a41106a2007370300200141d8006a41186a2006370300200120012900b901220637038002200120063703580c010b20014180026a41186a200141d1016a29000037030020014180026a41106a200141c9016a29000037030020014180026a41086a200141c1016a290000370300200141d8006a41086a4200370300200141d8006a41106a4200370300200141d8006a41186a4200370300200120012900b90137038002200142003703580b0240200b41fb01490d00200b41857e6a2203450d00411010292204450d02200441086a41002900e7f342370000200441002900dff342370000200441104120102a2204450d0320042003360010200141e0016a41186a22034200370300200141e0016a41106a22054200370300200141e0016a41086a220c4200370300200142003703e00120044114200141e0016a1000200141b8016a41186a2003290300370300200141b8016a41106a2005290300370300200141b8016a41086a200c290300370300200120012903e0013703b801200141b8016a412010062004102e0b200141e0016a41186a22044200370300200141e0016a41106a22034200370300200141e0016a41086a22054200370300200142003703e001200141e0016a101f200141f8006a41186a2004290300370300200141f8006a41106a2003290300370300200141f8006a41086a2005290300370300200120012903e001370378200141b8016a41186a220c200141386a41186a290300370300200141b8016a41106a220d200141386a41106a290300370300200141b8016a41086a220e200141386a41086a290300370300200120012903383703b801200442003703002003420037030020054200370300200142003703e0010240200141b8016a4120200141e0016a1020450d0020014198016a41086a2005290300220637030020014198016a41106a2003290300220737030020014198016a41186a20042903002208370300200120012903e001220f37039801200e2006370300200d2007370300200c20083703002001200f3703b80102402002200a470d00200241016a22042002490d0620024101742203200420042003491b220aad42247e2206422088a70d062006a722044100480d060240024020020d002004102921090c010b2009200241246c2004102a21090b2009450d050b2009200241246c6a220441003a0000200420012903b801370001200441096a200141c0016a290300370000200441116a200141c8016a290300370000200441196a200141d0016a290300370000200420012f0080023b0021200441236a20014182026a2d00003a0000200241016a21020b200020012903383700102000200b36020020002001290378370030200041286a200141386a41186a290300370000200041206a200141386a41106a290300370000200041186a200141386a41086a290300370000200041386a200141f8006a41086a290300370000200041c0006a200141f8006a41106a290300370000200041c8006a200141f8006a41186a2903003700002000410c6a2002360200200041086a200a36020020002009360204200041e8006a200141d8006a41186a290300370000200041e0006a200141d8006a41106a290300370000200041d8006a200141d8006a41086a29030037000020002001290358370050200141a0026a24000f0b41eff0c2004133200141b8016a4184f4c2001053000b41104101102c000b41204101102c000b20044104102c000b102d000ba40301027f23004180026b22022400024002402001450d00200220003602000c010b200241c8ecc5003602000b20022001360204200241f8006a2002103c0240200228027c450d00200241086a200241f8006a41f00010f6041a200241086a10ab020240200241086a410c6a2802002200450d00200228020c2101200041246c210003400240024020012d0000220341034b0d0002400240024020030e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b0240200241106a280200450d00200228020c102e0b20024180026a240042010f0b200241f4016a411c3602002002411c6a41023602002002420237020c200241d4f1c1003602082002411c3602ec01200241e0f2c1003602e801200241003602fc01200241c8ecc5003602f8012002200241e8016a3602182002200241f8016a3602f001200241086a41e4f1c100106a000bcc28010b7f230041d0006b220224002002410036022820024201370320024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240410410292203450d0020024284808080c00037022420022003360220200341edcad18b0636000002400240200228022420022802282203460d00200228022021040c010b200341016a22042003490d1b20034101742205200420042005491b22054100480d1b0240024020030d002005102921040c010b200228022020032005102a21040b2004450d0220022005360224200220043602200b2002200341016a360228200420036a41073a00004113200241206a10474180dcc100210603402006280204210720062802082203200241206a10470240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1c20054101742204200820082004491b22044100480d1c0240024020050d002004102921050c010b200228022020052004102a21050b2005450d042002200436022420022005360220200228022821040b2002200420036a360228200520046a2007200310f6041a200228022421042002280228210302400240200628020c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e20034101742205200420042005491b22054100480d1e0240024020030d002005102921040c010b200228022020032005102a21040b2004450d072002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d20034101742205200420042005491b22054100480d1d0240024020030d002005102921040c010b200228022020032005102a21040b2004450d072002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628020c4101460d00200241306a20062802101101002002280234210720022802382203200241206a10470240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1e20054101742204200820082004491b22044100480d1e0240024020050d002004102921050c010b200228022020052004102a21050b2005450d092002200436022420022005360220200228022821040b2002200420036a360228200520046a2007200310f6041a200228024021050240200228023c4101460d0020052002280244200241206a10b3020c020b200520022802482203200241206a10b30202402003450d00200341d8006c21074100210403400240200520046a220341346a280200450d002003413c6a280200450d00200341386a280200102e0b0240200341c4006a280200450d00200341cc006a280200450d00200341c8006a280200102e0b2007200441d8006a2204470d000b0b2002280244450d012005102e0c010b2006280214210720062802182203200241206a10470240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1d20054101742204200820082004491b22044100480d1d0240024020050d002004102921050c010b200228022020052004102a21050b2005450d092002200436022420022005360220200228022821040b2002200420036a360228200520046a2007200310f6041a200628022021030240200628021c4101460d002003200641246a280200200241206a10b3020c010b20032006280228200241206a10b3020b200228022421042002280228210302400240200628022c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e20034101742205200420042005491b22054100480d1e0240024020030d002005102921040c010b200228022020032005102a21040b2004450d0b2002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d20034101742205200420042005491b22054100480d1d0240024020030d002005102921040c010b200228022020032005102a21040b2004450d0b2002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628022c4101460d00200241186a200628023011010020022802182104200228021c2203200241206a10472003450d012003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10470240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1f20074101742205200a200a2005491b22054100480d1f0240024020070d002005102921070c010b200228022020072005102a21070b2007450d0e2002200536022420022007360220200228022821050b2002200520046a360228200720056a2009200410f6041a200341706a200241206a10b4022003200241206a10b5022003412c6a2103200841546a22080d000c020b0b2006280230210420062802382203200241206a10472003450d002003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10470240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1e20074101742205200a200a2005491b22054100480d1e0240024020070d002005102921070c010b200228022020072005102a21070b2007450d0e2002200536022420022007360220200228022821050b2002200520046a360228200720056a2009200410f6041a200341706a200241206a10b4022003200241206a10b5022003412c6a2103200841546a22080d000b0b200228022421042002280228210302400240200628023c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e20034101742205200420042005491b22054100480d1e0240024020030d002005102921040c010b200228022020032005102a21040b2004450d0f2002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d20034101742205200420042005491b22054100480d1d0240024020030d002005102921040c010b200228022020032005102a21040b2004450d0f2002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628023c4101460d00200241106a20062802401101002002280210210420022802142203200241206a10472003450d012003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10470240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1f20074101742205200a200a2005491b22054100480d1f0240024020070d002005102921070c010b200228022020072005102a21070b2007450d122002200536022420022007360220200228022821050b2002200520046a360228200720056a2009200410f6041a200341706a200241206a10b5022003200241206a10b5022003412c6a2103200841546a22080d000c020b0b2006280240210420062802482203200241206a10472003450d002003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10470240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1e20074101742205200a200a2005491b22054100480d1e0240024020070d002005102921070c010b200228022020072005102a21070b2007450d122002200536022420022007360220200228022821050b2002200520046a360228200720056a2009200410f6041a200341706a200241206a10b5022003200241206a10b5022003412c6a2103200841546a22080d000b0b02400240200628024c4101460d00200241086a20062802501101002002280208210b200228020c2203200241206a10472003450d01200341386c210c410021070340200b20076a220341046a2802002109200341086a2802002204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a200a2005491b22054100480d1f0240024020080d002005102921080c010b200228022020082005102a21080b2008450d142002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a200341106a2802002109200341146a2802002204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a200a2005491b22054100480d1f0240024020080d002005102921080c010b200228022020082005102a21080b2008450d152002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a02400240200341186a2802004101460d00200241306a2003411c6a280200200341206a28020028020c1100002002280230210920022802382204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2120084101742205200a200a2005491b22054100480d210240024020080d002005102921080c010b200228022020082005102a21080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a2002280234450d012009102e0c010b2003411c6a2802002109200341246a2802002204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2020084101742205200a200a2005491b22054100480d200240024020080d002005102921080c010b200228022020082005102a21080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a0b200341286a200241206a10b502200c200741386a2207470d000c020b0b2006280250210b20062802582203200241206a10472003450d00200341386c210c410021070340200b20076a220341046a2802002109200341086a2802002204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1e20084101742205200a200a2005491b22054100480d1e0240024020080d002005102921080c010b200228022020082005102a21080b2008450d172002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a200341106a2802002109200341146a2802002204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1e20084101742205200a200a2005491b22054100480d1e0240024020080d002005102921080c010b200228022020082005102a21080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a02400240200341186a2802004101460d00200241306a2003411c6a280200200341206a28020028020c1100002002280230210920022802382204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2020084101742205200a200a2005491b22054100480d200240024020080d002005102921080c010b200228022020082005102a21080b2008450d1b2002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a2002280234450d012009102e0c010b2003411c6a2802002109200341246a2802002204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a200a2005491b22054100480d1f0240024020080d002005102921080c010b200228022020082005102a21080b2008450d1b2002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a0b200341286a200241206a10b502200c200741386a2207470d000b0b200641dc006a220641d4e9c100470d000b2002280228220341046a2204417f4c0d1720022802242108200228022021070240024020040d00410121050c010b200410292205450d190b2002410036023820022004360234200220053602302003200241306a10470240024020022802342205200228023822046b2003490d00200228023021050c010b200420036a22092004490d1b2005410174220a20092009200a491b22094100480d1b0240024020050d002009102921050c010b200228023020052009102a21050b2005450d1a20022009360234200220053602300b200520046a2007200310f6041a200420036a210302402008450d002007102e0b200241d0006a24002003ad4220862005ad840f0b41044101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20044101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b1032000b20044101102c000b20094101102c000b102d000b921d010a7f230041106b22032400200120021047024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001450d00200141d8006c2104410021050340200020056a220641046a2802002107200641086a28020022082002104702400240200241046a2209280200220a200241086a2201280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d18200a410174220b200c200c200b491b220b4100480d1802400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d032002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a200641d4006a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1820084101742207200b200b2007491b22074100480d180240024020080d0020071029210b0c010b200228020020082007102a210b0b200b450d042002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a000002402006410c6a2d0000220841024b0d0002400240024020080e03000102000b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1b2008410174220a200b200b200a491b220a4100480d1b0240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d082002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41003a0000200641146a2802002107200641186a280200220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1b200a410174220b200c200c200b491b220b4100480d1b02400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d092002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a0c020b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200b200a491b220a4100480d1a0240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d092002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41013a00002006410d6a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a20084101742207200b200b2007491b22074100480d1a0240024020080d0020071029210b0c010b200228020020082007102a210b0b200b450d0a2002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a0000200641146a2802002107200641186a280200220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200c200b491b220b4100480d1a02400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d0b2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a200641206a2802002107200641246a280200220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200c200b491b220b4100480d1a02400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d0c2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200b200a491b220a4100480d1a0240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d0d2002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a2006410e6a2d00003a00000c010b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d192008410174220a200b200b200a491b220a4100480d190240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d0d2002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41023a00002006410d6a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1920084101742207200b200b2007491b22074100480d190240024020080d0020071029210b0c010b200228020020082007102a210b0b200b450d0e2002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a0000200641146a2802002107200641186a280200220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200c200b491b220b4100480d1902400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d0f2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a200641206a2802002107200641246a280200220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200c200b491b220b4100480d1902400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d102002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a2006412c6a2802002107200641306a280200220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200c200b491b220b4100480d1902400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d112002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a2006410e6a2d0000220841044b0d000240024002400240024020080e050001020304000b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1d2008410174220a200b200b200a491b220a4100480d1d0240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41003a00000c040b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1c2008410174220a200b200b200a491b220a4100480d1c0240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41013a00000c030b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1b2008410174220a200b200b200a491b220a4100480d1b0240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41023a00000c020b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200b200a491b220a4100480d1a0240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41033a00000c010b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d192008410174220a200b200b200a491b220a4100480d190240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41043a00000b02400240200641346a2802004101460d002003200641386a2802002006413c6a28020028020c110000200328020021072003280208220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200c200b491b220b4100480d1a02400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d182002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a2003280204450d012007102e0c010b200641386a2802002107200641c0006a280200220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200c200b491b220b4100480d1902400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d182002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a0b200641c4006a200210b5022004200541d8006a2205470d000b0b200341106a24000f0b200b4101102c000b20074101102c000b200a4101102c000b200b4101102c000b200a4101102c000b20074101102c000b200b4101102c000b200b4101102c000b200a4101102c000b200a4101102c000b20074101102c000b200b4101102c000b200b4101102c000b200b4101102c000b200a4101102c000b200a4101102c000b200a4101102c000b200a4101102c000b200a4101102c000b200b4101102c000b200b4101102c000b102d000bfe0601087f20002802042102024002400240024002400240024020002802004101460d00200041086a2802002200200110472000450d01200041186c2103200241146a2100200141086a2102200141046a21040340200041706a2802002105200041746a2802002206200110470240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d0820074101742208200920092008491b22084100480d080240024020070d002008102921070c010b200128020020072008102a21070b2007450d042001200736020020042008360200200228020021080b2002200820066a360200200720086a2005200610f6041a2000417c6a280200210520002802002206200110470240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d0820074101742208200920092008491b22084100480d080240024020070d002008102921070c010b200128020020072008102a21070b2007450d052001200736020020042008360200200228020021080b2002200820066a360200200720086a2005200610f6041a200041186a2100200341686a22030d000c020b0b2000410c6a2802002200200110472000450d00200041186c2103200241146a2100200141086a2102200141046a21040340200041706a2802002105200041746a2802002206200110470240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d0720074101742208200920092008491b22084100480d070240024020070d002008102921070c010b200128020020072008102a21070b2007450d052001200736020020042008360200200228020021080b2002200820066a360200200720086a2005200610f6041a2000417c6a280200210520002802002206200110470240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d0720074101742208200920092008491b22084100480d070240024020070d002008102921070c010b200128020020072008102a21070b2007450d062001200736020020042008360200200228020021080b2002200820066a360200200720086a2005200610f6041a200041186a2100200341686a22030d000b0b0f0b20084101102c000b20084101102c000b20084101102c000b20084101102c000b102d000b800401087f200028020421020240024002400240024020002802004101460d00200041086a28020022002001104720004103742200450d01200220006a2103200141086a2104034020022802002105200241046a28020022002001104702400240200141046a22062802002207200428020022086b2000490d00200128020021070c010b200820006a22092008490d0620074101742208200920092008491b22084100480d060240024020070d002008102921070c010b200128020020072008102a21070b2007450d042001200736020020062008360200200428020021080b2004200820006a360200200720086a2005200010f6041a200241086a22022003470d000c020b0b2000410c6a28020022002001104720004103742200450d00200220006a2103200141086a2104034020022802002105200241046a28020022002001104702400240200141046a22062802002207200428020022086b2000490d00200128020021070c010b200820006a22092008490d0520074101742208200920092008491b22084100480d050240024020070d002008102921070c010b200128020020072008102a21070b2007450d042001200736020020062008360200200428020021080b2004200820006a360200200720086a2005200010f6041a200241086a22022003470d000b0b0f0b20084101102c000b20084101102c000b102d000bd10301027f230041a0076b22022400024002402001450d00200220003602080c010b200241c8ecc5003602080b2002200136020c200241f0046a200241086a10b70102400240024020022903d8054203510d00200241106a200241f0046a41a00210f6041a200241b0026a200241106a41a00210f6041a2002200241b0026a3602f004200241d0046a200241f0046a10ac0220022802d8042101200241f0046a200241b0026a41a00210f6041a20024198076a20022802d804360200200220022903d00437039007200241e0046a200241f0046a200120024190076a10ae02410121000240024020022802e0044101460d004100210020022802e40441004721030c010b4280828898f01f20022802e404410374ad88a721030b410110292201450d01200120003a0000200141014102102a2201450d02200120033a0001200241a0076a24002001ad428080808020840f0b2002411c6a411c360200200241c4026a4102360200200242023702b402200241d4f1c1003602b0022002411c360214200241f8f2c100360210200241003602e404200241c8ecc5003602e0042002200241106a3602c0022002200241e0046a360218200241b0026a41e4f1c100106a000b41014101102c000b41024101102c000ba70d04067f017e087f017e230041d0016b2202240010af02200241186a41b0f3c200410d107d41002103200228021c410020022802181b109501200241106a41a2e4c5004115107d410421040240024002400240024002400240024002402002280214410020022802101b22050d004104210641042107410021050c010b2005ad420c7e2208422088a70d062008a722094100480d06200910292206450d072006210a4100210b0340411410292209450d02200941106a4100280093e545360000200941086a410029008be54537000020094100290083e545370000200941144128102a2209450d032009200b360014200241206a41186a220c4200370300200241206a41106a220d4200370300200241206a41086a220742003703002002420037032020094118200241206a1000200241a0016a41186a200c290300370300200241a0016a41106a200d290300370300200241a0016a41086a2007290300370300200220022903203703a00120024100360220200241a0016a4120200241206a10082107024002402002280220220e417f460d002007450d002002200e36022420022007360220200241086a200241206a103102400240024020022802080d002002280224220f200228020c220d490d00200d417f4c0d0902400240200d0d004101210c0c010b200d1034220c450d02200c20022802202210200d10f6041a2002200f200d6b36022420022010200d6a3602200b200c0d020b41eff0c2004133200241c0016a4184f4c2001053000b200d4101102c000b200dad220842208621110240200e450d002007102e0b20112008842108200241a0016a412010060c010b4101210c420021080b2009102e200a41046a2008370200200a200c360200200a410c6a210a2005200b41016a220b470d000b200621070b02402005410c6c2209450d002009410c6e2203410374220a4100480d06200a10292204450d040b4100210b02402006200620096a220d460d00200421092006210a0340200a280200210c200941046a200a41086a2802003602002009200c360200200941086a2109200b41016a210b200a410c6a220a200d470d000b0b2002200b3602282002200336022420022004360220200241a0016a200241206a10ad0202402003450d002004102e0b02402005450d002005410c6c210903400240200641046a280200450d002006280200102e0b2006410c6a2106200941746a22090d000b2005450d002007102e0b200241206a41186a200241a0016a41186a290300370300200241206a41106a2209200241a0016a41106a290300370300200241206a41086a200241a0016a41086a290300370300200220022903a001370320200241c0016a41086a220a4200370300200242003703c00141bdf3c2004115200241c0016a100320024190016a41086a200a290300370300200220022903c00137039001200241103602c401200220024190016a3602c001200241206a200241c0016a10b802200241206a10b002200241003602c801200242013703c0012009200241c0016a1046200241206a200241c0016a1066200241d0006a200241c0016a1046200241f0006a200241c0016a10462002280224210b2002412c6a2802002209200241c0016a10470240024020090d0020022802c801210a20022802c00121060c010b200941246c210e20022802c401210d20022802c80121090340200241a0016a200b104520022802a001210702400240200d20096b20022802a801220c490d002009200c6a210a20022802c00121060c010b2009200c6a220a2009490d08200d4101742206200a200a2006491b22054100480d0802400240200d0d002005102921060c010b20022802c001200d2005102a21060b2006450d07200220053602c401200220063602c0012005210d0b2002200a3602c801200620096a2007200c10f6041a024020022802a401450d002007102e0b200b41246a210b200a2109200e415c6a220e0d000b0b0240200228022c220b450d0020022802242109200b41246c210b03400240024020092d0000220c41034b0d00024002400240200c0e0404000102040b2009410c6a280200450d03200941086a280200102e0c030b2009410c6a280200450d02200941086a280200102e0c020b2009410c6a280200450d01200941086a280200102e0c010b200941086a280200450d00200941046a280200102e0b200941246a2109200b415c6a220b0d000b0b0240200241286a280200450d002002280224102e0b200241d0016a2400200aad4220862006ad840f0b41144101102c000b41284101102c000b1032000b200a4104102c000b20054101102c000b102d000b20094104102c000bdf0301017f024002400240024002400240410110292202450d00200220002d00003a0000200241014102102a2202450d01200220002d00013a0001200241024104102a2202450d02200220002d00023a0002200220002d00033a0003200241044108102a2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102a2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102a2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f200128020020012802042002412010042002102e0f0b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000bc12605017f027e107f027e047f230041d0036b22022400024002402001450d00200220003602200c010b200241c8ecc5003602200b20022001360224200241386a200241206a10e4010240024020022802382201450d002002200229023c37022c20022001360228200241386a200241286a10ba02024020022802384101470d002002200229023c3703a0024186c5c2004128200241a0026a4198c2c2001053000b200241386a41086a2903002103200241106a41c5c1c200410d108101200229031821042002280210210141a002102922050d0141a0024108102c000b200241cc006a4102360200200241ac026a411c3602002002420237023c200241d4f1c1003602382002411c3602a40220024190f3c1003602a002200241003602bc01200241c8ecc5003602b8012002200241a0026a3602482002200241b8016a3602a802200241386a41e4f1c100106a000b2005200241a0026a41e80010f60422064202370368200641023a009801200620022903b801370370200641f8006a200241b8016a41086a29030037030020064180016a200241c8016a29030037030020064188016a200241d0016a29030037030020064190016a200241d8016a290300370300200620022800b003360099012006419c016a200241b0036a41036a28000036000020062003200442b8177c42b81720011b220420042003541b3703a001200641a8016a200241386a41f80010f6041a200241286a2101200228022c2107024002400240024003402001280200220841086a210020082f0106220941037421014100210a0240024003402001450d0141fb9bc2002000410810f804220b450d02200141786a2101200a41016a210a200041086a2100200b417f4a0d000b200a417f6a21090b2007450d022007417f6a2107200820094102746a41e4016a21010c010b0b20022008200a410c6c6a220141e8006a2802003602a4022002200141e0006a2802003602a002200241386a200241a0026a103b2002280238220c450d00200228023c210d02400240200241386a41086a22012802002209450d00200241a0026a41086a22004200370300200242003703a002419893c2004111200241a0026a100320012000290300370300200220022903a002370338200241003602a002200241386a4110200241a0026a1008210102400240024020022802a0022200417f460d002001450d00200220003602bc01200220013602b801200241a0026a200241b8016a103d20022802a0022207450d02200241a8026a280200210e20022802a402210f2000450d012001102e0c010b4100210f410421074100210e0b2007200e41c4006c22016a210002400240024002400240024020010d00200721010c010b4100210102400340200720016a220a2d0000210b200241386a200a41016a41c30010f6041a200b4102460d01200241b8016a41186a200241386a41186a290000370300200241b8016a41106a200241386a41106a290000370300200241b8016a41086a200241386a41086a290000370300200220022900383703b801200b4101460d03200141c4006a2101200a41c4006a2000470d000b200021010c010b200a41c4006a21010b0240034020002001460d0120012d0000210a200141c4006a2101200a4102470d000b0b41012108410021100240200f0d00410021110c020b2007102e410021110c010b200241a0026a41086a220b200241b8016a41086a290300370300200241a0026a41106a2212200241b8016a41106a290300370300200241a0026a41186a2210200241b8016a41186a290300370300200220022903b801220337039003200220033703a002412010292208450d02200820022903a002370000200841186a2010290300370000200841106a2012290300370000200841086a200b29030037000002400240200e41c4006c41bc7f6a2001470d0041012110410121110c010b200a41c4006a210a200e41c4006c20076a41bc7f6a211341012110410121110340200a21010240034020012d0000210a200241386a200141016a41c30010f6041a200a4102460d01200241b8016a41186a220b200241386a41186a290000370300200241b8016a41106a2212200241386a41106a290000370300200241b8016a41086a2214200241386a41086a290000370300200220022900383703b8010240200a4101460d00200141c4006a22012000470d010c040b0b200241a0026a41086a20142903002203370300200241a0026a41106a20122903002204370300200241a0026a41186a200b2903002215370300200220022903b80122163703a00220024190036a41186a2212201537030020024190036a41106a2214200437030020024190036a41086a221720033703002002201637039003024020112010470d00201041016a220a2010490d0d2010410174220b200a200a200b491b221141ffffff3f712011470d0d2011410574220a4100480d0d0240024020100d00200a102921080c010b20082010410574200a102a21080b2008450d050b200141c4006a210a200820104105746a220b200229039003370000200b41186a2012290300370000200b41106a2014290300370000200b41086a2017290300370000201041016a211020132001470d010c020b0b200141c4006a21000b2007200e41c4006c6a210a02400340200a2000460d0120002d00002101200041c4006a210020014102470d000b0b200f450d002007102e0b200c200941f0006c6a2109200241a0026a41106a2118200241a0026a41086a210f4200210341042119200c210b02400340200b2802042101200b2802002100200241386a200b41086a41e80010f6041a200b41f0006a210b024020010d00200b2009460d070340200b2802042207450d08200b41086a280200210e0240200b410c6a2802002201450d00200141246c21002007210103400240024020012d0000220a41034b0d00024002400240200a0e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b200b41f0006a210b0240200e450d002007102e0b200b2009470d000c080b0b200241b8016a200241386a41e80010f6041a200220013602a402200220003602a002200f200241b8016a41e80010f6041a200241086a41b0f3c200410d107d20022802082101200228020c2100200241b0036a200241a0026a109602024002400240024020022802a002417f6a220a2000410020011b22014f0d00200241386a200a10ba01200241386a2018412010f8040d0020022802a002221a41002001417b6a2200200020014b1b490d00200241b0036a20086b220741606a2112200741406a2114200741a07f6a211320082010410574220a6a210e410021010240024002400340024002400240200e200820016a22006b41e0004b0d0020104105742001470d01410021000c060b024020072001470d00200241b0036a21000c060b2000200241b0036a412010f804450d0520122001470d01200241b0036a21000c050b03400240200241b0036a2000470d00200241b0036a21000c060b2000200241b0036a412010f804450d05200041206a2100200a41606a220a0d000b410021000c040b200041206a2217200241b0036a412010f804450d02024020142001470d00200241b0036a21000c040b200041c0006a2217200241b0036a412010f804450d01024020132001470d00200241b0036a21000c040b200a41807f6a210a20014180016a2101200041e0006a200241b0036a412010f8040d000b200820016a41606a21000c020b201721000c010b201721000b200241386a201a10ba01200241386a200241b0036a412010f804210120000d0020010d010b024020022802ac022200450d0020022802a4022101200041246c210003400240024020012d0000220a41034b0d00024002400240200a0e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b20022802a802450d0120022802a402102e0c010b200241b0036a200241a0026a109602200241386a200241a0026a41f00010f6041a02402003a72003422088a72201470d00200141016a22002001490d0d2001410174220a20002000200a491bad220442f0007e2215422088a70d0d2015a722004100480d0d0240024020010d002000102921190c010b2019200141f0006c2000102a21190b2019450d0220034280808080708320048421030b2019200141f0006c6a200241386a41f00010f6041a200241386a41186a2200200241b0036a41186a290300370300200241386a41106a220a200241b0036a41106a290300370300200241386a41086a2207200241b0036a41086a290300370300200220022903b003370338024020112010470d00201041016a22012010490d0d2010410174220e20012001200e491b221141ffffff3f712011470d0d201141057422014100480d0d0240024020100d002001102921080c010b200820104105742001102a21080b2008450d040b20034280808080107c2103200820104105746a22012002290338370000200141186a2000290300370000200141106a200a290300370000200141086a2007290300370000201041016a21100b200b2009470d010c070b0b20004104102c000b20014101102c000b200a4101102c000b41204101102c000b41eff0c2004133200241b0036a4184f4c2001053000b41012109200d450d03200c102e0c030b0240200d450d00200c102e0b02402011450d002008102e0b0240200342ffffffff0f560d00410121092003a7450d032019102e0c030b20190d010b410121090c010b0240200641a00241c004102a22050d0041c0044108102c000b200541a0026a200241a0026a41e80010f6041a2005420237038803200541033a00b803200520033703c003200520193602bc03200520022903b8013703900320054198036a200241c0016a290300370300200541a0036a200241c8016a290300370300200541a8036a200241d0016a290300370300200541b0036a200241d8016a290300370300200520022f00b0033b00b90341022109200541bb036a200241b0036a41026a2d00003a0000200541c8036a200241386a41f80010f6041a0b200241286a2101200228022c21060240024002400240024003402001280200220841086a210020082f0106220741037421014100210a0240024003402001450d0141d5f4c1002000410810f804220b450d02200141786a2101200a41016a210a200041086a2100200b417f4a0d000b200a417f6a21070b2006450d022006417f6a2106200820074102746a41e4016a21010c010b0b200841e0006a200a410c6c6a22012802084104490d0020012802002800002106200241a0026a41086a22014200370300200242003703a002418bd9c0004115200241a0026a1003200241386a41086a2001290300370300200220022903a00237033841002101200241003602a002200241386a4110200241a0026a1008210a0240024020022802a0022200417f460d00200220003602bc012002200a3602b801200241a0026a200241b8016a1041024020022802a002220b450d00200241a8026a280200210120022802a40221082000450d02200a102e0c020b41eff0c2004133200241b0036a4184f4c2001053000b4104210b410021080b4100210002402001417f6a220a20014b0d00200a20014f0d00200b200a4102746a2201450d00200128020020064721000b02402008450d00200b102e0b20000d010b200921120c010b2005200941a0026c220120094101742200200941016a221220122000491b41a0026c2200102a2205450d01200520016a200241a0026a41e80010f604220142023703682001410d3a0098012001419c016a2006360200200120022903b801370370200141f8006a200241c0016a29030037030020014180016a200241c8016a29030037030020014188016a200241d0016a29030037030020014190016a200241d8016a29030037030020014199016a20022f00b0033b00002001419b016a200241b2036a2d00003a0000200141a0016a200241386a41800110f6041a0b2002280228200228022c200228023010e501200241003602a802200242013703a0022012200241a0026a1047201241a0026c210920022802a402210620022802a80221012005210a03402002200a3602b801200241386a200241b8016a10ac022002280238210702400240200620016b20022802402208490d00200120086a210020022802a002210b0c010b200120086a22002001490d042006410174220b20002000200b491b220e4100480d040240024020060d00200e1029210b0c010b20022802a0022006200e102a210b0b200b450d032002200e3602a4022002200b3602a002200e21060b200220003602a802200b20016a2007200810f6041a0240200228023c450d002007102e0b200a41a0026a210a20002101200941e07d6a22090d000b201241a0026c210a20054198016a210103402001102f200141a0026a2101200a41e07d6a220a0d000b2005102e200241d0036a24002000ad422086200bad840f0b20004108102c000b200e4101102c000b102d000bf00101067f2001280204210202400240024003402001280200220341086a210420032f01062205410374210141002106024003402001450d0141f4e1c5002004410810f8042207450d03200141786a2101200641016a2106200441086a21042007417f4a0d000b2006417f6a21050b02402002450d002002417f6a2102200320054102746a41e4016a21010c010b0b200041fce1c500360204200041086a41283602000c010b200341e0006a2006410c6c6a220128020841074b0d01200041a4e2c500360204200041086a41293602000b200041013602000f0b200041086a2001280200290000370300200041003602000bde29060c7f017e057f027e017f017e230041c0026b22022400024002402001450d00200220003602180c010b200241c8ecc5003602180b2002200136021c200241d0006a200241186a10aa020240024002400240024002400240024002400240024002400240024020022802542203450d00200241c8016a2802002104200241c4016a2802002105200241c0016a2802002106200241d0006a410c6a280200210720022802582108200241d0006a200241186a10e40120022802502201450d012002200229025437022420022001360220200241013b013c20024200370234200241e08dc000360230200241306a41086a21092004450d0b2006200441a0026c6a210a200241d8016a410272210b2006210c0340200c41e8006a2903004202520d0c0240200c2d009801410247220d0d00200c2903a001210e200241206a21012002280224210f0240024002400240024002400240024002400240024002400240024002400240024003402001280200221041086a210020102f010622114103742101410021120240024003402001450d0141d8dec5002000410810f8042213450d02200141786a2101201241016a2112200041086a21002013417f4a0d000b2012417f6a21110b200f450d02200f417f6a210f201020114102746a41e4016a21010c010b0b0240201041e0006a2012410c6c6a220128020841074b0d00201442808080807083422984210e41e0dec50021110c020b200e42f02e8020012802002900002214510d0341928dc00021114131210f0c020b201442808080807083421c84210e4189dfc50021110b200ea7210f0b024002400240024020022d003d450d004131210141b09cc20021000c010b20022802302002280234200228023810e50120024200370234200241e08dc000360230200242e2c289abb68edbb7f400370340200241d8016a410272410041da0010f5041a200241d0006a410041840110f5041a41e40110292213450d0420134100360200201341046a200241d8016a41dc0010f6041a201341e0006a200241d0006a41840110f6041a200241003602342002201336023020132f0106220c4103742110417f210041002101024002400340024020102001470d00200c21000c020b200241c0006a201320016a41086a410810f8042212450d02200141086a2101200041016a2100201241004e0d000b0b200242e2c289abb68edbb7f400370264200220093602602002200036025c20022013360254200241003602502002200241306a360258200f41046a2200417f4c0d062000450d02200010292201450d07200220003602bc02200220013602d801200241003602b802200f413f4b0d032001200f4102743a0000410121120c1c0b412d210141839cc20021000b200220013602542002200036025041e19cc2004122200241d0006a41849dc2001053000b200241003602bc02200241003602b80241012100200241013602d801410110292201450d05200141033a0000200241013602bc02200220013602d801200241013602b802410521120c140b200f41808001490d17200f418080808004490d160c120b200d0d0d200c2903a0012115200241d0006a200241206a10ba020240024020022802504101470d002002350258210e200228025421164101210d0c010b2002290358210e200241086a41c5c1c200410d10810102402015200e423c7c560d004100210d2015200229031042b8177c42b81720022802081b220e540d010c0f0b201742808080807083422584210e4101210d41e1c4c20021160b024020022d003d450d004131210141b09cc20021000c070b0240200d450d0020022802302002280234200228023810e50120024200370234200241e08dc000360230200242f4d2b59bc7ae98b8303703400c050b20022802302110200242f4d2b59bc7ae98b830370340201041e08dc000460d042002280234210f0c050b41e4014104102c000b1032000b20004101102c000b41014101102c000b200b410041da0010f5041a200241d0006a410041840110f5041a41e40110292210450d024100210f20104100360200201041046a200241d8016a41dc0010f6041a201041e0006a200241d0006a41840110f6041a20024100360234200220103602300b02400340201041086a210020102f01062211410374210141002112024003402001450d01200241c0006a2000410810f8042213450d03200141786a2101201241016a2112200041086a21002013417f4a0d000b2012417f6a21110b0240200f450d00200f417f6a210f201020114102746a41e4016a28020021100c010b0b200242f4d2b59bc7ae98b830370264200220093602602002201136025c20022010360254200241003602502002200241306a360258200241003602e001200242013703d8014101102921010240200d0d002001450d04200141003a000020024281808080103702dc01200220013602d801200141014109102a2201450d052001200e3700012002428980808090013702dc01200220013602d8010c080b2001450d05200141013a000020024281808080103702dc01200220013602d801200ea72201200241d8016a10470240024020022802dc01221220022802e00122006b2001490d0020022802d80121120c010b200020016a22132000490d1820124101742210201320132010491b22134100480d180240024020120d002013102921120c010b20022802d80120122013102a21120b2012450d07200220133602dc01200220123602d8010b2002200020016a3602e001201220006a2016200110f6041a0c070b412d210141839cc20021000b200220013602542002200036025041e19cc2004122200241d0006a41849dc2001053000b41e4014104102c000b41014101102c000b41094101102c000b41014101102c000b20134101102c000b200241c0006a41086a200241d8016a41086a280200360200200220022903d801370340200241d0006a200241c0006a10e6012002200d3a003d200241003a003c200e2117200d450d00200241d8016a41086a200241306a41086a290300370300200220022903303703d8010c0e0b200c41a0026a220c200a470d000c0c0b0b2002413c6a411c360200200241ec016a4102360200200242023702dc01200241d4f1c1003602d8012002411c360234200241acf3c10036023020024100360244200241c8ecc5003602402002200241306a3602e8012002200241c0006a360238200241d8016a41e4f1c100106a000b200241e4006a4102360200200241d8016a410c6a411c36020020024202370254200241d4f1c1003602502002411c3602dc01200241acf3c1003602d80120024100360234200241c8ecc5003602302002200241d8016a3602602002200241306a3602e001200241d0006a41e4f1c100106a000b200141033a0000200241013602b8022000417f6a41034b0d01200041017422124105201241054b1b22124100480d0a0b200120002012102a2201450d01200220123602bc02200220013602d801201221000b2001200f360001410521120c030b20124101102c000b02400240200041034b0d00200041017422124104201241044b1b22124100480d08200120002012102a2201450d01200220123602bc02200220013602d801201221000b2001200f410274410272360000410421120c020b20124101102c000b0240200041014b0d0020012000200041017422124102201241024b1b2212102a2201450d02200220123602bc02200220013602d801201221000b410221122001200f4102744101723b00000b200220123602b8020240200020126b200f4f0d002012200f6a22132012490d0520004101742210201320132010491b22134100480d05200120002013102a2201450d02200220133602bc02200220013602d8010b20022012200f6a3602b802200120126a2011200f10f6041a200220022802d801360240200220022802bc02360244200220022802b802360248200241d0006a200241c0006a10e60120024180023b013c200241d8016a41086a200241306a41086a290300370300200220022903303703d8010c030b20124101102c000b20134101102c000b200241d8016a41086a2009290300370300200220022903303703d8010b20022802202002280224200228022810e50102402007450d00200741246c21002003210103400240024020012d0000221241034b0d0002400240024020120e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402008450d002003102e0b02402004450d00200441a0026c210020064198016a210103402001102f200141a0026a2101200041e07d6a22000d000b0b02402005450d002006102e0b20024100360258200242013703500240410110292201450d002002410136025420022002280258220041016a36025820022001360250200120006a20022d00e4013a0000024002400240200228025420022802582201460d00200228025021000c010b200141016a22002001490d0320014101742212200020002012491b22124100480d030240024020010d002012102921000c010b200228025020012012102a21000b2000450d012002201236025420022000360250200228025821010b2002200141016a360258200020016a20022d00e5013a000020022802e001200241d0006a104720022802d80122122100024020022802dc012213450d002013210120122100034020002802e40121002001417f6a22010d000b0b0240024002400240024002400240024002400240024020022802e00122110d00410021010c010b200241d8016a210d41002113034002400240201320002f01064f0d0020002013410c6c6a41e0006a2110200020134103746a41086a2101201341016a21130c010b02400240200028020022010d00201542808080807083200dad84211541002112410021010c010b2000330104422086200dad842115410121120b201521142015210e02402015422088a7220020012f0106490d000340200e221442ffffffff0f83210e201241016a211220012f01042200200128020022012f01064f0d000b0b20012000410c6c6a2113200120004103746a210f200041027420016a41e8016a28020021002014a7210d02402012417f6a2201450d00034020002802e40121002001417f6a22010d000b0b201341e0006a2110200f41086a2101410021130b02400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d032002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00003a000002400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d042002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00013a000002400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d052002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00023a000002400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d062002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00033a000002400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d072002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00043a000002400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d082002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00053a000002400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d092002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00063a000002400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d0a2002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00073a00002010280200210f20102802082201200241d0006a10470240024020022802542210200228025822126b2001490d00200228025021100c010b201220016a220c2012490d0e20104101742212200c200c2012491b22124100480d0e0240024020100d002012102921100c010b200228025020102012102a21100b2010450d0b2002201236025420022010360250200228025821120b2002201220016a360258201020126a200f200110f6041a2011417f6a22110d000b20022802e001210120022802dc01211320022802d80121120b2002350250210e2002350258211420122013200110e501200241c0026a2400200e2014422086840f0b200c4101102c000b200c4101102c000b200c4101102c000b200c4101102c000b200c4101102c000b200c4101102c000b200c4101102c000b200c4101102c000b20124101102c000b20124101102c000b41014101102c000b102d000b4f02017f027e230041306b22022400200241c8ecc500410010bd0220024100360228200242013703202002200241206a10462002350228210320023502202104200241306a240020042003422086840b9718012d7f230041b00d6b220324002003200236020c20032001360208200341106a41086a2201420037030020034200370310419df5c2004115200341106a1003200341900d6a41086a2001290300370300200320032903103703900d200341f00c6a200341900d6a10fe02024002400240024020032802f40c22040d0041012104410021050c010b20032802f80c2105200341f00c6a410c6a28020022020d010b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20032c00f00c2101200341106a410041e00c10f5041a200441206a2106200420024105746a210741002108410021094100210a4100210b4100210c4100210d4100210e4100210f410021104100211141002112410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f4100212041002121410021224100212341002124410021254100212641002127200421024100212841d1002129024003402028212a02400240024002402001450d0020072004460d01200141016a210103400240024020022007470d002006212b200621022004212c0c010b2002212c200241206a222b21020b2001417f6a22010d000c030b0b024020022007460d00200241206a212b2002212c0c030b2006212b2004212c20072004460d040c010b200141016a2101034020072002460d04200241206a21022001417f6a22010d000b200241606a212c2002212b0b202c450d020b202b2102024002400240024002400240200328020c220141056a222b417f4c0d002003280208212802400240202b450d00202b1029222d450d03200341003602980d2003202b3602940d0c010b200341003602980d2003202b3602940d200341013602900d41011029222d450d03200341013602940d0b2003202d3602900d200341013602980d202d202a3a00002001200341900d6a10470240024020032802940d222d20032802980d222b6b2001490d0020032802900d212d0c010b202b20016a222e202b490d05202d410174222f202e202e202f491b222e4100480d0502400240202d0d00202e1029212d0c010b20032802900d202d202e102a212d0b202d450d042003202e3602940d2003202d3602900d0b2003202b20016a3602980d202d202b6a2028200110f6041a202c200341900d6a104620032802940d212c20032802980d212b20032802900d2101200341900d6a41186a222d4200370300200341900d6a41106a22284200370300200341900d6a41086a222e4200370300200342003703900d2001202b200341900d6a1000200341f00c6a41186a222b202d290300370300200341f00c6a41106a222d2028290300370300200341f00c6a41086a222f202e290300370300200320032903900d3703f00c0240202c450d002001102e0b2029417f6a2129202a41016a2128200341106a202a4103704105746a220120032903f00c370000200141186a202b290300370000200141106a202d290300370000200141086a202f2903003700004100212c0340202a202a41036e222b417d6c6a4102470d06200341106a202c6a220141df006a2d000022082001411f6a2d000022097120082009722001413f6a2d00007172211f200141de006a2d000022082001411e6a2d000022097120082009722001413e6a2d00007172211e200141dd006a2d000022082001411d6a2d000022097120082009722001413d6a2d00007172211d200141dc006a2d000022082001411c6a2d000022097120082009722001413c6a2d00007172211c200141db006a2d000022082001411b6a2d000022097120082009722001413b6a2d00007172211b200141da006a2d000022082001411a6a2d000022097120082009722001413a6a2d00007172211a200141d9006a2d00002208200141196a2d00002209712008200972200141396a2d000071722119200141d8006a2d00002208200141186a2d00002209712008200972200141386a2d000071722118200141d7006a2d00002208200141176a2d00002209712008200972200141376a2d000071722117200141d6006a2d00002208200141166a2d00002209712008200972200141366a2d000071722116200141d5006a2d00002208200141156a2d00002209712008200972200141356a2d000071722115200141d4006a2d00002208200141146a2d00002209712008200972200141346a2d000071722114200141d3006a2d00002208200141136a2d00002209712008200972200141336a2d000071722113200141d2006a2d00002208200141126a2d00002209712008200972200141326a2d000071722112200141d1006a2d00002208200141116a2d00002209712008200972200141316a2d000071722111200141d0006a2d00002208200141106a2d00002209712008200972200141306a2d000071722110200141cf006a2d000022082001410f6a2d000022097120082009722001412f6a2d00007172210f200141ce006a2d000022082001410e6a2d000022097120082009722001412e6a2d00007172210e200141cd006a2d000022082001410d6a2d000022097120082009722001412d6a2d00007172210d200141cc006a2d000022082001410c6a2d000022097120082009722001412c6a2d00007172210c200141cb006a2d000022082001410b6a2d000022097120082009722001412b6a2d00007172210b200141ca006a2d000022082001410a6a2d000022097120082009722001412a6a2d00007172210a200141c9006a2d00002208200141096a2d00002209712008200972200141296a2d000071722109200141c8006a2d00002208200141086a2d00002220712008202072200141286a2d000071722108200141c7006a2d00002220200141076a2d00002221712020202172200141276a2d000071722120200141c6006a2d00002221200141066a2d00002222712021202272200141266a2d000071722121200141c5006a2d00002222200141056a2d00002223712022202372200141256a2d000071722122200141c4006a2d00002223200141046a2d00002224712023202472200141246a2d000071722123200141c3006a2d00002224200141036a2d00002225712024202572200141236a2d000071722124200141c2006a2d00002225200141026a2d00002226712025202672200141226a2d000071722125200141c1006a2d00002226200141016a2d00002227712026202772200141216a2d000071722126200141c0006a2d0000222720012d0000222d712027202d72200141206a2d000071722127202c41800c460d06200341106a202c202b410574202a41096e41e0006c6b6a6a220141ff006a201f3a0000200141fe006a201e3a0000200141fd006a201d3a0000200141fc006a201c3a0000200141fb006a201b3a0000200141fa006a201a3a0000200141f9006a20193a0000200141f8006a20183a0000200141f7006a20173a0000200141f6006a20163a0000200141f5006a20153a0000200141f4006a20143a0000200141f3006a20133a0000200141f2006a20123a0000200141f1006a20113a0000200141f0006a20103a0000200141ef006a200f3a0000200141ee006a200e3a0000200141ed006a200d3a0000200141ec006a200c3a0000200141eb006a200b3a0000200141ea006a200a3a0000200141e9006a20093a0000200141e8006a20083a0000200141e7006a20203a0000200141e6006a20213a0000200141e5006a20223a0000200141e4006a20233a0000200141e3006a20243a0000200141e2006a20253a0000200141e1006a20263a0000200141e0006a20273a0000202b212a202c41e0006a222c41e00c470d000c060b0b1032000b202b4101102c000b41014101102c000b202e4101102c000b102d000b4100210120290d000b0b2000201f3a001f2000201e3a001e2000201d3a001d2000201c3a001c2000201b3a001b2000201a3a001a200020193a0019200020183a0018200020173a0017200020163a0016200020153a0015200020143a0014200020133a0013200020123a0012200020113a0011200020103a00102000200f3a000f2000200e3a000e2000200d3a000d2000200c3a000c2000200b3a000b2000200a3a000a200020093a0009200020083a0008200020203a0007200020213a0006200020223a0005200020233a0004200020243a0003200020253a0002200020263a0001200020273a00000b02402005450d002004102e0b200341b00d6a24000bf756040b7f017e127f027e230041b00a6b22022400024002402001450d00200220003602300c010b200241c8ecc5003602300b20022001360234200241d8066a200241306a10b7010240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022903c0074203510d00200241386a200241d8066a41a00210f6041a200241d8026a200241386a41a00210f6041a2002200241d8026a3602f804200241d8066a200241f8046a10ac0220022802e0062100024020022802dc06450d0020022802d806102e0b200241d8066a200241d8026a41a00210f6041a200241f8046a200241d8066a10b901024020022802f8044101470d00200228028005416b6a220041054b0d1b20022802fc04210102400240024020000e06001e1e1e1e01000b4102210341f6012104200141ccc4c200460d01200141ccc4c200411510f804450d010c1d0b410021040240200141949dc200470d00410021030c1e0b41002103200141949dc200411a10f8040d1c0b0c1c0b200241d8066a20024180056a41d80110f6041a200241286a200241a8076a2205109402024020022903f8064202520d0041f00110292201450d04200141013a00e801200142003703e00120014280808080c0003703d801200142043703d0012001427f3703c801200142003703c001200142013703b801200142003703b00120014280808080c0003703a801200142043703a0012001427f3703980120014200370390012001420137038801200142003703800120014280808080c000370378200142043703702001427f37036820014200370360200142013703582001420037035020014280808080c000370348200142043703402001427f37033820014200370330200142013703282001420037032020014280808080c000370318200142043703102001427f37030820014200370300200141ec016a200241f8046a41036a280000360000200120022800f8043600e9012002200141f0016a3602fc09200220013602f809200241053602f409200220013602f009200241800a6a41206a22044200370300200241800a6a41186a22064280808080c000370300200241013a00a80a200242043703900a2002427f3703880a200242003703800a200241b8096a41086a22072001290308370300200241b8096a41106a22082001290310370300200241b8096a41186a22032001290318370300200241b8096a41206a22092001290320370300200220012903003703b809200220012800293602e80920022001412c6a2800003600eb09200141306a210020012d0028220a4102460d0f200241f8086a41286a220b200241800a6a41286a220c290300370300200241f8086a41206a2004290300370300200241f8086a41186a2006290300370300200241f8086a41106a200241800a6a41106a290300370300200241f8086a41086a200241800a6a41086a290300370300200220022903800a3703f808200241f8046a41206a2009290300370300200241f8046a41186a2003290300370300200241f8046a41106a2008290300370300200241f8046a41086a2007290300370300200220022903b8093703f8042002200a3a00a005200241a1056a220a20022802e809360000200a41036a20022800eb09360000200241800a6a200241f8086a200241f8046a10bf022007200041086a2903003703002008200041106a2903003703002003200041186a2903003703002009200041206a290300370300200220002903003703b809200220012800593602e8092002200141dc006a2800003600eb09200141e0006a210020012d005822074102470d020c0f0b20022d002c210a2002280228210941f00110292204450d042002280290072106411310292201450d05200141002900eff3423700002001410f6a41002800fef342360000200141086a41002900f7f34237000020024293808080b0023702fc04200220013602f804200241d8066a200241f8046a104a20022802fc042107200241206a20022802f804220820022802800510c0022002280224410020022802201b210102402007450d002008102e0b0240024002400240200120064b0d00410c10292207450d0a410410292208450d0b200242043702fc04200220083602f804200241d8066a200241f8046a104a0240024020022802fc04220320022802800522086b4104490d0020022802f804210b0c010b200841046a220b2008490d2120034101742208200b200b2008491b22084100480d210240024020030d0020081029210b0c010b20022802f80420032008102a210b0b200b450d0d200220083602fc042002200b3602f80420022802800521080b410421032002200841046a36028005200b20086a2006360000200241f8086a41086a2002280280052208360200200220022903f804220d3703f808200741086a20083602002007200d370200410021080240200120064f0d00410c10292203450d0e410410292201450d0f200242043702fc04200220013602f804200241d8066a200241f8046a104a0240024020022802fc04220820022802800522016b4104490d0020022802f80421080c010b200141046a220b2001490d2220084101742201200b200b2001491b22014100480d220240024020080d002001102921080c010b20022802f80420082001102a21080b2008450d11200220013602fc04200220083602f80420022802800521010b2002200141046a36028005200820016a2006417f6a360000200241f8086a41086a2002280280052201360200200220022903f804220d3703f808200341086a20013602002003200d370200410121080b200220022800800a3602f0092002200241800a6a41036a2800003600f309200220022802f0093602e809200220022800f3093600eb09200241186a41d1e4c5004117107d417f200228021c410020022802181b220120006a220620062001491b418080c002418080f001200a41017122011b4b0d01200241106a41b7e4c500411a107d417f2002280214410020022802101b220a418094ebdc034180afd0e50220011b2206200920062009491b6a220b200b200a491b20064b0d01200220022800f8043602800a2002200241fb046a2800003600830a200220022802800a3602b809200220022800830a3600bb09200241f8046a200229039807200241a0076a290300200241d8066a20092001200010850120022d00f8044101460d02200441013a0088012004428180808010370380012004200736027c2004200836027820042008360274200420033602702004427f37036820042009ad220d370360200442013703582004420037035020044280808080c000370348200442043703402004427f37033820044200370330200442013703282004420037032020044280808080c000370318200442043703102004427f370308200442003703002004427f200d20011b370390012004427f37039801200442043703a00120044280808080c0003703a801200442003703b001200441013a00b8012004418c016a20022800eb09360000200420022802e80936008901200420022802b8093600b901200441bc016a20022800bb0936000020042002290380053703c001200441c8016a200241f8046a41106a2200290300370300200441d0016a200241f8046a41186a2206290300370300200441d8016a200241f8046a41206a2207290300370300200441e0016a200241f8046a41286a2208290300370300200441e8016a200241f8046a41306a2903003703002002200441f0016a3602fc09200220043602f809200241053602f409200220043602f009200241800a6a41206a22034200370300200241800a6a41186a22094280808080c000370300200241013a00a80a200242043703900a2002427f3703880a200242003703800a200241b8096a41086a220a2004290308370300200241b8096a41106a220b2004290310370300200241b8096a41186a220c2004290318370300200241b8096a41206a220e2004290320370300200220042903003703b809200220042800293602e80920022004412c6a2800003600eb09200441306a210120042d0028220f4102460d10200241f8086a41286a200241800a6a41286a290300370300200241f8086a41206a2003290300370300200241f8086a41186a2009290300370300200241f8086a41106a200241800a6a41106a290300370300200241f8086a41086a200241800a6a41086a290300370300200220022903800a3703f8082007200e2903003703002006200c2903003703002000200b290300370300200241f8046a41086a200a290300370300200220022903b8093703f8042002200f3a00a005200241a1056a220f20022802e809360000200f41036a221020022800eb09360000200241800a6a200241f8086a200241f8046a10bf02200a200141086a290300370300200b200141106a290300370300200c200141186a290300370300200e200141206a290300370300200220012903003703b809200220042800593602e8092002200441dc006a2800003600eb09200441e0006a210120042d0058220a4102470d060c100b200220022800800a3602f0092002200241830a6a2800003600f30920024181083b01f8082004102e41012101410421060c020b200220022800f8043602800a2002200241f8046a41036a2800003600830a20024181023b01f80802402008450d002008410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b2003102e0b0240200741046a280200450d002007280200102e0b2007102e2004102e41012106410121010c0f0b200220022d00f90422063a00f908200241013a00f80802402008450d002008410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b2003102e0b0240200741046a280200450d002007280200102e0b2007102e2004102e410121010b0c0d0b200241c4006a411c360200200241ec026a4102360200200242023702dc02200241d4f1c1003602d8022002411c36023c200241c4f3c100360238200241003602fc04200241c8ecc5003602f8042002200241386a3602e8022002200241f8046a360240200241d8026a41e4f1c100106a000b200b200c290300370300200241f8086a41206a220c200241800a6a41206a220e290300370300200241f8086a41186a220f200241800a6a41186a2210290300370300200241f8086a41106a2211200241800a6a41106a2212290300370300200241f8086a41086a2213200241800a6a41086a2214290300370300200220022903800a3703f808200241f8046a41206a2215200241b8096a41206a2208290300370300200241f8046a41186a2216200241b8096a41186a2203290300370300200241f8046a41106a2217200241b8096a41106a2209290300370300200241f8046a41086a2218200241b8096a41086a220b290300370300200220022903b8093703f804200220073a00a005200a20022802e809360000200a41036a220720022800eb09360000200241800a6a200241f8086a200241f8046a10bf02200b200041086a2903003703002009200041106a2903003703002003200041186a2903003703002008200041206a290300370300200220002903003703b80920022001280089013602e80920022001418c016a2800003600eb0920014190016a210020012d00880122194102460d0c200241f8086a41286a221a200241800a6a41286a221b290300370300200c200e290300370300200f20102903003703002011201229030037030020132014290300370300200220022903800a3703f8082015200829030037030020162003290300370300201720092903003703002018200b290300370300200220022903b8093703f804200220193a00a005200a20022802e809360000200720022800eb09360000200241800a6a200241f8086a200241f8046a10bf02200b200041086a2903003703002009200041106a2903003703002003200041186a2903003703002008200041206a290300370300200220002903003703b809200220012800b9013602e8092002200141bc016a2800003600eb09200141c0016a210020012d00b80122074102460d0c201a201b290300370300200241f8086a41206a220c200241800a6a41206a220e290300370300200241f8086a41186a220f200241800a6a41186a2210290300370300200241f8086a41106a2211200241800a6a41106a2212290300370300200241f8086a41086a2213200241800a6a41086a2214290300370300200220022903800a3703f808200241f8046a41206a2215200241b8096a41206a2208290300370300200241f8046a41186a2216200241b8096a41186a2203290300370300200241f8046a41106a2217200241b8096a41106a2209290300370300200241f8046a41086a2218200241b8096a41086a220b290300370300200220022903b8093703f804200220073a00a005200a20022802e809360000200a41036a220720022800eb09360000200241800a6a200241f8086a200241f8046a10bf02200b200041086a2903003703002009200041106a2903003703002003200041186a2903003703002008200041206a290300370300200220002903003703b809200220012800e9013602e8092002200141ec016a2800003600eb09200141f0016a210020012d00e80122014102460d0c200241f8086a41286a200241800a6a41286a290300370300200c200e290300370300200f20102903003703002011201229030037030020132014290300370300200220022903800a3703f8082015200829030037030020162003290300370300201720092903003703002018200b290300370300200220022903b8093703f804200220013a00a005200a20022802e809360000200720022800eb09360000200241800a6a200241f8086a200241f8046a10bf020c0c0b200241f8086a41286a2212200241800a6a41286a2213290300370300200241f8086a41206a2214200241800a6a41206a2215290300370300200241f8086a41186a2216200241800a6a41186a2217290300370300200241f8086a41106a2218200241800a6a41106a2219290300370300200241f8086a41086a221a200241800a6a41086a221b290300370300200220022903800a3703f808200241f8046a41206a221c200241b8096a41206a220b290300370300200241f8046a41186a221d200241b8096a41186a220c290300370300200241f8046a41106a221e200241b8096a41106a220e290300370300200241f8046a41086a221f200241b8096a41086a2211290300370300200220022903b8093703f8042002200a3a00a005200f20022802e809360000201020022800eb09360000200241800a6a200241f8086a200241f8046a10bf022011200141086a290300370300200e200141106a290300370300200c200141186a290300370300200b200141206a290300370300200220012903003703b80920022004280089013602e80920022004418c016a2800003600eb0920044190016a210120042d008801220a4102460d0920122013290300370300201420152903003703002016201729030037030020182019290300370300201a201b290300370300200220022903800a3703f808201c200b290300370300201d200c290300370300201e200e290300370300201f2011290300370300200220022903b8093703f8042002200a3a00a005200f20022802e809360000200f41036a220a20022800eb09360000200241800a6a200241f8086a200241f8046a10bf022011200141086a290300370300200e200141106a290300370300200c200141186a290300370300200b200141206a290300370300200220012903003703b809200220042800b9013602e8092002200441bc016a2800003600eb09200441c0016a210120042d00b801220b4102460d09200241f8086a41286a2212200241800a6a41286a2213290300370300200241f8086a41206a2214200241800a6a41206a2215290300370300200241f8086a41186a2216200241800a6a41186a2217290300370300200241f8086a41106a2218200241800a6a41106a2219290300370300200241f8086a41086a221a200241800a6a41086a221b290300370300200220022903800a3703f808200241f8046a41206a221c200241b8096a41206a220c290300370300200241f8046a41186a221d200241b8096a41186a220e290300370300200241f8046a41106a221e200241b8096a41106a2210290300370300200241f8046a41086a221f200241b8096a41086a2211290300370300200220022903b8093703f8042002200b3a00a005200f20022802e809360000200a20022800eb09360000200241800a6a200241f8086a200241f8046a10bf022011200141086a2903003703002010200141106a290300370300200e200141186a290300370300200c200141206a290300370300200220012903003703b809200220042800e9013602e8092002200441ec016a2800003600eb09200441f0016a210120042d00e80122044102460d0920122013290300370300201420152903003703002016201729030037030020182019290300370300201a201b290300370300200220022903800a3703f808201c200c290300370300201d200e290300370300201e2010290300370300201f2011290300370300200220022903b8093703f804200220043a00a005200f20022802e809360000200f41036a20022800eb09360000200241800a6a200241f8086a200241f8046a10bf020c090b41f0014108102c000b41f0014108102c000b41134101102c000b410c4104102c000b41044101102c000b20084101102c000b410c4104102c000b41044101102c000b20014101102c000b200241f8046a41086a2204200241800a6a41086a2903003703002000200241800a6a41106a29030037030020062009290300370300200720032903003703002008200241800a6a41286a290300370300200220013602f809200220022903800a3703f804200241f0096a103a200241f8086a41086a20022903f8042220370300200241f8086a41106a20042903002221370300200241f8086a41186a2000290300220d370300200241f8086a41206a2006290300370300200241f8086a41286a2007290300370300200241f8086a41306a200829030037030041002101200241003a00f808200da7210c20022d00f90821060b200241a8096a2d00002110200241a4096a2802002109200241a0096a280200210e2002419c096a280200210b20024198096a280200210a20024194096a280200210f024020010d00410121030c020b42bcf7ea858cf8afdfbd7f2006410473ad42078342038688a72104410021030c0b0b200241f8086a41086a2201200241800a6a41086a290300370300200241f8086a41106a2207200241800a6a41106a290300370300200241f8086a41186a22082006290300370300200241f8086a41206a22062004290300370300200241f8086a41286a2204200241800a6a41286a290300370300200220003602f809200220022903800a3703f808200241f0096a103a200241f8046a41106a2001290300220d370300200241f8046a41186a22012007290300370300200241f8046a41206a22002008290300370300200241f8046a41286a22072006290300370300200241f8046a41306a22032004290300370300200220022903f80822213703800541002104200241003a00f804200241f0096a41086a200d370300200220213703f009200241f8046a412c6a28020021062007280200210a2002419c056a28020021082000280200210020024194056a280200210b2001280200210920022d00a8074112470d092003290300210d200241cc076a2802002110200241086a41b8dfc5004114107d200241b8096a200228020c410020022802081b10f601200220103602e809200241f8086a41186a22014200370300200241f8086a41106a22044200370300200241f8086a41086a22074200370300200242003703f808200241e8096a4104200241f8086a1000200241800a6a41186a2001290300370300200241800a6a41106a2004290300370300200241800a6a41086a2007290300370300200220022903f8083703800a0240024020022802bc09220720022802c00922046b4120490d00200441206a210320022802b80921010c010b200441206a22032004490d0e20074101742201200320032001491b220c4100480d0e0240024020070d00200c102921010c010b20022802b8092007200c102a21010b2001450d022002200c3602bc09200220013602b809200c21070b200120046a220420022903800a370000200441186a200241800a6a41186a290300370000200441106a200241800a6a41106a290300370000200441086a200241800a6a41086a2903003700002001200341c8ecc500410041001005210302402007450d002001102e0b410121042003417f470d09200241b8dfc5004114107d200241c8076a2802002002280204410020022802001b2212470d09200241f8086a41086a22014200370300200242003703f8084183d9c500410d200241f8086a1003200241800a6a41086a2001290300370300200220022903f8083703800a200241b8096a200241800a6a109802024020022802b80922130d00410021040c0a0b20022802bc09211402400240200241b8096a41086a28020020104d0d002002410036028009200242013703f80820022802ac072104410410292201450d0420024284808080c0003702fc08200220013602f80820012004360000200241b0076a2802002103200241b8076a2802002201200241f8086a10470240024020022802fc08220720022802800922046b2001490d0020022802f80821070c010b200420016a220c2004490d102007410174220e200c200c200e491b220c4100480d100240024020070d00200c102921070c010b20022802f8082007200c102a21070b2007450d062002200c3602fc08200220073602f8080b2002200420016a36028009200720046a2003200110f6041a200241bc076a2802002104200241c4076a2802002201200241f8086a10470240024020010d0020022802fc082103200228028009210f201221070c010b20042001410c6c6a211103402004280200210e200441086a2802002201200241f8086a10470240024020022802fc08220320022802800922076b2001490d0020022802f808210c0c010b200720016a220c2007490d122003410174220f200c200c200f491b220f4100480d120240024020030d00200f1029210c0c010b20022802f8082003200f102a210c0b200c450d092002200f3602fc082002200c3602f808200f21030b2002200720016a220f36028009200c20076a200e200110f6041a2004410c6a22042011470d000b20022802c80721070b024002402003200f6b4104490d0020022802f80821010c010b200f41046a2201200f490d1020034101742204200120012004491b22044100480d100240024020030d002004102921010c010b20022802f80820032004102a21010b2001450d08200220043602fc08200220013602f808200421030b2002200f41046a2204360280092001200f6a200736000020022802cc07210c02400240200320046b41034d0d00200321070c010b200441046a22072004490d102003410174220e20072007200e491b22074100480d100240024020030d002007102921010c010b200120032007102a21010b2001450d09200220073602fc08200220013602f8080b200120046a200c3600002001200f41086a200241d0076a201320104105746a2203100c210402402007450d002001102e0b2004450d010b410021042014450d0a2013102e0c0a0b410c10292201450d07410410292204450d0820024284808080c0003702fc08200220043602f808200420123600002003200241f8086a104a200241800a6a41086a2002280280092204360200200220022903f80822213703800a200141086a200436020020012021370200200220022802e8093602b009200220022800eb093600b30902402014450d002013102e0b200241800a6a41206a428180808010370300200241800a6a41186a4100360200200241ac0a6a20022800b30936000041012103200241013a00a80a2002200136029c0a200242043703900a2002427f3703880a200242003703800a200220022802b0093600a90a200241f8086a41086a200241f0096a41086a290300370300200241f8086a41246a2006360200200241f8086a41206a200a360200200241f8086a41186a2000360200200241f8086a41146a200b360200200220022903f0093703f8082002200d3703a00920022008360294092002200936028809200241b8096a200241800a6a200241f8086a10bf02200241b8096a41146a280200210f200241b8096a41186a280200210a200241b8096a41206a280200210e200241b8096a41246a280200210920022903b809212020022903c009212120022802c809210c20022802d409210b20022d00e00921100b0c090b200c4101102c000b41044101102c000b200c4101102c000b200f4101102c000b20044101102c000b20074101102c000b410c4104102c000b41044101102c000b02402000450d002000410c6c21002009210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b0240200b450d002009102e0b02402006450d002006410c6c21002008210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b42002120427f21214104210c0240200a450d002008102e0b4100210a41012110410121094101210e4100210f410021030b2005102f0c010b4100210341810121040b200241003602e0064201210d200242013703d806024002400240024002400240024002400240024002400240200341024d0d00420021210c010b024002400240024020030e03000102000b410110292201450d04200241013602dc06200220022802e006220041016a3602e006200220013602d806200120006a41003a00000240024020022802dc0620022802e0062201460d0020022802d80621000c010b200141016a22002001490d0f20014101742205200020002005491b22054100480d0f0240024020010d002005102921000c010b20022802d80620012005102a21000b2000450d06200220053602dc06200220003602d80620022802e00621010b2002200141016a3602e006200020016a20043a00000c020b410110292201450d05200241013602dc06200220022802e006220041016a3602e006200220013602d806200120006a41013a00000240024020022802dc06220020022802e00622016b4108490d0020022802d80621000c010b200141086a22042001490d0e20004101742201200420042001491b22014100480d0e0240024020000d002001102921000c010b20022802d80620002001102a21000b2000450d07200220013602dc06200220003602d80620022802e00621010b2002200141086a3602e006200020016a2020370000200a200241d8066a10470240200a450d00200c200a410c6c6a2108200c2104034020042802002106200441086a2802002201200241d8066a10470240024020022802dc06220520022802e00622006b2001490d0020022802d80621050c010b200020016a22072000490d1020054101742200200720072000491b22004100480d100240024020050d002000102921050c010b20022802d80620052000102a21050b2005450d0a200220003602dc06200220053602d80620022802e00621000b2002200020016a3602e006200520006a2006200110f6041a2004410c6a22042008470d000b0b2009200241d8066a104702402009450d00200b2009410c6c6a2108200b2104034020042802002106200441086a2802002201200241d8066a10470240024020022802dc06220520022802e00622006b2001490d0020022802d80621050c010b200020016a22072000490d1020054101742200200720072000491b22004100480d100240024020050d002000102921050c010b20022802d80620052000102a21050b2005450d0b200220003602dc06200220053602d80620022802e00621000b2002200020016a3602e006200520006a2006200110f6041a2004410c6a22042008470d000b0b0240024020022802dc06220020022802e00622016b4108490d0020022802d80621000c010b200141086a22042001490d0e20004101742201200420042001491b22014100480d0e0240024020000d002001102921000c010b20022802d80620002001102a21000b2000450d0a200220013602dc06200220003602d80620022802e00621010b2002200141086a3602e006200020016a20213700000240024020022802dc0620022802e0062201460d0020022802d80621000c010b200141016a22002001490d0e20014101742204200020002004491b22044100480d0e0240024020010d002004102921000c010b20022802d80620012004102a21000b2000450d0b200220043602dc06200220003602d80620022802e00621010b2002200141016a3602e006200020016a20103a00000c010b410110292201450d0a200241013602dc06200220022802e006220041016a3602e006200220013602d806200120006a41023a00000240024020022802dc0620022802e0062201460d0020022802d80621000c010b200141016a22002001490d0d20014101742205200020002005491b22054100480d0d0240024020010d002005102921000c010b20022802d80620012005102a21000b2000450d0c200220053602dc06200220003602d80620022802e00621010b2002200141016a3602e006200020016a20043a00000b20023502e006422086212120023502d806210d0b024020034101470d000240200a450d00200a410c6c2100200c210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b0240200f450d00200c102e0b02402009450d002009410c6c2100200b210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b200e450d00200b102e0b200241b00a6a24002021200d840f0b41014101102c000b20054101102c000b41014101102c000b20014101102c000b20004101102c000b20004101102c000b20014101102c000b20044101102c000b41014101102c000b20054101102c000b102d000b980505017f027e077f017e017f230041106b220324002002290300210420012903002105200141106a21062002280210210702400240024002400240200141146a2802002208200141186a28020022096b200241186a280200220a490d00200628020021080c010b2009200a6a220b2009490d032008410174220c200b200b200c491b220bad420c7e220d422088a70d03200da7220c4100480d030240024020080d00200c102921080c010b20062802002008410c6c200c102a21080b2008450d0120012008360210200141146a200b3602000b20082009410c6c6a2007200a410c6c10f6041a200141186a2009200a6a36020020024100360218200341086a200641086a280200360200200320062902003703002001411c6a2106200228021c210b02400240200141206a2802002208200141246a28020022096b200241246a280200220a490d00200628020021080c010b2009200a6a220c2009490d032008410174220e200c200c200e491b220cad420c7e220d422088a70d03200da7220e4100480d030240024020080d00200e102921080c010b20062802002008410c6c200e102a21080b2008450d022001200836021c200141206a200c3602000b20082009410c6c6a200b200a410c6c10f6041a200141246a2009200a6a360200200241003602242000427f200520047c220420042005541b37030020002003290300370210200041186a200341086a2802003602002000200629020037021c200041246a200641086a280200360200200020022d0028410020012d00281b3a00282000200229030822052001290308220420042005561b3703080240200241146a280200450d002007102e0b0240200241206a280200450d00200b102e0b200341106a24000f0b200c4104102c000b200e4104102c000b102d000bf70101047f230041c0006b22032400200341206a41186a22044200370300200341206a41106a22054200370300200341206a41086a220642003703002003420037032020012002200341206a1000200341186a2004290300370300200341106a2005290300370300200341086a200629030037030020032003290320370300410021022003410036022020034120200341206a1008210102400240024020032802202204417f470d000c010b024020010d000c010b20044104490d01200128000021042001102e410121020b2000200436020420002002360200200341c0006a24000f0b41eff0c2004133200341206a4184f4c2001053000bce3705057f017e0c7f027e1b7f23004190046b22022400024002400240024002400240024002400240024020014104490d00200041c8ecc50020011b2800002103100e4101470d08200241286a41d2d7c1004111107d200228022c2100200228022821044100210520024100360270410141d0d9c100411c200241f0006a100f21012000410020041b21040240024020022802702200417f470d0041012100410121060c010b2000ad220742208620078421072001452100024020010d00410121060c010b2007422088a74105490d0320012800012205200449200520034920012d00001b2106200121050b200420034f0d012006450d010240410110292201450d00200141003a00000240200141014105102a2201450d0020012003360001410141d0d9c100411c4100200520001b22042007422088a7417f20041b20014105101021042001102e024020002007a745720d002005102e0b20040d0a200241f0006a41086a22014200370300200242003703704183d9c500410d200241f0006a100320024190036a41086a20012903003703002002200229037037039003200241f0006a20024190036a1098024100210802400240200228027022090d00410121094100210a4100210b0c010b2001280200210b2002280274210a0b200241e9dabdf30636028004200241003602840420024180046a20024184046a10112101200220022802840436028c042002200136028804200241206a20024188046a10312002280224210620022802200d05200228028c0422014160712200417f4c0d070240024002402001410576220c0d00410121080c010b200010292208450d010b2006450d0741002105034020012104200241003a0090012005220d41016a2105410021010240024002400240034020042001460d01200241f0006a20016a20022802880422002d00003a00002002200041016a360288042002200141016a22003a0090012000210120004120470d000b200241306a41086a220e200241f0006a41086a290300370300200241306a41106a220f200241f0006a41106a290300370300200241306a41186a2210200241f0006a41186a29030037030020022002290370370330200c200d470d03200d4101742201200520052001491b220c41ffffff3f71200c470d11200c410574220141004e0d010c110b2002410036028c040240200141ff0171450d00200241003a0090010b200c0d01410021080c0b0b02400240200d0d002001102921080c010b2008200d4105742001102a21080b20080d0120014101102c000b2008102e410021080c080b200420006b21012008200d4105746a220d2002290330370000200d41186a2010290300370000200d41106a200f290300370000200d41086a200e29030037000020052006470d000b2002200420006b36028c040c070b20004101102c000b41054101102c000b41014101102c000b2002419c036a411c36020020024184016a410236020020024202370274200241d4f1c1003602702002411c36029403200241e0f3c1003602900320024100360234200241c8ecc500360230200220024190036a360280012002200241306a36029803200241f0006a41e4f1c100106a000b20002007a745720d062005102e0c060b02402007a7450d002001102e0b41d2d6c500412d10090c050b0b410121112008410120081b21054100211241002113024002400240024002402006410020081b2200450d0020004105742201410575221241ffffff3f712012470d0920014100480d09200110292211450d01200520016a210d20004105742106410021010340200520016a22002900002107200041086a2900002114200041106a2900002115201120016a220441186a200041186a290000370000200441106a2015370000200441086a2014370000200420073700002006200141206a2201470d000b200d20056b41606a41057641016a21130b02402008450d00200c450d002005102e0b20134115490d024101450d04201341017622164105742201417f4c0d04200110292217450d01201141606a2118201141a07f6a21194104211a4100211b4100210c2013211c0340201c21084100211c4101210602402008417f6a2204450d00024002400240024002400240201120044105746a2008410574220d20116a41406a412010f8044100480d002008417e6a21052019200d6a21014100211c410021000340024020052000470d00200821060c080b200041016a2100200141206a2001412010f8042104200141606a21012004417f4a0d000b200041016a21062000417f7320086a21040c010b2019200d6a210102400340024020044101470d00410021040c020b2004417f6a2104200141206a2001412010f8042100200141606a210120004100480d000b0b20082004490d01200820134b0d03200820046b22064101762205450d002018200d6a2101201120044105746a2100034020024190036a41186a220d200041186a220e29000037030020024190036a41106a220f200041106a221029000037030020024190036a41086a221d200041086a221e2900003703002002200029000037039003200141086a221f2900002107200141106a22202900002114200141186a221c290000211520002001290000370000200e201537000020102014370000201e2007370000201c200d2903003700002020200f290300370000201f201d2903003700002001200229039003370000200141606a2101200041206a21002005417f6a22050d000b0b024020040d002004211c0c050b0240200641094d0d002004211c0c050b200820134b0d01200820046b2105201120044105746a210d034020082004417f6a221c490d0402402008201c6b22064102490d00201120044105746a22012011201c4105746a2204412010f804417f4a0d002004290000210720042001290000370000200241f0006a41186a221d200441186a2200290000370300200241f0006a41106a221e200441106a220e290000370300200241f0006a41086a221f200441086a220f290000370300200f200141086a290000370000200e200141106a2900003700002000200141186a2900003700002002200737037041012110024020064103490d00200441c0006a200241f0006a412010f804417f4a0d0041022100200d210102400340200141186a200141386a290000370000200141106a200141306a290000370000200141086a200141286a2900003700002001200141206a220e29000037000020052000460d01200141c0006a210f20002110200e2101200041016a2100200f200241f0006a412010f804417f4a0d020c000b0b200021100b200420104105746a22012002290370370000200141186a201d290300370000200141106a201e290300370000200141086a201f2903003700000b201c450d05200d41606a210d200541016a2105201c21042006410a4f0d050c000b0b200420081035000b20082004417f6a221c490d010b20082013105e000b201c20081035000b024002400240201b200c470d00201b41016a2201201b490d0c201b4101742200200120012000491b220141ffffffff01712001470d0c200141037422004100480d0c02400240201b0d0020001029211a0c010b201a201b4103742000102a211a0b201a450d012001211b0b201a200c4103746a220120063602042001201c360200200c41016a221d210c201d4102490d0103400240024002400240201a201d220f417f6a221d4103746a2201280200450d00200f410374201a6a220641746a2802002205200128020422004d0d004102210c200f41024d0d06201a200f417d6a22014103746a2802042204200020056a4d0d014103210c200f41034d0d06200641646a280200200420056a4d0d01200f210c0c060b200f4103490d0120012802042100201a200f417d6a22014103746a28020421040b20042000490d010b200f417e6a21010b024002400240024002400240200f200141016a22214d0d00200f20014d0d01201a20014103746a221e2802042222201e2802006a2201201a20214103746a221f2802002220490d02200120134b0d03201e41046a2123201120204105746a220e201f280204221041057422006a210520014105742104200120206b220820106b220120104f0d04201720052001410574220010f604220d20006a21060240024020104101480d00200141014e0d010b20052101200d21000c060b201820046a21042005210103402004200141606a2205200641606a220820082005412010f804410048220c1b2200290000370000200441186a200041186a290000370000200441106a200041106a290000370000200441086a200041086a29000037000020062008200c1b21060240200e20052001200c1b2201490d00200d21000c070b200441606a2104200d2100200d2006490d000c060b0b41f484c0002021200f1038000b41f484c0002001200f1038000b202020011035000b20012013105e000b2017200e200010f604220d20006a21060240024020104101480d00200820104a0d010b200e2101200d21000c010b201120046a210c200d2100200e2101034020012005200020052000412010f80441004822081b2204290000370000200141186a200441186a290000370000200141106a200441106a290000370000200141086a200441086a2900003700002000200041206a20081b2100200141206a2101200541206a200520081b2205200c4f0d01200620004b0d000b0b20012000200620006b41607110f6041a2023202220106a360200201e2020360200201f201f41086a2021417f73200f6a41037410f7041a201d210c201d41014d0d020c000b0b20004104102c000b201c0d000b0240201b450d00201a102e0b2016450d032017102e0c030b20014101102c000b20014101102c000b20134102490d002013417f6a2100201341057420116a41606a21064101210403400240024002400240201320002201417f6a2200490d00201320006b22084102490d03201120014105746a2201201120004105746a2205412010f804417f4a0d032005290000210720052001290000370000200241f0006a41186a220f200541186a220c290000370300200241f0006a41106a2210200541106a220d290000370300200241f0006a41086a221a200541086a220e290000370300200e200141086a290000370000200d200141106a290000370000200c200141186a290000370000200220073703704101210120084103490d02200541c0006a200241f0006a412010f804417f4a0d0241002108200621010340200141186a200141386a290000370000200141106a200141306a290000370000200141086a200141286a2900003700002001200141206a220d29000037000020042008220c460d02200c417f6a2108200141c0006a210e200d2101200e200241f0006a412010f804417f4a0d020c000b0b200020131035000b4102200c6b21010b200520014105746a22012002290370370000200141186a200f290300370000200141106a2010290300370000200141086a201a2903003700000b200641606a21062004417f6a210420000d000b0b200b450d022009200b4105746a210e200241b1026a211d20024196036a2124200241f0006a41016a211e20024188026a2125200241a8016a2126200241f0006a41306a2127200241f0006a41286a21284100210820092106024002400240024002400340024002400240201341014b0d00024020130e020c000c0b0340200241f0006a41186a200641186a290000370300200241f0006a41106a200641106a290000370300200241f0006a41086a200641086a290000370300200220062900003703702011200241f0006a412010f804450d02200841016a2108200e200641206a2206470d000c0c0b0b0340200241f0006a41186a200641186a290000370300200241f0006a41106a200641106a290000370300200241f0006a41086a200641086a29000037030020022006290000370370200641206a210602402013450d004100210120132100034020012000410176220420016a2205201120054105746a200241f0006a412010f80441004a1b2101200020046b220041014b0d000b201120014105746a200241f0006a412010f804450d030b200841016a21082006200e460d0b0c000b0b200641206a2106410021010b0240024002400240024002400240201320014d0d00200241003602900320024190036a1012210402402002280290032200417f470d00410321010c0f0b20022000360274200220043602702000450d0320042d0000210520022000417f6a3602742002200441016a360270200541014b0d030240024020050e020100010b4100212120222116201a211f2010211c200f2129200d212a200c21202022212b201a212c2010212d200f212e200d212f200c21300c060b200241186a200241f0006a103120022802180d0320022802742205200228021c222c490d03202c417f4c0d0d02400240202c0d004101212141010d010c050b202c10342221450d0220212002280270221f202c10f604212020022005202c6b3602742002201f202c6a3602702020450d040b200241106a200241f0006a103120022802100d022002280274410c6e222f410c6c2205417f4c0d0d200228021421300240024002400240024020050d004104212e0c010b20051029222e450d010b02400240024020300d00202e212d0c010b410021164100211f4100211c202e212d0340200241086a200241f0006a103120022802080d0220022802742220200228020c2205490d022005417f4c0d130240024020050d004101212a0c010b20051034222a450d05202a20022802702229200510f6041a2002202020056b3602742002202920056a3602700b201c41016a21200240201c202f470d002016202020202016491b222fad420c7e2207422088a70d182007a722294100480d1802400240201c0d0020291029212e0c010b202e201f2029102a212e0b202e450d06202e212d0b202d201f6a221c202a360200201c41046a2005ad2207422086200784370200201641026a2116201f410c6a211f2020211c20302020470d000b0b202d450d06202c212b20302120202f212a202e2129202d211c202c211f202c211620210d080c070b0240201c450d004100210503400240202d20056a222041046a280200450d002020280200102e0b201f2005410c6a2205470d000b0b202f450d05202e102e0c050b20054104102c000b20054101102c000b20294104102c000b41ecd9c100200120131038000b202c4101102c000b202c450d002021102e0b41002121200c2130200d212f200f212e2010212d201a212c2022212b202321202017212a201b21292018211c2019211f200b21160b2000450d010b2004102e0b024020210d00410321010c080b200241b8dfc5004114107d2002280204212220022802002123200242013703702002410036027802400240024002400240410410292200450d0020024284808080c0003702742002200036027020002003360000201f200241f0006a10470240024020022802742204200228027822006b201f490d00200228027021040c010b2000201f6a22052000490d102004410174220c20052005200c491b22054100480d100240024020040d002005102921040c010b200228027020042005102a21040b2004450d0220022005360274200220043602700b20022000201f6a360278200420006a2021201f10f6041a2020200241f0006a10472020450d02201c2020410c6c6a211a201c210403402004280200210f200441086a2802002200200241f0006a1047024002402002280274220c200228027822056b2000490d002002280270210d0c010b200520006a220d2005490d11200c4101742210200d200d2010491b22104100480d1102400240200c0d0020101029210d0c010b2002280270200c2010102a210d0b200d450d05200220103602742002200d3602702010210c0b2002200520006a2210360278200d20056a200f200010f6041a2004410c6a2204201a470d000c050b0b41044101102c000b20054101102c000b2002280274210c200228027821100c010b20104101102c000b02400240200c20106b4104490d00200228027021000c010b201041046a22002010490d0b200c4101742204200020002004491b22044100480d0b02400240200c0d002004102921000c010b2002280270200c2004102a21000b2000450d0220022004360274200220003602702004210c0b2002201041046a2204360278200020106a2022410020231b220d36000002400240200c20046b41034d0d00200c21050c010b200441046a22052004490d0b200c410174220f20052005200f491b22054100480d0b02400240200c0d002005102921000c010b2000200c2005102a21000b2000450d0320022005360274200220003602700b200020046a2008360000200241e9dabdf30636029003202642003703002027420037030020284200370300200241f0006a41206a4200370300200241f0006a41186a4200370300200241f0006a41106a4200370300200241f0006a41086a420037030020024200370370024020024190036a201120014105746a2000201041086a200241f0006a10130d00200241306a41086a2201201e41086a290000370300200241306a41106a2204201e41106a290000370300200241306a41186a220c201e41186a290000370300200241306a41206a220f201e41206a290000370300200241306a41286a2210201e41286a290000370300200241306a41306a221a201e41306a290000370300200241306a41376a2222201e41376a2900003700002002201e29000037033020022d0070212302402005450d002000102e0b200241f0006a202441e80010f6041a201d2002290330370000201d41086a2001290300370000201d41106a2004290300370000201d41186a200c290300370000201d41206a200f290300370000201d41286a2010290300370000201d41306a201a290300370000201d41376a2022290000370000200220233a00b002200220083602ac022002200d3602a802200220203602a4022002202a3602a0022002202936029c022002201f36029802200220163602940220022021360290022002200336028c02200241123a008802200242023703d8012002200241f0006a3602880420024190036a20024188046a10ac022002280290032200200228029803101421010240200228029403450d002000102e0b20010d04410110292201450d05200141013a0000200141014105102a2201450d06200841016a210820012003360001410141d0d9c100411c2001410510152001102e2025102f2030210c202f210d202e210f202d2110202c211a202b212220202123202a21172029211b201c2118201f21192016210b2006200e470d010c090b0b02402005450d002000102e0b02402016450d002021102e0b02402020450d002020410c6c210103400240201c41046a280200450d00201c280200102e0b201c410c6a211c200141746a22010d000b0b41022101202a450d062029102e0c060b20044101102c000b20054101102c000b2025102f410421010c030b41014101102c000b41054101102c000b1032000b0240200a450d002009102e0b02402012450d002011102e0b0240024002400240024020010e050102030400010b41a4d6c500412e10090c050b41d2d6c500412d10090c040b41ffd6c500412a10090c030b41a9d7c500411f10090c020b41c8d7c500412e10090c010b0240200a450d002009102e0b2012450d002011102e0b20024190046a240042010f0b102d000b8f0806027f017e047f017e017f017e230041c0006b22022400024002402001450d00200220003602080c010b200241c8ecc5003602080b2002200136020c200241206a200241086a103f0240024002400240024020022802202203450d002002200229022422043702142002200336021020024101360238200241ddf4c10036023c200241206a200241106a200241386a104b024002400240200228022022054105470d0041002100200241003602380c010b2002412c6a2802002101200241286a2802002106024020050d00200220022802242200360238200241306a28020021070c020b410021002002410036023820054101470d002001450d002006102e0b0b410110292205450d012002428180808010370224200220053602200240024020000d00200541003a00000c010b200541013a00002001200241206a104702402001450d002000200141286c6a210803402000200241206a104a200041206a29030021090240024020022802242205200228022822016b4108490d00200228022021050c010b200141086a220a2001490d0820054101742201200a200a2001491b22014100480d080240024020050d002001102921050c010b200228022020052001102a21050b2005450d062002200136022420022005360220200228022821010b2002200141086a360228200520016a20093700002008200041286a2200470d000b0b0240024020022802242200200228022822016b4104490d00200228022021000c010b200141046a22052001490d0620004101742201200520052001491b22014100480d060240024020000d002001102921000c010b200228022020002001102a21000b2000450d052002200136022420022000360220200228022821010b2002200141046a360228200020016a20073600000b2004422088a72101200235022821092002350220210b024020022802382200450d002006450d002000102e0b2004a7210a02402001450d00200141246c21002003210103400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b0240200a450d002003102e0b200241c0006a24002009422086200b840f0b200241346a41023602002002411c6a411c36020020024202370224200241d4f1c1003602202002411c360214200241f8f3c1003602102002410036023c200241c8ecc5003602382002200241106a3602302002200241386a360218200241206a41e4f1c100106a000b41014101102c000b20014101102c000b20014101102c000b102d000ba40904027f017e067f027e230041c0006b22022400024002402001450d00200220003602080c010b200241c8ecc5003602080b2002200136020c200241206a200241086a103f02400240024002400240024020022802202203450d002002200229022422043702142002200336021020024101360238200241ddf4c10036023c200241206a200241106a200241386a104b4100210502400240200228022022014105470d000c010b200241346a2802002106200241306a28020021002002412c6a2802002107200241286a280200210820022802242109024020014101470d00200821050c010b20010d002008450d002009102e0b4105410120051b220810292201450d012002410136022820022008360224200220013602200240024020050d00200141003a00000c010b200141013a00000240024020022802242208200228022822016b4104490d00200228022021080c010b200141046a220a2001490d0720084101742201200a200a2001491b22014100480d070240024020080d002001102921080c010b200228022020082001102a21080b2008450d042002200136022420022008360220200228022821010b2002200141046a360228200820016a20093600002000200241206a104702402000450d002005200041286c6a210a2005210003402000200241206a104a200041206a290300210b0240024020022802242208200228022822016b4108490d00200228022021080c010b200141086a22092001490d0920084101742201200920092001491b22014100480d090240024020080d002001102921080c010b200228022020082001102a21080b2008450d072002200136022420022008360220200228022821010b2002200141086a360228200820016a200b370000200a200041286a2200470d000b0b0240024020022802242200200228022822016b4104490d00200228022021000c010b200141046a22082001490d0720004101742201200820082001491b22014100480d070240024020000d002001102921000c010b200228022020002001102a21000b2000450d062002200136022420022000360220200228022821010b2002200141046a360228200020016a20063600000b2004422088a721012002350228210b2002350220210c02402005450d002007450d002005102e0b2004a7210902402001450d00200141246c21002003210103400240024020012d0000220841034b0d0002400240024020080e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402009450d002003102e0b200241c0006a2400200b422086200c840f0b200241346a41023602002002411c6a411c36020020024202370224200241d4f1c1003602202002411c36021420024198f4c1003602102002410036023c200241c8ecc5003602382002200241106a3602302002200241386a360218200241206a41e4f1c100106a000b20084101102c000b20014101102c000b20014101102c000b20014101102c000b102d000bf10303077f017e017f230041306b2202240041082103200241106a41086a220442003703002002420037031041dadcc500411b200241106a1003200241086a200429030037030020022002290310370300410021052002410036021020024110200241106a100821060240024020022802102207417f460d002002200736022420022006360220200241106a200241206a103e024020022802102203450d00200241186a2802002104200228021421052007450d022006102e0c020b41eff0c2004133200241286a4184f4c2001053000b410021040b20024100360218200242013703102004200241106a10470240024002402004450d002003200441286c6a21082003210703402007200241106a104a200741206a29030021090240024020022802142206200228021822046b4108490d00200228021021060c010b200441086a220a2004490d0420064101742204200a200a2004491b22044100480d040240024020060d002004102921060c010b200228021020062004102a21060b2006450d032002200436021420022006360210200228021821040b2002200441086a360218200620046a20093700002008200741286a2207470d000b0b200235021821092002280210210402402005450d002003102e0b200241306a240020094220862004ad840f0b20044101102c000b102d000b7101017f024002400240410810292202450d00200242f02e370000200241084110102a2202450d012002429602370008200241104120102a2202450d02200242e807370018200242e8073700102002ad42808080808004840f0b41084101102c000b41104101102c000b41204101102c000bd40b06017f017e067f017e017f017e230041a0016b22022400200241186a41a9ddc50041131081012002290320210320022802182104200241286a41086a22054200370300200242003703284199ddc5004110200241286a100320024190016a41086a220620052903003703002002200229032837039001200241286a20024190016a10c7022005280200210720022802282108200228022c2109200241086a418addc500410f1081012002290310210a2002280208210b200542003703002002420037032841ffddc500410f200241286a10032006200529030037030020022002290328370390012003420020041b210c2009410020081b21052007410020081b2104200a4200200b1b21032008410820081b2108200241286a20024190016a10c8020240024020022d00284101460d0020024188016a4200370300200241f0006a41106a4200370300200241f0006a41086a4200370300200242003703700c010b20024188016a200241c1006a290000370300200241f0006a41106a200241396a290000370300200241f0006a41086a200241316a290000370300200220022900293703700b200241286a41086a220642003703002002420037032841ccddc5004113200241286a100320024190016a41086a20062903003703002002200229032837039001200220024190016a10c902200241c8006a2004360200200241c4006a2005360200200241d4006a200241f0006a41086a290300370200200241dc006a20024180016a290300370200200241e4006a20024188016a29030037020020022008360240200242e4003703382002200c370330200220033703282002200229037037024c2002410120022d0000220541017120054102461b3a006c2002410036027820024201370370024002400240024002400240410810292205450d002002410836027420022002280278220841086a36027820022005360270200520086a2003370000200229033021030240024020022802742208200228027822056b4108490d00200228027021080c010b200541086a22042005490d0620084101742205200420042005491b22054100480d060240024020080d002005102921080c010b200228027020082005102a21080b2008450d022002200536027420022008360270200228027821050b2002200541086a360278200820056a2003370000200229033821030240024020022802742208200228027822056b4108490d00200228027021080c010b200541086a22042005490d0620084101742205200420042005491b22054100480d060240024020080d002005102921080c010b200228027020082005102a21080b2008450d032002200536027420022008360270200228027821050b2002200541086a360278200820056a20033700002002280240210820022802482205200241f0006a104702402005450d002008200541286c6a210703402008200241f0006a104a200841206a29030021030240024020022802742204200228027822056b4108490d00200228027021040c010b200541086a22062005490d0820044101742205200620062005491b22054100480d080240024020040d002005102921040c010b200228027020042005102a21040b2004450d062002200536027420022004360270200228027821050b2002200541086a360278200420056a20033700002007200841286a2208470d000b0b200241cc006a200241f0006a10ca0202400240200228027420022802782205460d00200228027021080c010b200541016a22082005490d0620054101742204200820082004491b22044100480d060240024020050d002004102921080c010b200228027020052004102a21080b2008450d052002200436027420022008360270200228027821050b2002200541016a360278200820056a20022d006c3a0000200235027821032002350270210a02402002280244450d002002280240102e0b200241a0016a24002003422086200a840f0b41084101102c000b20054101102c000b20054101102c000b20054101102c000b20044101102c000b102d000bcd06020e7f047e230041c0016b2202240020024100360298012001411020024198016a1008210302400240024002400240024002402002280298012204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a103120022802080d052002280214220541286e220641286c2201417f4c0d01200228020c21070240024020010d00410821080c010b200110292208450d030b02402007450d00410021090340200241003a00b8012009220a41016a21094100210102400240024002400240034020052001460d0120024198016a20016a2002280210220b2d00003a00002002200b41016a3602102002200141016a220c3a00b801200c2101200c4120470d000b200241f8006a41086a220d20024198016a41086a290300370300200241f8006a41106a220e20024198016a41106a290300370300200241f8006a41186a220f20024198016a41186a290300370300200220022903980137037820022005200c6b2201360214200141074d0d01200241386a41086a200d2903002210370300200241386a41106a200e2903002211370300200241386a41186a200f2903002212370300200241186a41086a220c2010370300200241186a41106a220d2011370300200241186a41186a220e20123703002002200b41096a3602102002200141786a220536021420022002290378221037033820022010370318200b29000121102006200a470d04200a4101742201200920092001491b2206ad42287e2211422088a70d0b2011a722014100480d0b200a0d022001102921080c030b20024100360214200141ff0171450d00200241003a00b8010b200241386a41186a200241d8006a41186a2903003703002006450d0a2008102e0c0a0b2008200a41286c2001102a21080b2008450d060b2008200a41286c6a22012002290318370300200c2903002111200d2903002112200e290300211320012010370320200141186a2013370300200141106a2012370300200141086a201137030020092007470d000b0b2008450d052000200636020420002008360200200041086a20073602002004450d002003102e0b200241c0016a24000f0b1032000b20014108102c000b20014108102c000b102d000b41eff0c200413320024198016a4184f4c2001053000bcb0201057f230041d0006b220224002002410036022820014110200241286a1008210302400240024020022802282204417f460d0020030d010b200041003a00000c010b41002101200241003a00480340024020042001470d000240200141ff0171450d00200241003a00480b41eff0c2004133200241286a4184f4c2001053000b200241286a20016a200320016a2d00003a00002002200141016a22053a00482005210120054120470d000b200241086a41186a2201200241286a41186a290300370300200241086a41106a2205200241286a41106a290300370300200241086a41086a2206200241286a41086a2903003703002002200229032837030802402004450d002003102e0b20002002290308370001200041013a0000200041196a2001290300370000200041116a2005290300370000200041096a20062903003700000b200241d0006a24000b960101037f230041106b220224002002410036020420014110200241046a100821010240024020022802042203417f460d002001450d00200241003a000202402003450d0020012d00002104200241003a000320034101460d0020012d000121032001102e0c020b41eff0c2004133200241086a4184f4c2001053000b410221040b200020033a0001200020043a0000200241106a24000b952801057f02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2202280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00003a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00013a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00023a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00033a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00043a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00053a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00063a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00073a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00083a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00093a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000e3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1020012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000f3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00103a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00113a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00123a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00133a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00143a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00153a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00163a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00173a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00183a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00193a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001e3a000002400240200228020020032802002202460d00200128020021040c010b200241016a22042002490d2120024101742205200420042005491b22054100480d210240024020020d002005102921040c010b200128020020022005102a21040b2004450d2020012004360200200141046a2005360200200141086a28020021020b2003200241016a360200200420026a20002d001f3a00000f0b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20054101102c000b102d000bce0302097f037e230041306b22022400200241206a41086a22034200370300200242003703204199ddc5004110200241206a1003200241106a41086a2003290300370300200220022903203703102002200241106a10c70202400240200228020022040d004101210541002106410021070c010b200228020421084100210602400240200241086a280200220341286c22090d0041012105410021070c010b0240200941286d220741ffffff3f712007470d00200741057422094100480d002009102922050d0120094101102c000b102d000b02402003450d00200341286c210a4100210620052103200421090340200941086a290000210b200941106a290000210c2009290000210d200341186a200941186a290000370000200341106a200c370000200341086a200b3700002003200d370000200641016a2106200341206a2103200941286a2109200a41586a220a0d000b0b2008450d002004102e0b20024100360228200242013703202006200241206a104702402006450d00200641057421092005210303402003200241206a104a200341206a2103200941606a22090d000b0b2002350228210b2002280220210302402007450d002005102e0b200241306a2400200b4220862003ad840bc90c03047f017e067f23004180026b220224000240024020010d002002200136020c200241c8ecc5003602080c010b20022001417f6a36020c410121032002200041016a36020820002d0000220141014b0d0041002104410021000240024002400240024002400240024020010e020100010b2002200241086a103120022802000d07200228020c220120022802042200490d072000417f4c0d010240024020000d00410121040c010b200010342204450d03200420022802082205200010f6041a2002200120006b36020c2002200520006a3602080b2004450d07200241106a20042000ad22064220862006842206422088a710cd0220022802104101460d03200241186a280200210520022802142100410021030b2002200536021420022000360210200241e7e485f3063602b001200241d0016a41186a22074200370300200241d0016a41106a22084200370300200241d0016a41086a22094200370300200242003703d00141002101200241106a410020001b210a0240024020000d004100210b0c010b200a41046a280200210c200a280200210b0b200241b0016a200b41c8ecc500200b1b200c4100200b1b200241d0016a1016200241f0006a41186a2007290300370300200241f0006a41106a2008290300370300200241f0006a41086a2009290300370300200220022903d0013703702002200536021420022000360210200241e2c289ab063602b001200742003703002008420037030020094200370300200242003703d0010240024020000d000c010b200a41046a280200210b200a28020021010b200241b0016a200141c8ecc50020011b200b410020011b200241d0016a101720024190016a41186a2207200241d0016a41186a220129030037030020024190016a41106a2208200241d0016a41106a220b29030037030020024190016a41086a2209200241d0016a41086a220a290300370300200220022903d00137039001200220053602fc01200220003602f801200241e9dabdf3063602f40120014200370300200b4200370300200a4200370300200242003703d0010240024020000d00410021000c010b200241f8016a410020001b220041046a2802002105200028020021000b200241f4016a200041c8ecc50020001b2005410020001b200241d0016a1017200241b0016a41186a22002001290300370300200241b0016a41106a2201200b290300370300200241b0016a41086a2205200a290300370300200241106a41086a200241f0006a41086a290300370300200241106a41106a200241f0006a41106a290300370300200241106a41186a200241f0006a41186a290300370300200220022903d0013703b00120022002290370370310200241c8006a2007290300370300200241c0006a2008290300370300200241386a20092903003703002002200229039001370330200241e8006a2000290300370300200241e0006a2001290300370300200241d8006a2005290300370300200220022903b001370350200241003602d801200242013703d001200241106a200241d0016a104a200241306a200241d0016a104a200241d0006a200241d0016a104a20022802d801210020022802d401210a20022802d001210b024020032006a745720d002004102e0b200041046a2201417f4c0d000240024020010d00410121050c010b200110292205450d040b2002410036021820022001360214200220053602102000200241106a10470240024020022802142205200228021822016b2000490d00200228021021050c010b200120006a22042001490d0620054101742207200420042007491b22044100480d060240024020050d002004102921050c010b200228021020052004102a21050b2005450d0520022004360214200220053602100b200520016a200b200010f6041a200120006a21000240200a450d00200b102e0b20024180026a24002000ad4220862005ad840f0b1032000b20004101102c000b200220022902143703d00141a4f1c1004116200241d0016a41bcf1c1001053000b20014101102c000b20044101102c000b102d000b200241dc016a411c360200200241246a410236020020024202370214200241d4f1c1003602102002411c3602d401200241b8f4c1003602d001200241003602b401200241c8ecc5003602b0012002200241d0016a3602202002200241b0016a3602d801200241106a41e4f1c100106a000b850804057f017e017f017e02400240024002402002450d00410020016b410020014103711b2103200241796a4100200241074b1b210441002105034002400240200120056a2d000022064118744118752207417f4a0d0042808080801021080240200641b6eac5006a2d0000417e6a220941024d0d0042808080808020210a0c070b0240024002400240024020090e03000102000b200541016a22062002490d024200210a0c090b4200210a200541016a220920024f0d08200120096a2d0000210902400240200641a07e6a2206410d4b0d000240024020060e0e0002020202020202020202020201000b200941e0017141a001460d0242808080808020210a0c0c0b02402009411874411875417f4c0d0042808080808020210a0c0c0b200941ff017141a001490d0142808080808020210a0c0b0b02402007411f6a41ff0171410b4b0d0002402009411874411875417f4c0d0042808080808020210a0c0c0b200941ff017141c001490d0142808080808020210a0c0b0b0240200941ff017141bf014d0d0042808080808020210a0c0b0b0240200741fe017141ee01460d0042808080808020210a0c0b0b2009411874411875417f4c0d0042808080808020210a0c0a0b42002108200541026a220620024f0d09200120066a2d000041c00171418001460d020c070b4200210a200541016a220920024f0d07200120096a2d0000210902400240200641907e6a220641044b0d000240024020060e050002020201000b200941f0006a41ff01714130490d0242808080808020210a0c0b0b02402009411874411875417f4c0d0042808080808020210a0c0b0b200941ff0171419001490d0142808080808020210a0c0a0b0240200941ff017141bf014d0d0042808080808020210a0c0a0b02402007410f6a41ff017141024d0d0042808080808020210a0c0a0b2009411874411875417f4c0d0042808080808020210a0c090b200541026a220620024f0d07200120066a2d000041c00171418001470d0642002108200541036a220620024f0d08200120066a2d000041c00171418001460d01428080808080e000210a42808080801021080c080b42808080808020210a4280808080102108200120066a2d000041c00171418001470d070b200641016a21050c010b0240200320056b4103710d000240200520044f0d000340200120056a220641046a280200200628020072418081828478710d01200541086a22052004490d000b0b200520024f0d010340200120056a2c00004100480d022002200541016a2205470d000c040b0b200541016a21050b20052002490d000b0b20002001360204200041086a2002360200200041003602000f0b428080808080c000210a42808080801021080c010b420021080b2000200a2008842005ad84370204200041013602000b130020004101360204200041b8f5c1003602000b3400200041b8f6c10036020420004100360200200041146a4105360200200041106a41c8f6c100360200200041086a420f3702000b02000b2201017f230041106b220224002002410036020020002002109901200241106a24000b130020004101360204200041d0fdc1003602000b34002000419981c20036020420004100360200200041146a4107360200200041106a41a081c200360200200041086a42073702000b2f01017f02404101102922020d0041014101102c000b200042818080801037020420002002360200200241003a00000b130020004101360204200041e48cc2003602000b880201057f230041106b22022400024002400240411110292203450d002002421137020420022003360200410d200210470240024020022802042204200228020822036b410d490d002003410d6a2105200228020021040c010b2003410d6a22052003490d0320044101742206200520052006491b22064100480d030240024020040d002006102921040c010b200228020020042006102a21040b2004450d0220022006360204200220043602000b20022005360208200420036a220341002900e1f441370000200341056a41002900e6f44137000020002002290300370200200041086a2002280208360200200241106a24000f0b41114101102c000b20064101102c000b102d000ba504010b7f230041106b220324002003420037030820012002200341086a102420032003290308370300200120026a21040240024002400240200241086a220520024f0d00200341086a2106200321074100210841002105410121094100210a0340200841017421022006200741016a220b6b210c034020072d00002107024002400240024020082005470d002008417f417f200c200420016b6a22052005200c491b220541016a220d200d2005491b6a22052008490d072002200520052002491b22054100480d070240024020080d002005102921090c010b200920082005102a21090b2009450d010b200920086a20073a00000240024002400240200a41ff01710e03010300010b20042001460d010c050b0240200b2006460d004100210a0c040b20042001470d040b200841016a21080c090b4101210a200b2006470d01200841016a21080c080b20054101102c000b200841016a2108200b21070c020b200841016a21084102210a200241026a21022001220741016a21010c000b0b0b410121092005450d0120054100480d002005102922090d0120054101102c000b102d000b410021080340200920086a200320086a2d00003a0000200841016a22084108470d000b024020020d00410821080c010b200920086a2107410021080340200720086a200120086a2d00003a00002002200841016a2208470d000b200420016b41086a21080b200020083602082000200536020420002009360200200341106a24000bef0702067f017e230041106b220224002002410036020820024201370300200028020021030240024002400240024002400240410410292204450d0020024284808080c0003702042002200436020020042003360000200028020421050240024020022802042206200228020822046b4104490d00200441046a2103200228020021060c010b200441046a22032004490d0720064101742207200320032007491b22074100480d070240024020060d002007102921060c010b200228020020062007102a21060b2006450d0220022007360204200220063602000b20022003360208200620046a200536000020002802082103200041106a28020022042002104702402004450d002003200441286c6a2107034020032002104a200341206a29030021080240024020022802042206200228020822046b4108490d00200228020021060c010b200441086a22052004490d0920064101742204200520052004491b22044100480d090240024020060d002004102921060c010b200228020020062004102a21060b2006450d052002200436020420022006360200200228020821040b2002200441086a360208200620046a20083700002007200341286a2203470d000b0b0240024020002802144101460d0002400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d0920044101742206200320032006491b22064100480d090240024020040d002006102921030c010b200228020020042006102a21030b2003450d062002200636020420022003360200200228020821040b2002200441016a360208200320046a41003a00000c010b02400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d0820044101742206200320032006491b22064100480d080240024020040d002006102921030c010b200228020020042006102a21030b2003450d062002200636020420022003360200200228020821040b2002200441016a360208200320046a41013a0000200028021821060240024020022802042203200228020822046b4104490d00200228020021030c010b200441046a22052004490d0820034101742204200520052004491b22044100480d080240024020030d002004102921030c010b200228020020032004102a21030b2003450d072002200436020420022003360200200228020821040b2002200441046a360208200320046a20063600000b2002280204210420012802002001280204200228020022032002280208100402402004450d002003102e0b200241106a24000f0b41044101102c000b20074101102c000b20044101102c000b20064101102c000b20064101102c000b20044101102c000b102d000baa6408017f017e017f017e1a7f017e037f027e230041e0056b22002400107f200041a0016a41bcddc500411010810120002903a801210120002802a001210220004190016a41a9ddc500411310810102400240024042002001420020021b220120002903980142002000280290011b7d220320032001561b42e400540d0020004188016a41b8dfc5004114107d200028028c0121042000280288012105200041c8046a41086a22024200370300200042003703c80441dbdfc5004115200041c8046a1003200041b0056a41086a2002290300370300200020002903c8043703b005200041003602c803200041b0056a4110200041c8036a1008210202400240024002400240024002400240024020002802c8032206417f470d00410221070c010b024020020d00410221070c010b2006450d0120022d000021072002102e0b41ccdfc500410f109c012108200041c8046a41086a22024200370300200042003703c80441ec8ec2004112200041c8046a1003200041b0056a41086a2002290300370300200020002903c8043703b005200041003602c803200041b0056a4110200041c8036a100821090240024002400240024002400240024002400240024020002802c803220a417f460d002009450d002000200a3602fc04200020093602f80420004180016a200041f8046a10312000280280010d1320002802fc04220b41807f712202417f4c0d11200028028401210c02400240200b410776220d0d004101210e0c010b20021029220e450d0b0b0240200c450d00200041c8036a41206a210f200041e0026a4101722110410021110340200041003a008003201141016a21124100210202400240024002400340200b2002460d01200041e0026a20026a20002802f80422062d00003a00002000200641016a3602f8042000200241016a22063a0080032006210220064120470d000b200041c0026a41086a2202200041e0026a41086a290300370300200041c0026a41106a2213200041e0026a41106a290300370300200041c0026a41186a2214200041e0026a41186a290300370300200020002903e0023703c0022000200b20066b3602fc04200041e0026a200041f8046a107820002d00e0024101460d01200041c8036a41186a2014290300370300200041c8036a41106a2013290300370300200041c8036a41086a2002290300370300200020002903c0023703c803200f201041e00010f6041a200041c0016a200041c8036a41800110f6041a200d2011470d0320114101742202201220122002491b220d41ffffff0f71200d470d1a200d410774220241004e0d020c1a0b200041003602fc04200241ff0171450d00200041003a0080030b200d450d17200e102e0c170b0240024020110d0020021029210e0c010b200e20114107742002102a210e0b200e450d050b200e20114107746a200041c0016a41800110f6041a2012200c460d0120002802fc04210b201221110c000b0b200e450d13200a450d012009102e0c010b4101210e4100210c4100210d0b4100210202400240200c41077422060d0041012115410021160c010b2006410276220b10292215450d08200641077621160b0240200e200e20066a22174622180d00200c410774210b20152102200e2106034020022006290000370000200241186a200641186a290000370000200241106a200641106a290000370000200241086a200641086a290000370000200241206a210220064180016a2106200b41807f6a220b0d000b200c41077441807f6a41077641016a21020b200041c8046a41086a22064200370300200042003703c80441fff4c1004112200041c8046a1003200041b0056a41086a2006290300370300200020002903c8043703b005200041003602d003200042013703c8032002200041c8036a104702402002450d00200241057421062015210203402002200041c8036a104a200241206a2102200641606a22060d000b0b2004410020051b210220002802cc032106200041b0056a411020002802c803220b20002802d003100402402006450d00200b102e0b200041b0016a200241026a10da020240024020002802b00122190d002008200841ff0171410247712108200041c8046a41086a22064200370300200042003703c80441fff4c1004112200041c8046a1003200041b0056a41086a2006290300370300200020002903c8043703b005200041003602c803200041b0056a4110200041c8036a1008210b024020002802c8032211417f460d00200b450d00200020113602c4012000200b3602c001200041c8036a200041c0016a103020002802c8032205450d09200041d0036a280200210620002802cc03211a02402011450d00200b102e0b4100211b0c020b41002106410121054100211a4100211b0c010b200041b8016a28020021064101211b20002802b401211a20192105410121080b200041c8046a41086a220b4200370300200042003703c80441b8dfc5004114200041c8046a1003200041b0056a41086a200b290300370300200020002903c8043703b0054101211c2000200241016a220a3602c803200041b0056a4110200041c8036a410410044100211202400240200641057422020d004100211d0c010b2002410575221d41ffffff0f71201d470d13201d410774220b4100480d13200b1029221c450d060b0240200520026a2005460d0020064105742111200041c0016a4101722104200041c8036a41206a210941002112201c2113200521020340200241086a2900002101200241106a29000021032002290000211e200041b0056a41186a2214200241186a290000370300200041b0056a41106a220c2003370300200041b0056a41086a220f20013703002000201e3703b005200041f8046a200041b0056a1077200028028005210b20002802f8042106200041003602c0012006200b200041c0016a1008210b0240024020002802c0012210417f470d004100210b0c010b0240200b0d004100210b0c010b200020103602cc042000200b3602c804200041c0016a200041c8046a107820002d00c0014101460d07200041e0026a200441e00010f6041a02402010450d00200b102e0b200041c0016a200041e0026a41e00010f6041a4101210b0b024020002802fc04450d002006102e0b02400240200b0d00200041e0026a410041e00010f5041a0c010b200041e0026a200041c0016a41e00010f6041a0b200241206a2102200041c8036a41086a200f290300370300200041c8036a41106a200c290300370300200041c8036a41186a2014290300370300200020002903b0053703c8032009200041e0026a41e00010f6041a201241016a21122013200041c8036a41800110f6044180016a2113201141606a22110d000b0b0240201a450d002005102e0b201241ffffff0f712012470d0f20124107742202417f4c0d0f0240024020020d004101210c0c010b20021029220c450d040b4100210202402012450d00201c20124107746a211441807f201c6b210f200041c8036a41e0006a2106200041c8036a41c0006a210b200041c8036a41206a2111200c2113201c21020340200041c8036a41186a200241186a290000370300200041c8036a41106a200241106a290000370300200041c8036a41086a200241086a290000370300200020022900003703c803201141186a200241386a290000370000201141106a200241306a290000370000201141086a200241286a2900003700002011200241206a290000370000200b41186a200241d8006a290000370000200b41106a200241d0006a290000370000200b41086a200241c8006a290000370000200b200241c0006a2900003700002006200241e0006a290000370000200641086a200241e8006a290000370000200641106a200241f0006a290000370000200641186a200241f8006a2900003700002013200041c8036a41800110f6044180016a211320024180016a22022014470d000b201c20124107746a200f6a41077641016a21020b200041c8046a41086a22064200370300200042003703c80441ec8ec2004112200041c8046a1003200041b0056a41086a2006290300370300200020002903c8043703b005200041003602d003200042013703c8032002200041c8036a104702402002450d00200c20024107746a2106200c210203402002200041c8036a104a200241206a200041c8036a104a200241c0006a200041c8036a104a200241e0006a200041c8036a104a20024180016a22022006470d000b0b20002802cc032102200041b0056a411020002802c803220620002802d003100402402002450d002006102e0b02402012450d00200c102e0b200020083a00c803200041c8046a41086a22024200370300200042003703c80441dbdfc5004115200041c8046a1003200041b0056a41086a2002290300370300200020002903c8043703b005200041b0056a4110200041c8036a410110042000200a3602cc03200041043a00c80341c8ecc5004100200041c8036a1072410810292206450d02200620173602042006200e3602002007200741ff017141024771450d0a0240024020180d002006200e4180016a22143602002000200e2900223701ca032000200e29002a3701d203200041c0026a41086a220220002903d0033703002000200e2900323701da03200041c0026a41106a220b20002903d8033703002000200e28003a3601e2032000200e2f003e3b01e603200041c0026a41186a221120002903e003370300200041003a00e8032000200e2d00213a00c9032000200e2d00203a00c803200020002903c8033703c002200041c8046a41186a22132011290300370300200041c8046a41106a2211200b290300370300200041c8046a41086a220b2002290300370300200020002903c0023703c804200041c0016a41186a22022013290300370300200041c0016a41106a22132011290300370300200041c0016a41086a2211200b290300370300200020002903c8043703c001200e0d010b2006102e4108210f41002114410021024108210b0c0d0b200041e0026a41186a2002290300370300200041e0026a41106a2013290300370300200041e0026a41086a2011290300370300200020002903c0013703e002201720146b41077641016a220241286c220b417f4c0d0f200b1029220f450d01200f20002903e002370300200f4201370320200f41186a200041e0026a41186a221f290300370300200f41106a200041e0026a41106a2220290300370300200f41086a200041e0026a41086a222129030037030002402006280200220b2006280204221a470d0041012114200f210b0c0c0b2006200b4180016a22183602002000200b2900223701ca032000200b29002a3701d203200041c0026a41086a221020002903d0033703002000200b2900323701da03200041c0026a41106a220920002903d8033703002000200b28003a3601e2032000200b2f003e3b01e603200041c0026a41186a220420002903e003370300200041003a00e8032000200b2d00213a00c9032000200b2d00203a00c803200020002903c8033703c002200041c8046a41186a220b2004290300370300200041c8046a41106a22112009290300370300200041c8046a41086a22132010290300370300200020002903c0023703c804200041c0016a41186a2205200b290300370300200041c0016a41106a22072011290300370300200041c0016a41086a220a2013290300370300200020002903c8043703c0014102211441c800210c0340201f200529030022013703002020200729030022033703002021200a290300221e370300200020002903c00122223703e002200b2001370300201120033703002013201e370300200020223703c80402400240024002402014417f6a2002460d00200221080c010b201a20186b41077620026a41016a22082002490d162002410174221a20082008201a491b2208ad42287e2201422088a70d162001a7221a4100480d160240024020020d00201a1029210f0c010b200f200241286c201a102a210f0b200f450d010b200f200c6a221a41606a220220002903c8043703002013290300210120112903002103200b290300211e201a4201370300200241186a201e370300200241106a2003370300200241086a2001370300200628020022022006280204221a470d01200f210b200821020c0e0b201a4108102c000b200620024180016a2218360200200020022900223701ca032000200229002a3701d203201020002903d003370300200020022900323701da03200920002903d8033703002000200228003a3601e203200020022f003e3b01e603200420002903e003370300200041003a00e803200020022d00213a00c903200020022d00203a00c803200020002903c8033703c002200b20042903003703002011200929030037030020132010290300370300200020002903c0023703c8042005200b29030037030020072011290300370300200a2013290300370300200020002903c8043703c001200c41286a210c201441016a2114200821020c000b0b20024101102c000b200b4108102c000b41084104102c000b20024101102c000b41eff0c2004133200041c0026a4184f4c2001053000b200b4101102c000b41eff0c2004133200041c0026a4184f4c2001053000b200b4101102c000b20024101102c000b41eff0c2004133200041c0026a4184f4c2001053000b2006102e0c020b2006102e0b200041c8046a41086a22064200370300200042003703c80441dadcc500411b200041c8046a1003200041b0056a41086a2006290300370300200020002903c8043703b005200041003602c803200041b0056a4110200041c8036a100821060240024020002802c8032213417f460d002006450d00200020133602c401200020063602c001200041c8036a200041c0016a103e20002802c8032210450d03200041d0036a280200211120002802cc0321092013450d012006102e0c010b4100210941082110410021110b0240024020142011470d00200b2010460d01201441016a21112010210603402011417f6a2211450d02200b2006412010f8040d01200641206a2113200b41206a210c200641286a2106200b41286a210b200c2903002013290300510d000b0b200041c8046a41086a22064200370300200042003703c8044191f5c1004117200041c8046a1003200041b0056a41086a220b2006290300370300200020002903c8043703b005200041c8036a200041b0056a411010c601024020002802c80322114101470d00200041b0056a411010060b200041c8036a41086a280200210c20002802cc03211320064200370300200042003703c80441ba8ec200411d200041c8046a1003200b2006290300370300200020002903c8043703b005200041b0056a411041c8ecc500410041001005210602400240024020114101460d0002402006417f470d00200041f8006a41b0f3c200410d107d200028027c21062000280278210b200041c8036a41106a2014360200200041d4036a2002360200200041003602dc032000200f3602d003200041003602cc03200020064100200b1b3602c803200041c8046a41086a22064200370300200042003703c80441ba8ec200411d200041c8046a1003200041b0056a41086a2006290300370300200020002903c8043703b005200041103602c4012000200041b0056a3602c001200041c8036a200041c0016a10d8020b20020d010c020b02402006417f470d00200041f0006a41b0f3c200410d107d200028027421062000280270210b200041e8006a41fe8ec200411a107d20064100200b1b210602402000280268450d00200028026c20064b0d010b200041c8046a41086a220b4200370300200042003703c80441fe8ec200411a200041c8046a1003200041b0056a41086a2211200b290300370300200020002903c8043703b0052000200620134101746a3602c803200041b0056a4110200041c8036a41041004200041e0036a200c360200200041c8036a41106a2014360200200041d4036a2002360200200041013602dc032000200f3602d003200020133602cc03200020063602c803200b4200370300200042003703c80441ba8ec200411d200041c8046a10032011200b290300370300200020002903c8043703b005200041103602c4012000200041b0056a3602c001200041c8036a200041c0016a10d8020b2002450d010b200f102e0b2009450d012010102e0c010b02402009450d002010102e0b2002450d00200f102e0b0240410810292202450d00200220173602042002200e360200024041081029221f450d00201f201c20124107746a2220360204201f201c360200200041d8006a418addc500410f10810102402000290360420020002802581b220142017c22222001540d00200041c8046a41086a22064200370300200042003703c804418addc500410f200041c8046a1003200041c0016a41086a220b2006290300370300200020002903c8043703c001200020223703c803200041c0016a4110200041c8036a41081004200041e8046a200241988fc200104320002802ec04211420002802e804211320002802f004210220064200370300200042003703c8044199ddc5004110200041c8046a1003200b2006290300370300200020002903c8043703c001200041003602d003200042013703c8032002200041c8036a1047024002402002450d002013200241286c6a21122013210603402006200041c8036a104a200641206a29030021010240024020002802cc03220b20002802d00322026b4108490d0020002802c803210b0c010b200241086a22112002490d0b200b4101742202201120112002491b22024100480d0b02400240200b0d0020021029210b0c010b20002802c803200b2002102a210b0b200b450d03200020023602cc032000200b3602c80320002802d00321020b2000200241086a3602d003200b20026a20013700002012200641286a2206470d000b0b20002802cc032102200041c0016a411020002802c803220620002802d003100402402002450d002006102e0b02402014450d002013102e0b200041c8006a41bcddc50041101081012000290350210120002802482102200041386a41a9ddc5004113108101024042002001420020021b22032000290340420020002802381b22017d221e201e2003561b42e400540d00034042002003427f200142e4007c221e201e2001541b22017d221e201e2003561b42e300560d000b0b200041c8046a41086a22024200370300200042003703c80441a9ddc5004113200041c8046a1003200041c0016a41086a22062002290300370300200020002903c8043703c001200020013703c803200041c0016a4110200041c8036a410810040240202242017c22032022540d0020024200370300200042003703c804418edec5004113200041c8046a100320062002290300370300200020002903c8043703c001200041c8036a200041c0016a10c8020240024020002d00c8034101460d0020004190056a420037030020004188056a420037030020004180056a4200370300200042003703f8040c010b20004190056a200041e1036a29000037030020004188056a200041d9036a29000037030020004180056a200041d1036a290000370300200020002900c9033703f8040b200041306a41a1dec5004111107d2000280234210220002802302106200041c8046a41086a220b4200370300200042003703c80441a1dec5004111200041c8046a1003200041c0016a41086a2211200b290300370300200020002903c8043703c001200041003602c803200041c0016a4110200041c8036a41041004200041c0016a41186a200041f8046a41186a290300370300200041c0016a41106a200041f8046a41106a2903003703002011200041f8046a41086a290300370300200020002903f8043703c001417f2002410020061b221041016a220220022010491b410d744128722205417f4c0d060240200510292207450d00200720002903c00137000020072003370020200741186a200041c0016a41186a290300370000200741106a200041c0016a41106a290300370000200741086a200041c0016a41086a290300370000200041d4036a20002902a405370200200041dc036a200041a4056a41086a280200360200200041003602d003200020103602cc03200041003602c803200041003602e003200041e4036a200029029805370200200041ec036a20004198056a41086a280200360200200041c8036a41106a2118200041c8036a41186a211a412821044100210241002111410021144100210f41002113410021064100210b034020002802d403210c20002802dc03211202400240024003400240200b450d0020002802d80322092012460d00200020123602dc03200020023602d0032000200c3602d403200020063602c803201821120c040b0240024002400240200620104f0d00411610292202450d032002410e6a41002900c0de45370000200241086a41002900bade45370000200241002900b2de4537000020024116412c102a220b450d05200b2006360016200041c0026a41186a22024200370300200041c0026a41106a22114200370300200041c0026a41086a22144200370300200042003703c002200b411a200041c0026a1000200041c8046a41186a2002290300370300200041c8046a41106a2011290300370300200041c8046a41086a2014290300370300200020002903c0023703c804200041c0026a200041c8046a10820120002802c0022202450d01200041c8046a4120100620002902c4022101200221110c020b200020123602dc03200020023602d0032000200c3602d403200020063602c803024020002802e00322080d00410021080c060b201a410020081b220a2802082209200a28020c460d05200a41086a21120c060b4200210141012102410121110b200b102e2001422088a7410574210b02402013450d00024020002802d80322132012460d002000201220136b41606a41607120136a41206a3602d8030b200c450d00200f102e0b200641016a21062011200b6a21122001a7210c200020023602d803200221142011210f200221132002210b0c010b0b41164101102c000b412c4101102c000b02402014450d00024020002802d80322022012460d002000201220026b41606a41607120026a41206a3602d8030b200c450d002011102e0b02402008450d000240200041c8036a41206a2802002202200041ec036a2802002206460d002000200620026b41606a41607120026a41206a3602e8030b200041e4036a280200450d002008102e0b200041c0026a41186a22024200370300200041c0026a41106a22064200370300200041c0026a41086a220b4200370300200042003703c00220072004200041c0026a1000200041c8036a41186a22112002290300370300200041c8036a41106a22122006290300370300200041c8036a41086a2213200b290300370300200020002903c0023703c80302402005450d002007102e0b200041c8046a41086a22024200370300200042003703c804418edec5004113200041c8046a1003200041c0016a41086a22062002290300370300200020002903c8043703c001200041103602e4022000200041c0016a3602e002200041c8036a200041e0026a10b802200041b0056a41186a200041f8046a41186a2903002201370300200041b0056a41106a200041f8046a41106a290300221e370300200041b0056a41086a200041f8046a41086a2903002222370300200020002903f80422233703b005201120013703002012201e37030020132022370300200020233703c80320024200370300200042003703c80441ffddc500410f200041c8046a100320062002290300370300200020002903c8043703c001200041103602e4022000200041c0016a3602e002200041c8036a200041e0026a10b802200041c0026a201f419891c2001043200041206a41a9ddc5004113108101200029032821012000280220211120024200370300200042003703c804418edec5004113200041c8046a100320062002290300370300200020002903c8043703c001200041c8036a200041c0016a10c8020240024020002d00c8034101460d00200041f8026a4200370300200041f0026a4200370300200041e8026a4200370300200042003703e0020c010b200041f8026a200041e1036a290000370300200041f0026a200041d9036a290000370300200041e8026a200041d1036a290000370300200020002900c9033703e0020b200041c8046a41086a22024200370300200042003703c80441ccddc5004113200041c8046a1003200041c0016a41086a22062002290300370300200020002903c8043703c001200041186a200041c0016a10c90220002d0019211220002d0018211341dfddc5004120109c01210b20024200370300200042003703c80441ccddc5004113200041c8046a100320062002290300370300200020002903c8043703c001200041106a200041c0016a10c90220024200370300200042003703c80441ccddc5004113200041c8046a100320062002290300370300200020002903c8043703c001024002400240410210292202450d0020024101201241017120134102461b2206200b410171200b41ff01714102461b220b3a0001200220063a0000200041c0016a41102002410210042002102e200041c8036a41186a42e400370300200041c8036a41106a427f2001420020111b220142e4007c221e201e2001541b370300200041c8036a41206a20002903c002370300200041f0036a200041c0026a41086a280200360200200041f4036a20002903e002370200200041fc036a200041e0026a41086a29030037020020004184046a200041e0026a41106a2903003702002000418c046a200041e0026a41186a29030037020020004194046a200b3a0000200020033703d003200041003602c803200041003602c801200042013703c0010240410110292202450d00200041013602c401200020002802c801220641016a3602c801200020023602c001200220066a41013a000020002903d003210102400240024020002802c401220620002802c80122026b4108490d0020002802c00121060c010b200241086a220b2002490d1220064101742202200b200b2002491b22024100480d120240024020060d002002102921060c010b20002802c00120062002102a21060b2006450d01200020023602c401200020063602c00120002802c80121020b2000200241086a3602c801200620026a200137000020002903d803210102400240024020002802c401220620002802c80122026b4108490d0020002802c00121060c010b200241086a220b2002490d1320064101742202200b200b2002491b22024100480d130240024020060d002002102921060c010b20002802c00120062002102a21060b2006450d01200020023602c401200020063602c00120002802c80121020b2000200241086a3602c801200620026a200137000020002903e003210102400240024020002802c401220620002802c80122026b4108490d0020002802c00121060c010b200241086a220b2002490d1420064101742202200b200b2002491b22024100480d140240024020060d002002102921060c010b20002802c00120062002102a21060b2006450d01200020023602c401200020063602c00120002802c80121020b2000200241086a3602c801200620026a2001370000200041c8036a41206a2802002106200041c8036a41286a2802002202200041c0016a1047024002402002450d002006200241286c6a211203402006200041c0016a104a200641206a29030021010240024020002802c401220b20002802c80122026b4108490d0020002802c001210b0c010b200241086a22112002490d17200b4101742202201120112002491b22024100480d1702400240200b0d0020021029210b0c010b20002802c001200b2002102a210b0b200b450d03200020023602c4012000200b3602c00120002802c80121020b2000200241086a3602c801200b20026a20013700002012200641286a2206470d000b0b200041f4036a200041c0016a10ca0202400240024020002802c40120002802c8012202460d0020002802c00121060c010b200241016a22062002490d162002410174220b20062006200b491b220b4100480d160240024020020d00200b102921060c010b20002802c0012002200b102a21060b2006450d012000200b3602c401200020063602c00120002802c80121020b2000200241016a3602c801200620026a20002d0094043a000020004183056a20002802c801360000200020002903c0013700fb04200041cc016a200041ff046a290000370000200041c28289aa043600c101200041023a00c001200020002900f8043700c501200041c0016a109801024020002802c8030d00200041ec036a280200450d0020002802e803102e0b0240410810292212450d00201220173602042012200e3602000240410810292218450d00201820203602042018201c360200200041086a41b8dfc5004114107d200041c8036a200028020c410020002802081b10f60120002802c803220220002802d0031018024020002802cc03450d002002102e0b200041b0f3c200410d107d2000280204210220002802002111200041c8046a41086a22064200370300200042003703c80441d2d7c1004111200041c8046a1003200041c0016a41086a220b2006290300370300200020002903c8043703c00120002002410020111b3602c803200041c0016a4110200041c8036a4104100402402012280200220220122802042211470d002012102e410021024101210f410021130c0b0b201220024180016a2214360200200020022900623701ca032000200229006a3701d203200041c0026a41086a221320002903d003370300200020022900723701da03200041c0026a41106a220c20002903d8033703002000200228007a3601e203200020022f007e3b01e603200041c0026a41186a220f20002903e003370300200020022f00603b01c803200020002903c8033703c002200041c8046a41186a2202200f290300370300200041c8046a41106a220f200c29030037030020062013290300370300200020002903c0023703c804200041c0016a41186a22132002290300370300200041c0016a41106a2202200f290300370300200b2006290300370300200020002903c8043703c001200041b0056a41186a22062013290300370300200041b0056a41106a2002290300370300200041b0056a41086a200b290300370300200020002903c0013703b005410121130240201120146b41077641016a2202410574220b1029220f450d00200f20002903b005370000200f41186a2006290300370000200f41106a200041b0056a41106a290300370000200f41086a200041b0056a41086a2903003700002012280200220620122802042208460d0a201220064180016a221a360200200020062900623701ca032000200629006a3701d203200041c0026a41086a220520002903d003370300200020062900723701da03200041c0026a41106a220720002903d8033703002000200628007a3601e203200020062f007e3b01e603200041c0026a41186a220a20002903e003370300200020062f00603b01c803200020002903c8033703c002200041c8046a41186a2206200a290300370300200041c8046a41106a220b2007290300370300200041c8046a41086a22112005290300370300200020002903c0023703c804200041c0016a41186a22102006290300370300200041c0016a41106a2209200b290300370300200041c0016a41086a22042011290300370300200020002903c8043703c001410221134120210c0340200041e0026a41186a20102903002201370300200041e0026a41106a20092903002203370300200041e0026a41086a2004290300221e370300200020002903c00122223703e00220062001370300200b20033703002011201e370300200020223703c804024002402013417f6a2002460d00200221140c010b2008201a6b41077620026a41016a22142002490d1a20024101742208201420142008491b221441ffffff3f712014470d1a201441057422084100480d1a0240024020020d0020081029210f0c010b200f20024105742008102a210f0b200f0d0020084101102c000b200f200c6a220220002903c804370000200241186a2006290300370000200241106a200b290300370000200241086a201129030037000002402012280200220220122802042208470d00201421020c0c0b201220024180016a221a360200200020022900623701ca032000200229006a3701d203200520002903d003370300200020022900723701da03200720002903d8033703002000200228007a3601e203200020022f007e3b01e603200a20002903e003370300200020022f00603b01c803200020002903c8033703c0022006200a290300370300200b200729030037030020112005290300370300200020002903c0023703c804201020062903003703002009200b29030037030020042011290300370300200020002903c8043703c001200c41206a210c201341016a2113201421020c000b0b200b4101102c000b41084104102c000b41084104102c000b200b4101102c000b20024101102c000b20024101102c000b20024101102c000b20024101102c000b41014101102c000b41024101102c000b2012102e0b200041c8046a41086a22064200370300200042003703c8044183d9c500410d200041c8046a1003200041c0016a41086a2006290300370300200020002903c8043703c001200041003602d003200042013703c8032013200041c8036a104702402013450d002013410574210b200f210603402006200041c8036a104a200641206a2106200b41606a220b0d000b0b20002802cc032106200041c0016a411020002802c803220b20002802d003100402402006450d00200b102e0b02402002450d00200f102e0b2018102e0240201d450d00201c102e0b0240201b201945720d0020002802b401450d002019102e0b02402016450d002015102e0b200d450d0a200e102e0c0a0b2012200941206a360200200041b0056a41086a200941086a2212290000370300200041b0056a41106a200941106a220c290000370300200041b0056a41186a200941186a220a290000370300200020092900003703b005200041c8046a41186a2208200a290000370300200041c8046a41106a220a200c290000370300200041c8046a41086a220c2012290000370300200020092900003703c80402400240200520046b411f4b0d00200441206a22122004490d0d20054101742209201220122009491b22124100480d0d0240024020050d002012102921070c010b200720052012102a21070b2007450d01201221050b200720046a221220002903c804370000201241186a2008290300370000201241106a200a290300370000201241086a200c290300370000200441206a21040c010b0b20124101102c000b20054101102c000b41c08fc00041c900109b01000b20024101102c000b41c08fc00041c900109b01000b41084104102c000b41084104102c000b41eff0c2004133200041c0026a4184f4c2001053000b1032000b200041e0056a24000f0b41eff0c2004133200041c0026a4184f4c2001053000b102d000bdada0109097f017e027f027e0a7f097e027f0a7e2d7f230041f0176b22022400200241a80c6a41086a22034200370300200242003703a80c41b29bc5004110200241a80c6a1003200241e80d6a41086a2003290300370300200220022903a80c3703e80d200241003602c8102001417f6a2104200241e80d6a4110200241c8106a1008210102400240024002400240024002400240024002400240024020022802c8102203417f460d002001450d002003450d0220012d0000220341034f0d022001102e200341014b0d07024020030e020100010b200241a80c6a41086a22014200370300200242003703a80c41b29bc5004110200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241e80d6a411010060c010b20044106700d060b200241a80c6a41086a22014200370300200242003703a80c41fff4c1004112200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241003602c810200241e80d6a4110200241c8106a1008210120022802c8102203417f460d022001450d02200220033602e40b200220013602e00b200241c8106a200241e00b6a103020022802c8102205450d0141082106200241c8106a41086a280200210720022802cc10210802402003450d002001102e0b0240024020070d00410021094100210a0c010b20074105744105752209ad42d0007e220b422088a70d0a200ba722014100480d0a200110292206450d042007410574220741606a410576210c200241c8106a41206a21012006210d200521030340200341086a290000210b200341106a290000210e2003290000210f200241e00b6a41186a2210200341186a290000370300200241e00b6a41106a2211200e370300200241e00b6a41086a2212200b3703002002200f3703e00b200241e80d6a200241e00b6a10e903200241c8106a41186a2010290300370300200241c8106a41106a2011290300370300200241c8106a41086a2012290300370300200120022903e80d370300200141086a200241e80d6a41086a290300370300200141106a200241e80d6a41106a290300370300200141186a200241e80d6a41186a290300370300200141206a200241e80d6a41206a290300370300200141286a200241e80d6a41286a290300370300200220022903e00b3703c810200d200241c8106a41d00010f60441d0006a210d200341206a2103200741606a22070d000b200c41016a210a0b02402008450d002005102e0b200621130c040b41eff0c2004133200241e00d6a4184f4c2001053000b41eff0c2004133200241e00d6a4184f4c2001053000b410821064100210a41002109410821130c010b20014108102c000b200241a80c6a41086a22014200370300200242003703a80c41999bc5004119200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241c8106a200241e80d6a10b303024020022802cc102214450d00200241e80d6a411010060b410021150240024020140d00410421144100211041002116410021110c010b200241d4106a280200211020022802d010211620022802c81021110b200241b00a6a41c5c1c200410d10810120022903b80a210b20022802b00a2101200241a00a6a41e7e7c300411710810120022903a80a210e20022802a00a2103200241a80c6a41086a220c4200370300200242003703a80c41e7e7c3004117200241a80c6a1003200241e80d6a41086a2217200c290300370300200220022903a80c3703e80d2002200b420020011b220b3703c810200241e80d6a4110200241c8106a410810040240200b200e420020031b7d220f500d00200c4200370300200242003703a80c4192e9c3004116200241a80c6a10032017200c290300370300200220022903a80c3703e80d200241003602c810200241e80d6a4110200241c8106a100821010240024020022802c8102203417f460d002001450d00200220033602e40b200220013602e00b200241c8106a200241e00b6a1030024020022802c8102218450d00200241d0106a280200210d20022802cc1021192003450d022001102e0c020b41eff0c2004133200241e00d6a4184f4c2001053000b410121184100210d410021190b200241880a6a41a5bcc40041111070200241880a6a41106a290300211a20022903900a211b20022802880a2101200241f0096a41c28cc00041161070200241e0096a20022903f809420020022802f00922031b221c200241f0096a41106a290300420020031b428094ebdc03420010fc04200241d0096a20022903e009220b200241e0096a41086a290300220e4280ec94a37c427f10fb04200241c0096a201b420020011b201a420020011b200dad420010fb04200f42ffffffff0f8342ffffffff0f200f428080808010541b211d20022903d009201c7c210f200241c0096a41086a290300211e4100210741b0a4c200210320022903c009211f024002400340024041f0a6c200200322016b41304b0d00200141f0a6c200460d032002200128020022033602c8102002418094ebdc033602cc10200241b0096a200b200e200241c8106a2003418094ebdc034b4102746a350200221a420010fb0420022903b009221b201a200f7e428094ebdc038042ffffffff0f837c221a201f5a200241b0096a41086a290300201a201b54ad7c221a201e5a201a201e511b0d03200241a0096a41086a21120c020b2002200128020022033602c8102002418094ebdc033602cc1020024190096a200b200e200241c8106a2003418094ebdc034b4102746a350200221a420010fb04200229039009221b201a200f7e428094ebdc038042ffffffff0f837c221a201f5a20024190096a41086a290300201a201b54ad7c221a201e5a201a201e511b0d022002200128021022033602c8102002418094ebdc033602cc1020024180096a200b200e200241c8106a2003418094ebdc034b4102746a350200221a420010fb040240200229038009221b201a200f7e428094ebdc038042ffffffff0f837c221a201f5a20024180096a41086a290300201a201b54ad7c221a201e5a201a201e511b450d00200121070c030b2002200128022022033602c8102002418094ebdc033602cc10200241f0086a200b200e200241c8106a2003418094ebdc034b4102746a350200221a420010fb04024020022903f008221b201a200f7e428094ebdc038042ffffffff0f837c221a201f5a200241f0086a41086a290300201a201b54ad7c221a201e5a201a201e511b450d00200141106a21070c030b2002200128023022033602c8102002418094ebdc033602cc10200241e0086a200b200e200241c8106a2003418094ebdc034b4102746a350200221a420010fb04200141c0006a2103200141306a210720022903e008221b201a200f7e428094ebdc038042ffffffff0f837c221a201f54200241e0086a41086a290300201a201b54ad7c221a201e54201a201e511b0d000b200141206a21070c010b034041e0a6c20020012207460d01200741106a21012002200741106a28020022033602c8102002418094ebdc033602cc10200241a0096a200b200e200241c8106a2003418094ebdc034b4102746a350200221a420010fb0420022903a009221b201a200f7e428094ebdc038042ffffffff0f837c221a201f5a2012290300201a201b54ad7c221a201e5a201a201e511b450d000b0b42002120200241c0086a201f201e428094ebdc03420010fc04200241b0086a20022903c008221b200241c0086a41086a290300221c4280ec94a37c427f10fb04200741b0a4c20020071b2201410c6a2d00002103200141046a2802002107200141086a28020021012002418094ebdc033602cc10200220013602c810200241c8106a2001418094ebdc034b4102746a350200211a2002418094ebdc033602cc10200220073602c810200241a0086a201b201c200241c8106a2007418094ebdc034b4102746a3502002221420010fb04200241d0086a200b200e201a420010fb0420024190086a420020022903d008220e201a200f7e428094ebdc038042ffffffff0f837c220b20022903a008221a202120022903b008201f7c7e428094ebdc038042ffffffff0f837c220f7d221b201b200b56200241d0086a41086a290300200b200e54ad7c220e200241a0086a41086a290300200f201a54ad7c221b7d200b200f54ad7d221a200e56201a200e511b22011b427f200b200f7c220f200f200b542207200e201b7c2007ad7c220b200e54200b200e511b22071b20031b4200201a20011b427f200b20071b20031b201d420010fb0420024180086a20022903900820024190086a41086a29030042e08f860f420010fc0402400240200d0d00420021220c010b201420104102746a21232018200d4105746a212420024180086a41086a290300212520022903800821262011ad212742002120420021222014210d20182110024002400340200d2023460d0302400240200d2802002201450d00024002400240024002402011450d00200241f0076a202620252027420010fc04200241e0076a20022903f007220b200241f0076a41086a290300220e2027420010fb04200241d0076a200b200e20112001200120114b1bad220f420010fb04202620022903e0077d200f7e202780210b20022903d007210e200241d0076a41086a290300211a411210292201450d0120014100290090e843370000200141106a41002f00a0e8433b0000200141086a4100290098e84337000020024292808080a0023702cc10200220013602c8102010200241c8106a104a20022802cc10210720022802d010210320022802c8102101200241f00a6a41186a22124200370300200241f00a6a41106a22054200370300200241f00a6a41086a22084200370300200242003703f00a20012003200241f00a6a1000200241e80d6a41186a2012290300370300200241e80d6a41106a2005290300370300200241e80d6a41086a22122008290300370300200220022903f00a3703e80d200241003602c810200241e80d6a4120200241c8106a1008210320022802c8102205417f460d032003450d03200220053602cc10200220033602c810200241c8076a200241c8106a103120022802c8070d02200241b0076a200241c8106a106520022903b007a70d02200241b0076a41106a290300210f20022903b807211b2005450d042003102e0c040b41b8bcc4001058000b41124101102c000b41eff0c2004133200241e00d6a4184f4c2001053000b4200211b4200210f0b201a200e200b42ffffffff0f837c220b200e54ad7c210e02402007450d002001102e0b4200211a200242003703f00d200242003703e80d02400240200b201b200b201b200b54200f200e54200f200e511b22011b22287d2229200e200f200e20011b222a7d200b202854ad7d222b8450450d004200210b0c010b200241c8106a201010e903200241c8106a41086a290300220b420020022903c810220e420156200b420052200b501b22011b210b200e420120011b210e20022802e81021050240024020022802f01022010d00200241a8066a200e200b428094ebdc03420010fc04200241a8066a41086a290300212c20022903a806212d0c010b2005200141306c6a2107200241a0076a200e200b428094ebdc03420010fc0420024180076a2029202b428094ebdc03420010fc0420024190076a2029202b428094ebdc03420010fd04200241a0076a41086a290300222c420020022903a007222d420156202c420052202c501b22011b211a202d420120011b211b20024180076a41086a290300211d2002290380072121200229039007212e200521010340200241f0066a200e2001290300220f200f200e56200141086a290300220f200b56200f200b511b22031b200b200f20031b201b201a10fc0420022903f006221c428080808010544100200241f0066a41086a290300501b450d04200241e0066a200e200b201b201a10fc0420022903e006220f428080808010544100200241e0066a41086a290300501b450d060240200fa7450d00200241b8066a2021201d201c42ffffffff0f83428094ebdc037e200f42ffffffff0f838042ffffffff0f83220f420010fb04200241c8066a200141106a20022903b806221c200f202e7e428094ebdc038042ffffffff0f837c220f200241b8066a41086a290300200f201c54ad7c10ea03200241e80d6a20022903c80620022903d006200241c8066a41106a29030010a601200141306a22012007460d020c010b0b41a4f1c2001058000b20024198066a200e20022903d810220f200f200e56200241c8106a41186a290300220f200b56200f200b511b22011b200b200f20011b202d4201202d420156202c420052202c501b22011b220f202c420020011b221a10fc04200229039806221b42808080801054410020024198066a41086a290300501b450d0220024188066a200e200b200f201a10fc04200229038806220b42808080801054410020024188066a41086a290300501b450d04200ba7450d05200241f8056a2029202b428094ebdc03420010fc04200241e8056a20022903f805220e200241f8056a41086a290300220f4280ec94a37c427f10fb04200241d8056a200e200f201b42ffffffff0f83428094ebdc037e200b42ffffffff0f838042ffffffff0f83220b420010fb0420022903d805220e200b202920022903e8057c7e428094ebdc038042ffffffff0f837c221a200e54ad210b200241d8056a41086a290300210e024020022802ec10450d002005102e0b200e200b7c210b0b200241c0056a2010201a20287c220e200b202a7c200e201a54ad7c10ea03200241e80d6a20022903c00520022903c805200241c0056a41106a29030010a601427f202220122903007c202020022903e80d7c220e2020542201ad7c220b2001200b202254200b2022511b22011b2122427f200e20011b21200b200d41046a210d201041206a22102024470d010c040b0b10b403000b10b503000b41a4f1c2001058000b02402016450d002014102e0b200241e0106a2022370300200241c8106a41106a2020370300200241c8106a41086a41003a0000200241033a00c81041c8ecc5004100200241c8106a1072200241a8056a41c28cc00041161070200241a8056a41106a290300210b20022903b005210e20022802a8052101200241a80c6a41086a22034200370300200242003703a80c41c28cc0004116200241a80c6a1003200241e80d6a41086a2003290300370300200220022903a80c3703e80d2002427f200b420020011b220b20227c200e420020011b220e20207c220f200e542201ad7c220e2001200e200b54200e200b511b22011b3703d0102002427f200f20011b3703c810200241e80d6a4110200241c8106a4110100402402020202284500d00201f201e84500d00200241e00b6a41086a22014200370300200242003703e00b41c28cc0004116200241e00b6a1003200241e80d6a41086a2001290300370300200220022903e00b3703e80d20024190056a200241e80d6a109701200229039805420020022802900522011b220b201f7d220f200b56200241a0056a290300420020011b220e201e7d200b201f54ad7d220b200e56200b200e511b0d0020024180056a200f200b201f201e10fc04200241d0046a20024180056a41086a290300220b42002020420010fb04200241e0046a20224200200229038005220e420010fb04200241f0046a200e42002020420010fb04200b42005220224200527120022903d8044200527220022903e80442005272200241f0046a41086a290300220b20022903d00420022903e0047c7c220e200b54720d0020022903f004210b200241e00b6a41086a22014200370300200242003703e00b41c28cc0004116200241e00b6a1003200241e80d6a41086a22072001290300370300200220022903e00b3703e80d200241b8046a200241e80d6a109701200241b8046a41106a290300210f20022903c004211a20022802b804210320014200370300200242003703e00b41c28cc0004116200241e00b6a100320072001290300370300200220022903e00b3703e80d2002427f200f420020031b220f200e7c200b201a420020031b221a7c221c201a542203ad7c221b2003201b200f54201b200f511b22031b3703d0102002427f201c20031b3703c810200241e80d6a4110200241c8106a41101004200241c8106a108701200241a8046a200241c8106a201a427f85200b20031b220b200f427f85200e20031b220f106d200241a8046a41086a290300211a20022903a804210e20024190046a41c28cc00041161070200b200e7d200e200b7d200e200b58201a200f58201a200f5122031b220d1b211d200f201a7d200b200e54ad7d201a200f7d200e200b54ad7d200d1b212120024190046a41106a2903004200200228029004220d1b211b2002290398044200200d1b211c02400240200e200b56201a200f5620031b0d0020074200370300200242003703e80d41c28cc0004116200241e80d6a100320012007290300370300200220022903e80d3703e00b20024200201b20217d201c201d54ad7d220b201c201d7d220e201c56200b201b56200b201b511b22011b3703f00d20024200200e20011b3703e80d200241e80d6a21010c010b200241a80c6a41086a22034200370300200242003703a80c41c28cc0004116200241a80c6a100320012003290300370300200220022903a80c3703e00b2002427f201b20217c201c201d7c220e201c542201ad7c220b2001200b201b54200b201b511b22011b3703f00d2002427f200e20011b3703e80d200241e80d6a21010b200241e00b6a41102001411010040b410121152019450d002018102e0b20024188046a41e49ac5004112107d2002280288042101200228028c042103200c4200370300200242003703a80c41e49ac5004112200241a80c6a10032017200c290300370300200220022903a80c3703e80d2002200341016a410120011b22233602c810200241e80d6a4110200241c8106a4104100420024180046a41f69ac5004123107d200c4200370300200242003703a80c41f69ac5004123200241a80c6a10032017200c290300370300200220022903a80c3703e80d200220043602c810200241e80d6a4110200241c8106a41041004024002400240024002400240024002400240024002400240024002400240202341a105490d00200241a80c6a41086a22014200370300200242003703a80c41c29bc5004112200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241003602c810200241e80d6a4110200241c8106a1008211702400240024002400240024020022802c8102218417f460d002017450d00200220183602cc10200220173602c810200241f8036a200241c8106a103120022802f8030d1820022802cc1022104178712201417f4c0d1220022802fc0321080240024002400240201041037622240d00410421050c010b200110292205450d010b02402008450d00410021114100210d410021070340200241003602e00b02400240024020104104490d0020022010417c6a22103602cc10200220022802c810220141046a3602c81020012800002112200241003602e00b20104104490d00200741016a210320022010417c6a22103602cc102002200141086a3602c8102001280004210120072024470d022011200320032011491b222441ffffffff01712024470d202024410374220c41004e0d010c200b2024450d1e2005102e0c1e0b0240024020070d00200c102921050c010b2005200d200c102a21050b2005450d040b2005200d6a22072012360200200741046a2001360200201141026a2111200d41086a210d2003210720082003470d000b0b2005450d1a02402018450d002017102e0b20082024470d040c030b20014104102c000b200c4104102c000b41002108410421050b200841016a22012008490d1720084101742203200120012003491b222441ffffffff01712024470d17202441037422014100480d170240024020080d002001102921050c010b200520084103742001102a21050b2005450d010b202341e07a6a2103200520084103746a22012004360204200120233602002005200841016a221141037422076a210d410021010240200741194f0d00200521070c020b20052110024003402010220728020020034f0d040240200741086a2802002003490d00200141016a21010c050b0240200741106a2802002003490d00200141026a21010c050b200741186a28020020034f0d01200141046a2101200d200741206a22106b41184b0d000b200741206a21070c020b200141036a21010c020b20014104102c000b2007200d460d000340200728020020034f0d01200141016a2101200d200741086a2207470d000b0b0240024002400240024020112001490d00201120016b2211450d0402402001450d002005200520014103746a201141037410f7041a0b20052802042108200241a80c6a41086a22014200370300200242003703a80c41a5dfc5004113200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241c8106a200241e80d6a411010c601024020022802c8104101470d000240200241c8106a41086a280200220c2008200c2008491b221220022802cc1022034f0d00200321120c050b0240200320124f0d000340411a10292201450d04200141186a41002f00f482403b0000200141106a41002900ec8240370000200141086a41002900e48240370000200141002900dc82403700002001411a4134102a2201450d052001200336001a200241f00a6a41186a22074200370300200241f00a6a41106a220d4200370300200241f00a6a41086a22104200370300200242003703f00a2001411e200241f00a6a1000200241900b6a41186a2007290300370300200241900b6a41106a200d290300370300200241900b6a41086a2010290300370300200220022903f00a3703900b200241900b6a412010062001102e200341016a2201210320122001470d000b0b200c20084b0d040b200241a80c6a41086a22014200370300200242003703a80c41a5dfc5004113200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241e80d6a411010060c040b418cc6c5001058000b411a4101102c000b41344101102c000b200241a80c6a41086a22014200370300200242003703a80c41a5dfc5004113200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d410810292201450d022001200c36000420012012360000200241e80d6a41102001410810042001102e0b200241a80c6a41086a22014200370300200242003703a80c41c29bc5004112200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241003602d010200242013703c8102011200241c8106a10470240024020110d0020022802d010210120022802cc10210720022802c81021030c010b200520114103746a2104410020022802d01022116b210d20022802cc102107410021010340201120016a2110200520016a22122802002108024002402007200d6a4104490d0020022802c81021030c010b201041046a22032010490d162007410174220c20032003200c491b220c4100480d160240024020070d00200c102921030c010b20022802c8102007200c102a21030b2003450d052002200c3602cc10200220033602c810200c21070b2002201041046a220c3602d010200320116a20016a2008360000201241046a280200210802402007200d6a417c6a41034b0d00200c41046a2223200c490d162007410174220c20232023200c491b220c4100480d160240024020070d00200c102921030c010b20032007200c102a21030b2003450d062002200c3602cc10200220033602c810200c21070b2002201041086a3602d010200320116a20016a41046a2008360000200d41786a210d200141086a2101201241086a2004470d000b201120016a21010b200241e80d6a411020032001100402402007450d002003102e0b2024450d002005102e0b200241f0036a41989ac5004116107d20022802f403212f20022802f0032130200241e8036a41ae9ac500411d107d20022802ec03213120022802e8032132200241f00a6a41186a22034200370300200241f00a6a41106a22074200370300200241f00a6a41086a220d4200370300200242003703f00a41f8e8c300411a200241f00a6a1000200241e80d6a41186a22102003290300370300200241e80d6a41106a22112007290300370300200241e80d6a41086a2212200d290300370300200220022903f00a3703e80d200241c8106a200241e80d6a412010dc01412810292201450d03200141c8ecc500360200200120022903c810370204200120022f00e00b3b00252001410c6a200241c8106a41086a290300370200200141146a200241c8106a41106a2903003702002001411c6a200241c8106a41186a290300370200200141246a200241c8106a41206a2d00003a0000200141276a200241e00b6a41026a22052d00003a00002003420037030020074200370300200d4200370300200242003703f00a41dee8c300411a200241f00a6a100020102003290300370300201120072903003703002012200d290300370300200220022903f00a3703e80d200241c8106a200241e80d6a412010dc01412810292233450d04203341c8ecc500360200203320022903c810370204203320022f00e00b3b00252033410c6a200241c8106a41086a2203290300370200203341146a200241c8106a41106a22072903003702002033411c6a200241c8106a41186a220d290300370200203341246a200241c8106a41206a22102d00003a0000203341276a20052d00003a0000200242003702bc0d200241e08dc0003602b80d200241003602d80d200242083703d00d200241e80c6a411c6a200241b80d6a360200200241e80c6a41186a200241e00d6a360200200241003602f80c200241d0bcc4003602ec0c200220013602e80c2002200241d00d6a3602fc0c2002200241e00d6a3602f40c2002200241e00d6a3602f00c200241c8106a200241e80c6a10810202400240024020022d00881122114102470d00200241023a00a80e0c010b200241a80c6a41386a2212200241c8106a41386a290300370300200241a80c6a41306a2205200241c8106a41306a290300370300200241a80c6a41286a2208200241c8106a41286a290300370300200241a80c6a41206a220c2010290300370300200241a80c6a41186a2210200d290300370300200241a80c6a41106a220d2007290300370300200241a80c6a41086a22072003290300370300200241900b6a41086a220320024191116a22232900003703002002419f0b6a222420024198116a290000370000200220022903c8103703a80c20022002290089113703900b20024184116a2012290300370200200241fc106a2005290300370200200241f4106a2008290300370200200241ec106a200c290300370200200241e4106a2010290300370200200241dc106a200d290300370200200241d4106a2007290300370200200241013602f80c200220022903a80c3702cc10200241e00b6a200241c8106a41c40010f6041a200241003602c810200241c8106a410472200241e00b6a41c40010f6041a200241c8106a41c8006a20113a0000202320022903900b37000020024199116a2003290300370000200241a0116a2024290000370000200241e80d6a200241e80c6a41146a200241c8106a10c20320022d00a80e4102470d010b2001102e41082134410021354108210541082118410021080c0b0b200241c8106a200110eb0341c80010292234450d052034200241e80d6a41c80010f6041a200241880d6a41186a200241e80c6a41186a290300370300200241880d6a41106a200241e80c6a41106a290300370300200241880d6a41086a200241e80c6a41086a290300370300200220022903e80c3703880d200241c8106a200241880d6a108102024020022d00881122054102470d0041012108410121350c090b200241c8106a41046a210120024191116a210d200241c8106a41047221362002419c0d6a213720024189116a211020022802980d21384102211141c8002107410021034101213502400340200241a80c6a41386a2212200241c8106a41386a290300370300200241a80c6a41306a2208200241c8106a41306a290300370300200241a80c6a41286a220c200241c8106a41286a290300370300200241a80c6a41206a2223200241c8106a41206a290300370300200241a80c6a41186a2224200241c8106a41186a290300370300200241a80c6a41106a2204200241c8106a41106a290300370300200241a80c6a41086a2217200241c8106a41086a290300370300200241900b6a41086a2218201041086a290000370300200241900b6a410f6a22192010410f6a290000370000200220022903c8103703a80c200220102900003703900b200141386a2012290300370200200141306a2008290300370200200141286a200c290300370200200141206a2023290300370200200141186a2024290300370200200141106a2004290300370200200141086a2017290300370200200120022903a80c3702002002203820036a221241016a3602980d200241e00b6a200241c8106a41c40010f6041a200220123602c8102036200241e00b6a41c40010f6041a200d20022903900b370000200d41086a2018290300370000200d410f6a2019290000370000200220053a009011200241e80d6a2037200241c8106a10c20320022d00a80e4102460d01200241c8106a200241e80d6a41c80010f6041a0240200341016a22122035470d00200241e00b6a20022802880d200228028c0d280210110000201241016a22052012490d152011200520052011491b2235ad42c8007e220b422088a70d15200ba722054100480d15024002402003417f470d002005102921340c010b203420072005102a21340b2034450d090b203420076a200241c8106a41c80010f6041a201141026a2111200741c8006a2107200241c8106a200241880d6a1081022012210320022d00881122054102460d090c000b0b200341016a2108203421050c090b41084101102c000b200c4101102c000b200c4101102c000b41284104102c000b41284104102c000b41c8004108102c000b20054108102c000b201241016a21080b20342105200241023a00a80e0b20022802880d2203200228028c0d220128020011010002402001280204450d002003102e0b200521180b200241e80d6a203310d603024020022802880e2236450d00200241e00b6a41017221370240024002400240034020022802900e2124200228028c0e2138200241880d6a41186a2239200241e80d6a41186a290300370300200241880d6a41106a223a200241e80d6a41106a290300370300200241880d6a41086a223b200241e80d6a41086a290300370300200220022903e80d3703880d200241e00b6a200241880d6a108202024002400240024020022d00e00b4101460d00200241003602e8100c010b200241a80c6a41186a203741186a290000370300200241a80c6a41106a203741106a290000370300200241a80c6a41086a203741086a290000370300200220372900003703a80c200241c8106a200241a80c6a10830220022802e81022010d010b4200211b4200211c0c010b200241c8106a41186a290300211c20022903d810211b20022802ec10450d002001102e0b2024ad42c8007e220b422088a70d06200ba72201417f4c0d0602400240024020010d00410821170c010b200110292217450d010b02400240202441057422010d00410021230c010b203620016a2119410021232036210403402004221041206a2104200241b80d6a210120022802bc0d2112024003402001280200221141086a210320112f0106220c4105742101410021070240024003402001450d0120102003412010f804220d450d02200141606a2101200741016a2107200341206a2103200d417f4a0d000b2007417f6a210c0b2012450d022012417f6a21122011200c4102746a4194036a21010c010b0b2008201120074102746a41e8026a220128020022034d0d052005200341c8006c6a2203290310210b200341186a290300210e200241d0036a41c28cc00041161070200241c0036a20022903d803200241d0036a41106a290300427f420010fc042008200128020022034d0d06200241b0036a201b201c20022903c003420020022802d00322071b220f4201200f420156200241c0036a41086a290300420020071b220f420052200f501b22071b200f420020071b10fc042005200341c8006c6a220341186a427f200e200b20022903b0037c220f200b542207ad7c221a2007201a200e54200f200b5a1b22071b3703002003427f200f20071b370310200241900b6a41186a2203201041186a290000370300200241900b6a41106a2207201041106a290000370300200241900b6a41086a220d201041086a290000370300200220102900003703900b20012802002110024020242023470d00202441016a22012024490d1220244101742211200120012011491b2201ad42c8007e220b422088a70d12200ba722114100480d120240024020240d002011102921170c010b2017202441c8006c2011102a21170b2017450d08200121240b2017202341c8006c6a2201420037030020012010360220200141186a4200370300200141106a4200370300200141086a4200370300200120022903900b3702242001412c6a200d290300370200200141346a20072903003702002001413c6a2003290300370200202341016a21230b20042019470d000b0b200241f00a6a41186a22012039290300370300200241f00a6a41106a2203203a290300370300200241f00a6a41086a2207203b290300370300200220022903880d3703f00a20024198036a41c28cc0004116107020024188036a20022903a00320024198036a41106a290300427f420010fc04200241f8026a201b201c2002290388034200200228029803220d1b220b4201200b42015620024188036a41086a2903004200200d1b220b420052200b501b220d1b200b4200200d1b10fc04200241e80c6a41086a220d2007290300370300200241e80c6a41106a22072003290300370300200241e80c6a41186a22032001290300370300200220022903f00a3703e80c20022903f802210b02402038450d002036102e0b2017450d06200241c8106a41186a22102003290300370300200241c8106a41106a22112007290300370300200241c8106a41086a2207200d290300370300200220022903e80c3703c810024020022802d80d220320022802d40d470d00200241e80d6a203310eb0320022802d40d220120022802d80d220d6b417f20022802e80d221241016a220c200c2012491b22124f0d00200d20126a2212200d490d0f2001410174220d20122012200d491b220dad42d0007e220e422088a70d0f200ea722124100480d0f0240024020010d002012102921010c010b20022802d00d200141d0006c2012102a21010b2001450d062002200d3602d40d200220013602d00d0b20022802d00d200341d0006c6a22012017360220200120022903c81037022c200141286a2023360200200141246a202436020020014200370310200142003703082001200b370300200141186a4200370300200141346a20072903003702002001413c6a2011290300370200200141c4006a20102903003702002002200341016a3602d80d200241e80d6a203310d60320022802880e22360d010c060b0b20014108102c000b41849ec300200320081038000b41b4f5c200200320081038000b20114108102c000b20124108102c000b2033102e0240024020082031410420321b22014101200141014b1b4f0d0002402035450d002034102e0b024020022802d80d2201450d00200141d0006c210320022802d00d41206a210103400240200141046a280200450d002001280200102e0b200141d0006a2101200341b07f6a22030d000b0b024020022802d40d0d00410021370c020b20022802d00d102e410021370c010b2008202f410020301b220120082001491b223a41ffffff3f71203a470d01203a4105742201417f4c0d01024002400240024020010d00410121370c010b200110292237450d010b203aad422c7e220b422088a70d03200ba72201417f4c0d0302400240024020010d00410421320c010b200110292232450d010b0240203a0d00410021314100213c0c030b2005200841c8006c22386a2104200241c8106a41186a2119200241c8106a41106a2136200241c8106a41086a213341002117203a213c034002402008450d002038210103400240201841c0006a2d00000d00200241e8026a427f427f201841106a290300220b4201200b420156201841186a290300220b420052200b501b22031b200b420020031b10fc042018200241e8026a41086a290300370308201820022903e8023703000b201841c8006a2118200141b87f6a22010d000b0b20022802d00d220d20022802d80d220c41d0006c6a2124024002400240024002400240200c450d00200d21100340024020102802282201450d00200141c8006c2107201028022041206a210103402008200128020022034d0d0402402005200341c8006c6a22032d00400d002003290310220e200341186a290300220f84500d00200241d8026a2010290300220b4200428080808010420010fb04200241a8026a42004200200b420010fb04200241c8026a427f20022903d802201041086a290300220b42ffffffff0f83200b5220022903b00242005272200241d8026a41086a290300221a200b42208620022903a8027c7c220b201a547222111b427f200b20111b200e200f10fc04200241b8026a201041146a350200201041186a290300220b42208684200b42208820022903c802200241c8026a41086a29030010fb042003427f2003290300220b20022903b8027c220e200e200b542211200341086a2212290300220b200241b8026a41086a2903007c2011ad7c220e200b54200e200b511b22111b3703002012427f200e20111b3703000b200141c8006a2101200741b87f6a22070d000b0b201041d0006a22102024470d000b0b201741016a21312005200841c8006c6a2110203821032005210103402001210702400240201020016b41d8014d0d00200741c0006a2d00000d01200741c8006a21010c070b0340024020030d00201721310c0c0b200341b87f6a2103200741c0006a2111200741c8006a2201210720112d00000d000b200141b87f6a21070c060b20074188016a2d0000450d03200741d0016a2d0000450d02200341e07d6a2103200741a0026a210120074198026a2d00000d000b410321030c030b41b4f5c200200320081038000b200741d8016a2101410221030c010b20074190016a2101410121030b2007200341c8006c6a21070b024020012010460d00200741086a290300210b2007290300210e0340200141c8006a21030240200141c0006a2d00000d00200141086a290300220f200b2001290300221a200e54200f200b54200f200b511b22101b210b201a200e20101b210e2001200720101b21070b2003210120042003470d000b0b200741013a00400240200c450d002007417c6a2112200741206a210c0340200d41d0006a21230240200d2802282203450d00200d2802202101200341c8006c210303400240024020122001460d00200141246a200c412010f8040d010b200d41186a2210290300210b200741086a2211290300210e20012007290300220f200d290310221a7d3703002001200e200b7d200f201a54ad7d3703082007290300210b20102011290300370300200d200b3703100b200141c8006a2101200341b87f6a22030d000b0b2023210d20232024470d000b0b2019200741386a2900003703002036200741306a2900003703002033200741286a290000370300200220072900203703c81002400240203c2017470d0020174101742201203120312001491b223c41ffffff3f71203c470d0e203c41057422014100480d0e0240024020170d002001102921370c010b203720174105742001102a21370b2037450d010b203720174105746a220120022903c810370000200141186a2019290300370000200141106a2036290300370000200141086a203329030037000020052118203121172031203a4f0d040c010b0b20014101102c000b20014104102c000b20014101102c000b0240024020022802d80d22010d004100213b0c010b20022802d00d2233200141d0006c6a212f410020376b213d2037203141057422396a210c4100213b0340200220332f002c3b01e80d20022033412e6a2d00003a00ea0d20022033413f6a2900003703c8102002203341c4006a2900003700cd10024020332802282201450d002033412c6a211820332802202224200141c8006c6a21382033413b6a2800002130203341376a280000213e203341336a280000213f2033412f6a28000021402024203d6a41246a21044100211941082136410021170240024003402024221141046a2112201141246a2103201141646a2105201141446a2108201141c8006a21242039210d20042110203721010240024003400240024002400240200c20016b41e0004d0d0020032001460d0220012003412010f8040d01200121070c050b0340200d450d06024002402010450d004100210720012003412010f8040d010b200121070b200141206a2101200d41606a210d201041606a21102007450d000c050b0b20122001460d00200141206a22072003412010f804450d0320052001460d00200141c0006a22072003412010f804450d0320082001470d010b200321070c020b200141e0006a2107200d41807f6a210d201041807f6a211020014180016a2223210120072003412010f8040d000b202341606a21070b20182007460d0020072018412010f804450d00024002402033290310221a2011290300220e85203341186a290300220f201141086a290300220b858450450d004200210b428080808010210e0c010b20024198026a200e4200428080808010420010fb0420024188026a42004200200e420010fb040240200b42ffffffff0f83200b522002290390024200527220024198026a41086a290300221b200b4220862002290388027c7c221c201b54724101470d000240201a422088200f42208684221a200f422088220f84500d00200241e8016a200e200b201a200f10fc04200241e8016a41086a290300210b20022903e801210e0c020b41a899c3001058000b200241f8016a200229039802201c201a4201201a420156200f420052200f501b22011b200f420020011b10fc04200241f8016a41086a290300210b20022903f801210e0b2011200e370310201141186a200b370300200220112f00243b01c00b2002201141266a2d00003a00c20b2002201141376a2900003703b00b20022011413c6a2900003700b50b201141336a28000021032011412f6a28000021072011412b6a280000210d201141276a2800002110024020192017470d00201941016a22012019490d1020194101742211200120012011491b2201ad42307e220f422088a70d10200fa722114100480d100240024020190d002011102921360c010b2036201941306c2011102a21360b2036450d03200121190b20022d00c20b211120022f01c00b21122036201741306c6a2201200336000f2001200736000b2001200d36000720012010360003200120123b0100200141026a20113a00002001200e370320200141286a200b370300200120022903b00b370013200141186a20022900b50b370000201741016a21170b200441c8006a210420242038470d000b02402017450d0002400240201741306c22030d004200210b4200210e0c010b203641206a21014200210b4200210e0340200141086a290300200e7c2001290300220e200b7c220b200e54ad7c210e200141306a2101200341506a22030d000b0b200241d8016a4200428080808010200b7d220f200f428080808010564200200e200b42808080801056ad7c7d220b420052200b501b22011b221b4200200b20011b220b2017ad221c420010fc0420022903d801210f0240201b201c544100200b501b0d00200241d8016a41086a290300211a203641206a21012017210303402001427f2001290300220b200f7c220e200e200b542207200141086a220d290300220b201a7c2007ad7c220e200b54200e200b511b22071b370300200d427f200e20071b370300200141306a21012003417f6a22030d000b0b200241c8016a200f200b201c200b10fb040240201b20022903c8017da7220d450d004100210103402036200120177041306c6a2203427f2003290320220b42017c220e200e200b542207200341286a2203290300220f2007ad7c221a200f54200e200b5a1b22071b3703202003427f201a20071b370300200141016a2201200d490d000b0b200220022f01e80d3b01dc0b200220022d00ea0d3a00de0b200220022903c8103703c80b200220022900cd103700cd0b0240203a203b470d00203a41016a2201203a490d0f203a4101742203200120012003491b2201ad422c7e220b422088a70d0f200ba722034100480d0f02400240203a0d002003102921320c010b2032203a412c6c2003102a21320b2032450d032001213a0b20022d00de0b210320022f01dc0b21072032203b412c6c6a2201203036000f2001203e36000b2001203f36000720012040360003200120073b0100200141026a20033a0000200120022903c80b370013200141186a20022900cd0b370000200120173602282001201936022420012036360220203b41016a213b0c030b2019450d022036102e0c020b20114108102c000b20034104102c000b203341d0006a2233202f470d000b0b02402035450d002034102e0b024020022802d80d2201450d00200141d0006c210320022802d00d41206a210103400240200141046a280200450d002001280200102e0b200141d0006a2101200341b07f6a22030d000b0b20022802d40d450d0020022802d00d102e0b20022802c00d211120022802b80d2103024020022802bc0d2201450d00034020032802940321032001417f6a22010d000b0b02402011450d00410021074100210103402011417f6a211102400240200120032f01064f0d00200141016a21010c010b02400240200328020022010d002007ad210b4100210d410021010c010b20033301044220862007ad84210b4101210d0b2003102e200ba7210702400240200b422088a7221020012f01064f0d00200121030c010b034002400240200128020022030d002007ad210b410021030c010b200d41016a210d20013301044220862007ad84210b0b2001102e200ba7210720032101200b422088a7221020032f01064f0d000b0b201041027420036a4198036a28020021030240200d417f6a2201450d00034020032802940321032001417f6a22010d000b0b410021010b20110d000b0b0240200341e08dc000460d00200328020021012003102e2001450d00200128020021032001102e2003450d00024020032802002201450d0003402003102e2001210320012802002207210120070d000b0b2003102e0b024020370d00200241086a41a5bcc400411110700c030b203b412c6c2201412c6e214141002118024002400240024020010d0041082142410021410c010b204141ffffff1f712041470d0a204141067422034100480d0a200310292242450d010b024002402032203220016a2238460d00200241e80d6a410172211141002118204221232032210c0340200241f00a6a41186a2219200c41186a290200370300200241f00a6a41106a2236200c41106a290200370300200241f00a6a41086a2233200c41086a2902003703002002200c2902003703f00a200241e80d6a200c108202024002400240024020022d00e80d4101460d00200241003602e8100c010b200241e00b6a41186a201141186a290000370300200241e00b6a41106a201141106a290000370300200241e00b6a41086a201141086a290000370300200220112900003703e00b200241c8106a200241e00b6a10830220022802e81022010d010b4200211c4200211d0c010b200241c8106a41186a290300211d20022903d810211c20022802ec10450d002001102e0b200c280220210d4100211002400240200c280228222441306c22120d0041082117410021240c010b202441ffffff1f712024470d0d202441067422014100480d0d200110292217450d030b200c412c6a21040240200d200d20126a460d0041002110201721010340200d220341286a290300210e200341206a290300210b200241e80d6a200c108202024002400240024020022d00e80d4101460d00200241003602e8100c010b200241e00b6a41186a201141186a290000370300200241e00b6a41106a201141106a290000370300200241e00b6a41086a201141086a290000370300200220112900003703e00b200241c8106a200241e00b6a10830220022802e81022070d010b4200211a4200211b0c010b200241c8106a41186a290300211b20022903d810211a20022802ec10450d002007102e0b200341306a210d200241a80c6a41086a22074200370300200242003703a80c41c28cc0004116200241a80c6a1003200241e80d6a41086a22052007290300370300200220022903a80c3703e80d200241b0016a200241e80d6a10970120024188016a20022903b801200241b0016a41106a290300427f420010fc04200241e8006a201a201b200229038801420020022802b00122081b220f4201200f42015620024188016a41086a290300420020081b220f420052200f501b22081b200f420020081b10fc0420074200370300200242003703a80c41c28cc0004116200241a80c6a100320052007290300370300200220022903a80c3703e80d20024198016a200241e80d6a109701200241f8006a20022903a00120024198016a41106a290300427f420010fc04200241386a200e42002002290368220f420010fb04200241d8006a200b4200200f420010fb04200241286a42004200200b420010fb04200241c8006a2002290378420020022802980122071b220f4201200f420156200241f8006a41086a290300420020071b220f420052200f501b22071b200f420020071b427f200235025c200241d8006a41086a290300221a200229033820022903287c7c220f422086842002290340200229033084420052200f201a547222071b42ffffffff0f200f42208820071b10fb042001200e3703082001200b370300200141106a2003290300370300200141186a200341086a290300370300200141206a200341106a290300370300200141286a200341186a290300370300200141386a200241c8006a41086a290300370300200141306a2002290348370300200141c0006a2101201041016a2110201241506a22120d000b0b2023201c3703002023201d37030820232017360230202341386a2010360200202341346a2024360200202320022903f00a370310202341186a2033290300370300202341206a2036290300370300202341286a2019290300370300201841016a2118202341c0006a21232004210c20042038470d000b0b200242003702c40a200241e08dc0003602c00a0240203720314105746a22392037460d00200241c8106a4102722143200241f00a6a41136a212f200241900b6a41136a2144200241e80d6a410172210c203721050340200241e80d6a2005108202024002400240024020022d00e80d4101460d00200241003602e8100c010b200241e00b6a41186a200c41186a290000370300200241e00b6a41106a200c41106a290000370300200241e00b6a41086a200c41086a2900003703002002200c2900003703e00b200241c8106a200241e00b6a10830220022802e81022010d010b4200210b4200210e0c010b200241c8106a41186a290300210e20022903d810210b20022802ec10450d002001102e0b200241e00b6a41186a2223200541186a290000370300200241e00b6a41106a2224200541106a290000370300200241e00b6a41086a2204200541086a290000370300200220052900003703e00b0240024002400240024002400240024020022802c00a221041e08dc000460d0020022802c40a21110c010b200241e80d6a410041e00210f5041a200241c8106a410041900410f5041a41f80610292210450d0141002111201041003b010620104100360200201041086a200241e80d6a41e00210f6041a201041e8026a200241c8106a41900410f6041a200241003602c40a200220103602c00a0b200541206a210502400340201041086a2103201041066a210820102f010622124105742101410021070240024003402001450d01200241e00b6a2003412010f804220d450d02200141606a2101200741016a2107200341206a2103200d417f4a0d000b2007417f6a21120b2011450d022011417f6a2111201020124102746a41f8066a28020021100c010b0b2010200741306c6a22014180036a200e370300200141f8026a200b370300200141f0026a200e370300200141e8026a200b37030020014190036a410036020020014188036a220728020021032001418c036a2802002101200742083703002003450d062001450d062003102e0c060b200241e80c6a41186a22012023290300370300200241e80c6a41106a2024290300220f370300200241e80c6a41086a2004290300221a370300200220022903e00b221b3703e80c200220022802c80a41016a3602c80a200241a80c6a41106a223f200f370300200241a80c6a41086a2240201a370300200241a80c6a41186a223420012903003703002002201b3703a80c20082f01002203410b490d03200241e80d6a410041e00210f5041a200241c8106a410041900410f5041a41f80610292201450d01200141003b010620014100360200200141086a200241e80d6a41e00210f6042107200141e8026a200241c8106a41900410f604210d200241900b6a41086a2245201041d0016a290000370300200241900b6a41106a2246201041d8016a290000370300200241900b6a41186a2247201041e0016a290000370300200241c8106a41086a221720104190056a290300370300200241c8106a41106a221920104198056a290300370300200241c8106a41186a2236201041a0056a290300370300200241c8106a41206a2233201041a8056a290300370300200241c8106a41286a2238201041b0056a290300370300200220102900c8013703900b20022010290388053703c8102007201041e8016a20102f010641796a220341057410f6042107200d201041b8056a200341306c10f604210d201041063b0106200120033b0106200220022f01900b3b01dc0b200220022d00920b3a00de0b200220442900003703c80b2002204441056a22482900003700cd0b20022800930b214920022800970b214a200228009b0b214b200228009f0b214c200241e80d6a41286a224d2038290300370300200241e80d6a41206a224e2033290300370300200241e80d6a41186a224f2036290300370300200241e80d6a41106a22502019290300370300200241e80d6a41086a22512017290300370300200220022903c8103703e80d0240024020124107490d00201241057420076a41c07e6a2007201241796a22114105746a2207200341ffff037120116b41057410f7041a200741186a2034290300370000200741106a203f290300370000200741086a2040290300370000200720022903a80c370000201241306c200d6a220341e07d6a200341b07d6a2203200141066a22082f010020116b41306c10f7041a200341186a200e3703002003200b3703102003200e3703082003200b370300200341286a4100360200200342083703200c010b201041086a20124105746a220341206a200320082f010020126b41057410f7041a200341186a2034290300370000200341106a203f290300370000200341086a2040290300370000200320022903a80c370000201041e8026a201241306c6a220341306a200320082f010020126b41306c10f7041a200341186a200e3703002003200b3703102003200e3703082003200b370300200341286a4100360200200342083703200b200820082f010041016a3b0100200241d00d6a41026a220320022d00de0b3a000020042051290300370300202420502903003703002023204f290300370300200241e00b6a41206a223d204e290300370300200241e00b6a41286a2235204d290300370300200220022f01dc0b3b01d00d200220022903c80b3703f00a200220022900cd0b3700f50a200220022903e80d3703e00b200241880d6a41286a22522035290300370300200241880d6a41206a2253203d290300370300200241880d6a41186a22542023290300370300200241880d6a41106a22552024290300370300200241880d6a41086a22562004290300370300200220022903e00b3703880d200220022f01d00d3b01c00b200220032d00003a00c20b200220022903f00a3703b00b200220022900f50a3700b50b0240201028020022110d00200241c00a6a2103200121070c050b20102f0104213041002157200121580340200241e00d6a41026a225920022d00c20b3a0000200220022f01c00b3b01e00d200220022903b00b3703d00d200220022900b50b3700d50d20352052290300370300203d2053290300370300202320542903003703002024205529030037030020042056290300370300200220022903880d3703e00b203041ffff0371211202400240024020112f01062201410b490d002043410041a20710f5041a41a8071029220d450d06200d4100360200200d41046a200241c8106a41a40710f6041a2047201141e0016a2900003703002046201141d8016a2900003703002045201141d0016a290000370300200220112900c8013703900b2038201141b0056a2903003703002033201141a8056a2903003703002036201141a0056a290300370300201920114198056a290300370300201720114190056a29030037030020022011290388053703c810200d41086a201141e8016a20112f0106220341796a220141057410f604215a200d41e8026a201141b8056a200141306c10f604215b200d41f8066a20114194076a2003417a6a220841027410f604213e201141063b0106200d20013b010602402008450d0041002101203e210303402003280200220720013b01042007200d360200200341046a21032008200141016a2201470d000b0b204d2038290300370300204e2033290300370300204f20362903003703002050201929030037030020512017290300370300200220022903c8103703e80d200220022f01900b3b01dc0b200220022d00920b3a00de0b20022900930b210b200229009b0b210e200220482900003700cd0b200220442900003703c80b202f20022903c80b370000202f41056a220820022900cd0b370000200220022d00de0b3a00f20a200220022f01dc0b3b01f00a2002200e3700fb0a2002200b3700f30a2038204d2903003703002033204e2903003703002036204f2903003703002019205029030037030020172051290300370300200220022903e80d3703c810203041ffff037122034107490d01205a2012417a6a22074105746a205a201241796a22014105746a2203200d2f010620016b41057410f7041a200341186a20022900d50d3700002003204c36000f2003204b36000b2003204a36000720032049360003200341026a20592d00003a0000200320022f01e00d3b0000200320022903d00d370013201241306c205b6a220341e07d6a200341b07d6a2203200d2f0106223020016b41306c10f7041a200341286a2035290300370300200341206a203d290300370300200341186a2023290300370300200341106a2024290300370300200341086a2004290300370300200320022903e00b370300200d203041016a22033b010620124102742230203e6a416c6a203e20074102746a2212200341ffff037120076b41027410f7041a201220583602002007200d2f010622124b0d02200d20306a41e0066a2103034020032802002207200141016a22013b01042007200d360200200341046a210320012012490d000c030b0b201141086a2203201241016a22074105746a200320124105746a2203200120126b220d41057410f7041a2003204c36000f2003204b36000b2003204a36000720032049360003200341026a20592d00003a0000200320022f01e00d3b0000200320022903d00d370013200341186a20022900d50d3700002011201241306c6a22034198036a200341e8026a2208200d41306c10f7041a20034190036a203529030037030020034188036a203d29030037030020034180036a2023290300370300200341f8026a2024290300370300200341f0026a2004290300370300200820022903e00b3703002011200141016a22013b01062012410274201141f8066a22036a41086a200320074102746a2203200141ffff037120076b41027410f7041a200320583602000240201220112f010622014f0d00205820073b010420582011360200200720014f0d002001417f6a210d20112007417f6a22014102746a4180076a2103034020032802002207200141026a3b010420072011360200200341046a2103200d200141016a2201470d000b0b41001a200241c00a6a1a20101a0c080b201141086a2201201241016a22074105746a200120124105746a220120112f0106223020126b223e41057410f7041a2001204c36000f2001204b36000b2001204a36000720012049360003200141026a20592d00003a0000200120022f01e00d3b0000200120022903d00d370013200141186a20022900d50d370000201141e8026a201241306c6a220141306a2001203e41306c10f7041a200141286a2035290300370300200141206a203d290300370300200141186a2023290300370300200141106a2024290300370300200141086a2004290300370300200120022903e00b3703002011203041016a22013b01062012410274223e201141f8066a22306a41086a203020074102746a2230200141ffff037120076b41027410f7041a20302058360200200320112f010622074f0d002011203e6a41fc066a2101034020012802002203201241016a22123b010420032011360200200141046a210120072012470d000b0b205741016a2112200241cc0d6a41026a220120022d00f20a3a000020402017290300370300203f201929030037030020342036290300370300200241a80c6a41206a22032033290300370300200241a80c6a41286a22072038290300370300200220022f01f00a3b01cc0d200220022903c8103703a80c2002202f2900003703b80d200220082900003700bd0d20022800f30a214920022800f70a214a20022800fb0a214b20022800ff0a214c2052200729030037030020532003290300370300205420342903003703002055203f29030037030020562040290300370300200220022903a80c3703880d200220022f01cc0d3b01c00b200220012d00003a00c20b200220022903b80d3703b00b200220022900bd0d3700b50b0240201128020022010d0020111a200241c00a6a22031a200d21070c060b20112f01042130200241c00a6a1a20111a20012111200d2158201221570c000b0b41f8064108102c000b41f8064108102c000b41a8074108102c000b201020124105746a220141286a200141086a2207200320126b41057410f7041a200141206a2034290300370000200141186a203f290300370000200141106a2040290300370000200720022903a80c3700002010201241306c6a22014198036a200141e8026a220320102f010620126b41306c10f7041a20014190036a410036020020014188036a420837030020014180036a200e370300200141f8026a200b370300200141f0026a200e3703002003200b370300201020102f010641016a3b01060c010b2043410041a20710f5041a024041a80710292201450d0020014100360200200141046a200241c8106a41a40710f6041a20012003280200220d3602f806200320013602002003200328020441016a360204200d41003b0104200d2001360200200120012f0106220d4105746a220341086a20022f01c00b3b00002003410a6a20022d00c20b3a0000200341176a204c360000200341136a204b3600002003410f6a204a3600002003410b6a20493600002003411b6a20022903b00b370000200341206a20022900b50b3700002001200d41306c6a220341e8026a20022903880d370300200341f0026a2056290300370300200341f8026a205529030037030020034180036a205429030037030020034188036a205329030037030020034190036a2052290300370300200141f8066a200d41016a22034102746a2007360200200120033b0106200720033b01042007200136020020101a0c010b41a8074108102c000b20052039470d000b0b20184106742201450d02204220016a21172042210403402004450d030240024020042802382201450d002004280230222320014106746a2124200441106a210c03402023220841106a2110200841c0006a2123200241c00a6a210120022802c40a2112024003402001280200221141086a210320112f010622054105742101410021070240024003402001450d0120102003412010f804220d450d02200141606a2101200741016a2107200341206a2103200d417f4a0d000b2007417f6a21050b2012450d022012417f6a2112201120054102746a41f8066a21010c010b0b2011200741306c6a220141e8026a2203427f2003290300220b20082903307c220e200e200b542203200141f0026a2207290300220b200841386a220d2903007c2003ad7c220e200b54200e200b511b22031b3703002007427f200e20031b370300200241c8106a41086a2210200c41086a290000370300200c290000210b200241c8106a41106a2211200c41106a290000370300200241c8106a41186a2212200c41186a2900003703002002200b3703c810200d290300210b2008290330210e20014188036a210d0240024020014190036a220728020022032001418c036a280200460d00200d28020021010c010b200341016a22012003490d1020034101742205200120012005491b2205ad42307e220f422088a70d10200fa722084100480d100240024020030d002008102921010c010b200d280200200341306c2008102a21010b2001450d04200d2001360200200d41046a2005360200200728020021030b2001200341306c6a2201200b3703082001200e370300200120022903c810370310200141186a2010290300370300200141206a2011290300370300200141286a20122903003703002007200728020041016a3602000b20232024470d000b0b200441c0006a22042017470d010c040b0b20084108102c000b20014108102c000b20034108102c000b200241a80c6a41086a22014200370300200242003703a80c4192e9c3004116200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241003602c810200241e80d6a4110200241c8106a100821030240024020022802c8102207417f460d002003450d00200220073602e40b200220033602e00b200241c8106a200241e00b6a1030024020022802c8102204450d00200241d0106a280200210120022802cc1021172007450d022003102e0c020b41eff0c2004133200241e00d6a4184f4c2001053000b4100211741012104410021010b02400240024002402001450d002001410574210c200421100340410f10292201450d04200141002900a2e843370000200141076a41002900a9e8433700002002428f808080f0013702cc10200220013602c8102010200241c8106a104a20022802cc10210820022802d010211120022802c810210d200241f00a6a41186a22014200370300200241f00a6a41106a22034200370300200241f00a6a41086a22074200370300200242003703f00a200d2011200241f00a6a1000200241e80d6a41186a22112001290300370300200241e80d6a41106a22122003290300370300200241e80d6a41086a22052007290300370300200220022903f00a3703e80d200241e80d6a4120100602402008450d00200d102e0b41121029220d450d03200d41002900cce843220b370000200d41106a41002f00dce84322243b0000200d41086a41002900d4e843220e37000020024292808080a0023702cc102002200d3602c8102010200241c8106a104a20022802cc10212320022802d010210820022802c810210d200142003703002003420037030020074200370300200242003703f00a200d2008200241f00a6a1000201120012903003703002012200329030037030020052007290300370300200220022903f00a3703e80d200241206a200241e80d6a4120109a012002280224410020022802201b210802402023450d00200d102e0b024020084102490d0041121029220d450d03200d200b370000200d41106a20243b0000200d41086a200e37000020024292808080a0023702cc102002200d3602c8102010200241c8106a104a20022802cc10212320022802d010212420022802c810210d200142003703002003420037030020074200370300200242003703f00a200d2024200241f00a6a1000201120012903003703002012200329030037030020052007290300370300200220022903f00a3703e80d20022008417f6a3602c810200241e80d6a4120200241c8106a410410042023450d00200d102e0b201041206a2110200c41606a220c0d000b0b02402017450d002004102e0b20022802c00a210d024020022802c40a2201450d00200121030340200d2802f806210d2003417f6a22030d000b03402001417f6a22010d000b0b024020022802c80a22050d00427f210f427f210b0c050b02400240200d2f0106450d00200d41e8026a2110200d41086a2111410121120c010b02400240200d28020022010d004100210741002103410021010c010b200d2f01042107410121030b0240200720012f0106490d000340200341016a210320012f01042207200128020022012f01064f0d000b0b2001200741306c6a41e8026a2110200120074105746a41086a2111200741027420016a41fc066a280200210d410021122003417f6a2201450d000340200d2802f806210d2001417f6a22010d000b0b200241c8106a41106a210c427f210f427f210b0340201041086a2201290300210e2010290300211a200241e00b6a41186a201141186a290000370300200241e00b6a41106a201141106a290000370300200241e00b6a41086a201141086a290000370300200220112900003703e00b20102802282211ad42307e221b422088a70d04201ba72203417f4c0d04201041186a290300211b2001290300211c2010290310211d20102903002121201028022021010240024002400240024020030d00410821080c010b200310292208450d010b0240024020110d00410021070c010b2001201141306c6a211041002107200821030340200320012903003703002003200141086a290300370308200341106a200141106a290300370300200341186a200141186a290300370300200341206a200141206a290300370300200341286a200141286a290300370300200341306a2103200741016a2107200141306a22012010470d000b0b200241c8106a41186a201b3703002002201d3703d810200220213703c810200220073602f010200220113602ec10200220083602e8102002201c3703d010410f10292201450d01200141002900a2e843370000200141076a41002900a9e8433700002002428f808080f0013702ec0d200220013602e80d200241e00b6a200241e80d6a104a20022802ec0d211020022802f00d210120022802e80d2107200241f00a6a41186a22034200370300200241f00a6a41106a22114200370300200241f00a6a41086a22084200370300200242003703f00a20072001200241f00a6a1000200241e80d6a41186a2003290300370300200241e80d6a41106a2011290300370300200241e80d6a41086a2008290300370300200220022903f00a3703e80d200241003602b00c200242013703a80c2002200241c8106a3602880d200241880d6a200241a80c6a106b2002200c3602880d200241880d6a200241a80c6a106b20022802e810210120022802f0102203200241a80c6a104702402003450d00200341306c21030340200141106a200241a80c6a104a200220013602880d200141306a2101200241880d6a200241a80c6a106b200341506a22030d000b0b20022802ac0c2101200241e80d6a412020022802a80c220320022802b00c100402402001450d002003102e0b201a200f542101200e200b512103200e200b54211102402010450d002007102e0b2001201120031b21012005417f6a2105024020022802ec10450d0020022802e810102e0b200e200b20011b210b201a200f20011b210f2005450d0802402012200d2f01064f0d00200d201241306c6a41e8026a2110200d20124105746a41086a2111201241016a21120c040b02400240200d28020022010d004100210741002103410021010c010b200d2f01042107410121030b200720012f0106490d020340200341016a210320012f01042207200128020022012f01064f0d000c030b0b20034108102c000b410f4101102c000b2001200741306c6a41e8026a2110200120074105746a41086a2111200741027420016a41fc066a280200210d410021122003417f6a2201450d000340200d2802f806210d2001417f6a22010d000c010b0b0b41124101102c000b41124101102c000b410f4101102c000b1032000b200241a80c6a41086a22014200370300200242003703a80c41a5bcc4004111200241a80c6a1003200241e80d6a41086a22032001290300370300200220022903a80c3703e80d2002200b3703d0102002200f3703c810200241e80d6a4110200241c8106a4110100420014200370300200242003703a80c4192e9c3004116200241a80c6a100320032001290300370300200220022903a80c3703e80d200241003602d010200242013703c8102031200241c8106a104702402031450d00203720314105746a21032037210103402001200241c8106a104a2003200141206a2201470d000b0b20022802cc102101200241e80d6a411020022802c810220320022802d010100402402001450d002003102e0b20022802c80a211220022802c00a2107024020022802c40a2201450d00034020072802f80621072001417f6a22010d000b0b02402012450d004100210d41002101034002400240200120072f01064f0d002007200141306c6a2203418c036a280200211120034188036a2802002103200141016a21010c010b02400240200728020022010d00200dad210b41002110410021010c010b2007330104422086200dad84210b410121100b2007102e200ba7210d02400240200b422088a7221120012f01064f0d00200121030c010b034002400240200128020022030d00200dad210b410021030c010b201041016a21102001330104422086200dad84210b0b2001102e200ba7210d20032101200b422088a7221120032f01064f0d000b0b201141027420036a41fc066a28020021072003201141306c6a2201418c036a280200211120014188036a280200210302402010417f6a2201450d00034020072802f80621072001417f6a22010d000b0b410021010b2003450d012012417f6a211202402011450d002003102e0b20120d000b0b0240200741e08dc000460d00200728020021012007102e2001450d00200128020021032001102e2003450d00024020032802002201450d0003402003102e2001210320012802002207210120070d000b0b2003102e0b02402018450d0020184106742103204241306a210103400240200141046a280200450d002001280200102e0b200141c0006a2101200341406a22030d000b0b2031ad210b02402041450d002042102e0b200b422086210b203cad210e0240203b450d00203b412c6c2103203241206a210103400240200141046a280200450d002001280200102e0b2001412c6a2101200341546a22030d000b0b200b200e84210b203a450d002032102e0b02402016452015720d002014102e0b20370d010240200a450d00200a41d0006c2103201341c0006a210103400240200141046a280200450d002001280200102e0b200141d0006a2101200341b07f6a22030d000b0b2009450d002006102e0b200041003602000c010b2000200b370204200020373602000240200a450d00200a41d0006c2103201341c0006a210103400240200141046a280200450d002001280200102e0b200141d0006a2101200341b07f6a22030d000b0b2009450d002006102e0b200241f0176a24000f0b41eff0c2004133200241e00d6a4184f4c2001053000b102d000b02000b280020004101360204200041086a200128020420012802006b4107762201360200200020013602000ba50201057f230041d0006b21020240200128020022032001280204470d00200041003602000f0b200120034180016a3602002002200329004237012a2002200329004a370132200241086a41086a220120022903303703002002200329005237013a200241086a41106a220420022903383703002002200328005a360142200220032f005e3b0146200241086a41186a22052002290340370300200220032f00403b012820022002290328370308200241286a41186a22062005290300370300200241286a41106a22052004290300370300200241286a41086a220420012903003703002002200229030837032820002003360200200020022903283702042000410c6a2004290300370200200041146a20052903003702002000411c6a20062903003702000bb905020b7f047e23004190016b22032400024002402001280200220420012802042205460d00200120044180016a22063602002003200441c2006a29000037016a2003200441ca006a290000370172200341c8006a41086a220720032903703703002003200441d2006a29000037017a200341c8006a41106a220820032903783703002003200441da006a280000360182012003200441de006a2f00003b018601200341c8006a41186a22092003290380013703002003200441c0006a2f00003b016820032003290368370348200341286a41186a220a2009290300370300200341286a41106a220b2008290300370300200341286a41086a220c200729030037030020032003290348370328200541807f6a210d02400340200341086a41186a200a290300220e370300200341086a41106a200b290300220f370300200341086a41086a200c2903002210370300200320032903282211370308200341e8006a41186a200e370300200341e8006a41106a200f370300200341e8006a41086a2010370300200320113703682002450d01200d2004460d02200120064180016a22053602002003200641c2006a29000037016a2003200641ca006a290000370172200720032903703703002003200641d2006a29000037017a200820032903783703002003200641da006a280000360182012003200641de006a2f00003b01860120092003290380013703002003200641c0006a2f00003b016820032003290368370348200a2009290300370300200b2008290300370300200c20072903003703002003200329034837032820044180016a21042002417f6a2102200521060c000b0b20002004360200200020032903683702042000410c6a200341f0006a290300370200200041146a200341f8006a2903003702002000411c6a20034180016a2903003702000c010b200041003602000b20034190016a24000b130020004101360204200041bc93c2003602000b3400200041c594c20036020420004100360200200041146a4103360200200041106a41d094c200360200200041086a420a3702000bd10801037f024002400240024002400240024002400240410110292202450d00200220002d00003a0000200241014102102a2202450d01200220002d00013a0001200241024104102a2202450d02200220002d00023a0002200220002d00033a0003200241044108102a2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102a2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102a2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f2002412041c000102a2202450d06200220002d00203a0020200220002d00213a0021200220002d00223a0022200220002d00233a0023200220002d00243a0024200220002d00253a0025200220002d00263a0026200220002d00273a0027200220002d00283a0028200220002d00293a0029200220002d002a3a002a200220002d002b3a002b200220002d002c3a002c200220002d002d3a002d200220002d002e3a002e200220002d002f3a002f200220002d00303a0030200220002d00313a0031200220002d00323a0032200220002d00333a0033200220002d00343a0034200220002d00353a0035200220002d00363a0036200220002d00373a0037200220002d00383a0038200220002d00393a0039200220002d003a3a003a200220002d003b3a003b200220002d003c3a003c200220002d003d3a003d200220002d003e3a003e200220002d003f3a003f02400240200141046a2802002203200141086a28020022006b41c000490d00200128020021030c010b200041c0006a22042000490d0920034101742200200420042000491b22004100480d090240024020030d002000102921030c010b200128020020032000102a21030b2003450d0820012003360200200141046a2000360200200141086a28020021000b200141086a200041c0006a360200200320006a220041386a200241386a290000370000200041306a200241306a290000370000200041286a200241286a290000370000200041206a200241206a290000370000200041186a200241186a290000370000200041106a200241106a290000370000200041086a200241086a290000370000200020022900003700002002102e0f0b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000b41c0004101102c000b20004101102c000b102d000b0a0041c498c2001058000b5201027e024002402003450d002002280200450d010b41c8a6c30041f403109b01000b2001280218220342002003290308220420023502047d2205200520045622021b37030820004105410420021b3602000bc80d06047f027e027f017e027f027e230041c00c6b22042400024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320022802042105200241246a2802002106200241346a28020021030240200241146a2802002207450d0041052102200128020028021828023c2802bc012003490d080b200441306a4200370300200441286a4200370300200441206a420037030020012802182202420020022903082208427f20012802102903482209420586200942ffffffffffffffff07832009521b7d22092009200856220a1b3703082004420037031841052102200a0d070240024020012802142802082005200441186a4120102241026a220a41024b0d00200a0e03090001090b41fcd4c5001058000b024002400240024020070d00410121034100210b0c010b200441086a200128021029034842002003ad220c420010fb042001280218220a4200200a2903082209427f200429030820042903104200521b7d22082008200956220a1b370308200a0d0a2003417f4c0d070240024020030d004101210b02402001280214280208200641014100102241026a220341024b0d0020030e030d00020d0b41fcd4c5001058000b024020031034220b450d00024020012802142802082006200b2003102241026a220341024b0d0020030e03040002040b41fcd4c5001058000b20034101102c000b200c422086200c842109200b4521030b20012802002101200441386a41186a220a200441186a41186a290300370300200441386a41106a2205200441186a41106a290300370300200441386a41086a2206200441186a41086a290300370300200420042903183703382001280218210720030d01200728023c2802bc012009422088a74f0d012009a7450d090b200b102e0c080b200441d8006a41186a200a290300370300200441d8006a41106a2005290300370300200441d8006a41086a20062903003703002004200429033837035820072802140d052007417f36021420044198016a41186a200741e4006a290000370300200441a8016a200741dc006a290000370300200441a0016a200741d4006a2900003703002004200729004c3703980102400240200741186a220d280200220a41e08dc000460d002007411c6a28020021060c010b41002106200441e0096a410041e00210f5041a200441c0016a410041a00810f5041a41880b1029220a450d07200a41003b0106200a4100360200200a41086a200441e0096a41e00210f6041a200a41e8026a200441c0016a41a00810f6041a2007411c6a41003602002007200a3602180b024002400340200a2f0106220e410574210541002102410021030240034020052002460d0120044198016a200a20026a41086a412010f8042201450d03200241206a2102200341016a21032001417f4a0d000b2003417f6a210e0b02402006450d002006417f6a2106200a200e4102746a41880b6a280200210a0c010b0b200441f8006a41186a20044198016a41186a2903002208370300200441f8006a41106a20044198016a41106a290300220c370300200441f8006a41086a20044198016a41086a290300220f37030020042004290398012210370378200441fc096a200f370200200441840a6a200c3702002004418c0a6a20083702002004200741206a3602f0092004200e3602ec092004200d3602e8092004200a3602e409200441003602e009200420103702f409200441f4016a4200370200200441fc016a41003a0000200441e08dc0003602f001200442003703d801200442003703c001200441e0096a200441c0016a104f21020c010b200441d8016a4200370300200441d4016a41e08dc000360200200441003602e001200441003602d001200442003703c801200441e08dc0003602c401200441003602c001200a200341e0006c6a41e8026a2102200441c0016a10ee010b200441c0016a41186a200441d8006a41186a290300370300200441c0016a41106a200441d8006a41106a290300370300200441c0016a41086a200441d8006a41086a290300370300200420042903583703c0012004200937029c012004200b36029801200441e0096a200241306a200441c0016a20044198016a10f501024020042802e009450d0020042802e4092202450d00200441e8096a280200450d002002102e0b2007200728021441016a360214410421020c070b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000b41aed9c1004110200441c0016a41c0d9c1001053000b41880b4108102c000b20002002360200200441c00c6a24000b950302017f027e230041c0006b22042400024002402003450d0020022802000d0020022802042103200441186a4200370300200441106a4200370300200441086a420037030020012802182202420020022903082205427f20012802102903482206420586200642ffffffffffffffff07832006521b7d2206200620055622021b3703082004420037030002400240024020020d00024002402001280214280208200320044120102241026a220241024b0d0020020e03020001020b41fcd4c5001058000b200441206a2001280200280218220241146a200241cc006a200241086a410020022802081b200410f2012004280220450d01200441306a41086a200441206a41086a28020036020020042004290320370330200141046a21020240200141086a280200450d002002280200102e0b20022004290330370200200241086a200441306a41086a280200360200410021010c020b200041053602000c030b2001410c6a4100360200410121010b20004100360200200020013602040c010b41c8a6c30041f403109b01000b200441c0006a24000b880e06017f017e057f027e037f027e230041d0016b220424000240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042103200241286a2903002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200441286a20012802102903484200200241146a280200220aad420010fb042001280218220242002002290308220b427f200429032820042903304200521b7d220c200c200b5622021b370308024002400240024020020d00200a417f4c0d0b02400240024002400240200a0d004101210d02402001280214280208200341014100102241026a220241024b0d00200141146a210e20020e03060002060b41fcd4c5001058000b0240200a1034220d450d00024020012802142802082003200d200a102241026a220241024b0d00200141146a210e20020e03030002030b41fcd4c5001058000b200a4101102c000b41002102200441003a00b80102400340200a2002460d0120044198016a20026a200d20026a2d00003a00002004200241016a22033a00b8012003210220034120470d000b200441f8006a41186a220220044198016a41186a290300370300200441f8006a41106a220320044198016a41106a290300370300200441f8006a41086a220f20044198016a41086a29030037030020042004290398013703780240200a450d00200d102e0b200441386a41086a200f290300370300200441386a41106a2003290300370300200441386a41186a200229030037030020042004290378370338200441186a200128021029034842002007ad420010fb042001280218220242002002290308220b427f200429031820042903204200521b7d220c200c200b5622021b37030820020d042007417f4c0d0f20070d03200e280200280208200641014100102241026a220241024b0d0220020e03040204040b0240200241ff0171450d00200441003a00b8010b200a450d030b200d102e0c020b41fcd4c5001058000b024002400240200710342202450d000240200e280200280208200620022007102241026a220341024b0d0020030e03030002030b41fcd4c5001058000b20074101102c000b2007410f4d0d00200241086a2900002110200229000021112002102e200441086a200128021029034842002009ad420010fb042001280218220242002002290308220b427f200429030820042903104200521b7d220c200c200b5622021b37030820020d01200141046a220a20091036024002402001280214280208200820012802042001410c6a280200102241026a220241024b0d0020020e03030001030b41fcd4c5001058000b200128020c21032001410036020c200141086a280200210d20012802042107200142013702042001280218220241086a2206290300220c210b024002400240024002402005500d002005210b200c2005540d010b2006200c200b7d3703002002290310210c200441f8006a41186a200241186a2903003703002004200b370380012004200b3703782004200c370388012001280200280218210620044198016a41186a200441386a41186a29030037030020044198016a41106a200441386a41106a29030037030020044198016a41086a200441386a41086a2903003703002004200429033837039801200420033602c8012004200d3602c401200420073602c001200441d8006a200620044198016a20112010200441f8006a200441c0016a105a4101210d20042802584101460d01200441d8006a41106a2d00002103200441e4006a2802002107200441e0006a28020021064100210d200428025c21090c020b200420033602a0012004200d36029c01200420073602980120044198016a21020c020b200441ec006a2802002107200441d8006a41106a2802002106200441e4006a2802002109410021030b200241086a220220042903800120022903007c370300200141086a28020021020240200d0d0002402002450d00200a280200102e0b2001200736020c20012009360204200141086a20063602000c060b200420073602a0012004200636029c01200420093602980120020d0320044198016a21020b200120022902003702042001410036020c0c030b2002102e0b200041053602000c0b0b2001280204102e20012004290398013702042001410036020c0b41800221030b20004100360200200020033602040c080b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000b200441d0016a24000ba00f07017f017e057f027e037f027e017f230041e0016b220424000240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042103200241286a2903002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200441206a20012802102903484200200241146a280200220aad420010fb042001280218220242002002290308220b427f200429032020042903284200521b7d220c200c200b5622021b370308024002400240024020020d00200a417f4c0d0b02400240024002400240200a0d004101210d02402001280214280208200341014100102241026a220241024b0d00200141146a210e20020e03060002060b41fcd4c5001058000b0240200a1034220d450d00024020012802142802082003200d200a102241026a220241024b0d00200141146a210e20020e03030002030b41fcd4c5001058000b200a4101102c000b41002102200441003a00c80102400340200a2002460d01200441a8016a20026a200d20026a2d00003a00002004200241016a22033a00c8012003210220034120470d000b20044188016a41186a2202200441a8016a41186a29030037030020044188016a41106a2203200441a8016a41106a29030037030020044188016a41086a220f200441a8016a41086a290300370300200420042903a801370388010240200a450d00200d102e0b200441306a41086a200f290300370300200441306a41106a2003290300370300200441306a41186a20022903003703002004200429038801370330200441106a200128021029034842002007ad420010fb042001280218220242002002290308220b427f200429031020042903184200521b7d220c200c200b5622021b37030820020d042007417f4c0d0f20070d03200e280200280208200641014100102241026a220241024b0d0220020e03040204040b0240200241ff0171450d00200441003a00c8010b200a450d030b200d102e0c020b41fcd4c5001058000b024002400240200710342202450d000240200e280200280208200620022007102241026a220341024b0d0020030e03030002030b41fcd4c5001058000b20074101102c000b2007410f4d0d00200241086a2900002110200229000021112002102e2004200128021029034842002009ad420010fb042001280218220242002002290308220b427f200429030020042903084200521b7d220c200c200b5622021b37030820020d01200141046a220320091036024002402001280214280208200820012802042001410c6a280200102241026a220241024b0d0020020e03030001030b41fcd4c5001058000b200128020c210a2001410036020c200141086a280200210d20012802042107200142013702042001280218220241086a2206290300220c210b0240024002402005500d002005210b200c2005540d010b2006200c200b7d3703002002290310210c20044188016a41186a200241186a2903003703002004200b370390012004200b370388012004200c37039801200128020028021821062004200a3602582004200d36025420042007360250200441a8016a20062011201020044188016a200441306a200441d0006a104d4101210a0240024020042802a8014101460d00200441d0006a41086a200441a8016a41186a290300370300200441d0006a41106a200441c8016a2802003602002004200441a8016a41106a290300370350200441d8016a2d00002109200441d0016a2802002108200441cc016a280200210e200441b4016a280200210d200441a8016a41086a28020021074100210a20042802ac0121060c010b200441bc016a280200210d200441b8016a2802002107200441b4016a2802002106410021090b200441f0006a41086a220f200441d0006a41086a290300370300200441f0006a41106a2212200441d0006a41106a280200360200200241086a220220042903900120022903007c370300200420042903503703700240200a0d00200441bc016a200f290300370200200441c4016a20122802003602002004200d3602b001200420073602ac01200420063602a801200420042903703702b4010240200141086a280200450d002003280200102e0b2001410036020c2001200e360204200141086a2008360200200941ff017122020d07200441a8016a2003104a0c070b200141086a28020021022004200d3602b001200420073602ac01200420063602a80120020d04200441a8016a21020c010b2004200a3602b0012004200d3602ac01200420073602a801200441a8016a21020b200120022902003702042001410036020c0c030b2002102e0b200041053602000c0b0b2001280204102e200120042903a8013702042001410036020c0b41800221020b20004100360200200020023602040c080b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000b200441e0016a24000b990303027f037e017f230041206b22042400024002402003450d0020022802000d0020034101460d0120022802100d0120022802042103200441106a20012802102903184200200241146a2802002205ad2206420010fb0420012802182202420020022903082207427f200429031020042903184200521b7d2208200820075622021b370308024020020d002004200128021029034842002006420010fb0420012802182202420020022903082207427f200429030020042903084200521b7d2208200820075622021b37030820020d00200141046a20051036024002402001280214280208200320012802042001410c6a280200102241026a220241024b0d0020020e03020001020b41fcd4c5001058000b200128020c21022001410036020c200141086a280200210320012802042105200142013702040240200128021c2209450d00200141206a280200450d002009102e0b2001200536021c200141246a2002360200200141206a20033602000b20004105360200200441206a24000f0b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b22002001410c6a4100360200200128020041206a200141046a104a200041043602000b26002001410c6a4100360200200128020028021841cc006a200141046a104a200041043602000bd50102027f027e410021042001410c6a41003602002001280218220541186a2903002106200529031021070240024002400240200141086a28020022054110490d00200128020421050c010b200541017422044110200441104b1b22044100480d020240024020050d002004102921050c010b200128020420052004102a21050b2005450d0120012005360204200141086a20043602002001410c6a28020021040b2001410c6a200441106a360200200520046a2201200637000820012007370000200041043602000f0b20044101102c000b102d000bc50103017f017e017f410021042001410c6a4100360200200128021841086a29030021050240024002400240200141086a28020022064108490d00200128020421060c010b200641017422044108200441084b1b22044100480d020240024020060d002004102921060c010b200128020420062004102a21060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441086a360200200620046a2005370000200041043602000f0b20044101102c000b102d000b9c04020b7f027e230041206b220424002001410c6a41003602000240024002402001280200280218220528021441016a220641004c0d00200541cc006a210720052006360214200541186a21082005411c6a28020021090240024003402008280200220a41086a210b200a2f0106220c41057421084100210d0240024003402008450d012007200b412010f804220e450d02200841606a2108200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a210c0b2009450d022009417f6a2109200a200c4102746a41880b6a21080c010b0b200a200d41e0006c6a220841e8026a280200450d00200841f8026a290300210f200841f0026a29030021100c010b200441086a200541246a2802002007200541286a28020028021c110300200441106a290300210f20052802142106200429030821100b20052006417f6a36021402400240200141086a280200220b2001410c6a28020022086b4110490d002001280204210b0c010b200841106a220d2008490d03200b4101742208200d200d2008491b22084100480d0302400240200b0d0020081029210b0c010b2001280204200b2008102a210b0b200b450d022001200b360204200141086a20083602002001410c6a28020021080b2001410c6a200841106a360200200b20086a2208200f3700082008201037000020004104360200200441206a24000f0b41e3d7c1004118200441186a41fcd7c1001053000b20084101102c000b102d000bd50102027f027e410021042001410c6a41003602002001280200220541086a2903002106200529030021070240024002400240200141086a28020022054110490d00200128020421050c010b200541017422044110200441104b1b22044100480d020240024020050d002004102921050c010b200128020420052004102a21050b2005450d0120012005360204200141086a20043602002001410c6a28020021040b2001410c6a200441106a360200200520046a2201200637000820012007370000200041043602000f0b20044101102c000b102d000bf80202047f027e230041306b220424000240024002402003450d0020022802000d0020034101460d0120022802100d01410521050240200241146a28020022032001280210220628026c4b0d00200228020421072004200629034842002003ad420010fb0420012802182202420020022903082208427f200429030020042903084200521b7d2209200920085622021b37030820020d002003417f4c0d0302400240024020030d004101210202402001280214280208200741014100102241026a220641024b0d0020060e03040002040b41fcd4c5001058000b0240200310342202450d0002402001280214280208200720022003102241026a220641024b0d0020060e03030002030b41fcd4c5001058000b20034101102c000b2001410c6a4100360200200441106a2002200310bd0241042105200441106a200141046a10462003450d010b2002102e0b20002005360200200441306a24000f0b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000bc20103017f017e017f410021042001410c6a4100360200200128020029031021050240024002400240200141086a28020022064108490d00200128020421060c010b200641017422044108200441084b1b22044100480d020240024020060d002004102921060c010b200128020420062004102a21060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441086a360200200620046a2005370000200041043602000f0b20044101102c000b102d000bb40803027f047e027f230041e0046b2204240002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200441286a20012802102903484200200241146a2802002202ad420010fb0420012802182203420020032903082206427f200429032820042903304200521b7d2207200720065622031b3703080240024020030d002002417f4c0d0402400240024020020d004101210302402001280214280208200541014100102241026a220541024b0d0020050e03040002040b41fcd4c5001058000b0240200210342203450d0002402001280214280208200520032002102241026a220541024b0d0020050e03030002030b41fcd4c5001058000b20024101102c000b2004200236023c20042003360238200441d0036a200441386a10b801024020042d00d00322054113460d00200441c8026a200441d0036a41017241870110f6041a02402002450d002003102e0b200441c0016a200441c8026a41870110f6041a200420053a0038200441386a410172200441c0016a41870110f6041a200441003602d803200442013703d003200441386a200441d0036a10bc0120042802d8032103024020042802d403450d0020042802d003102e0b200128021822022903102206200241186a2903002207844200510d07200441186a2003ad42004280c8afa025420010fb04200441086a200429031822084280a094a58d1d7c2209200441186a41086a2903002009200854ad7c2006200710fc0420024200200229030822062004290308427f200441086a41086a290300501b7d220720072006561b37030820072006580d03200441386a102f0c020b2002450d010b2003102e0b410521020c070b20012802002102200441c8026a200441386a41880110f6041a200441c0016a41086a2002280218220241d4006a290000370300200441d0016a2203200241dc006a290000370300200441d8016a2205200241e4006a2900003703002004200229004c3703c001200441d7036a200441c8026a41880110f6041a0240200241386a2802002201200241346a280200470d00200141016a220a2001490d062001410174220b200a200a200b491b220aad42b0017e2206422088a70d062006a7220b4100480d060240024020010d00200b102921010c010b2002280230200141b0016c200b102a21010b2001450d0520022001360230200241346a200a360200200228023821010b2002280230200141b0016c6a220141013a0000200120042903c001370001200141096a200441c8016a290300370000200141116a2003290300370000200141196a2005290300370000200141216a200441d0036a418f0110f6041a2002200228023841016a360238410421020c060b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000b41c8a5c3001058000b200b4108102c000b102d000b20002002360200200441e0046a24000b911705087f027e037f027e057f230041a0026b22042400024002400240024002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620034107460d0720022802700d0720022802042103200241246a2802002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200241f4006a280200210a200441206a20012802102903484200200241146a280200220bad420010fb042001280218220242002002290308220c427f200429032020042903284200521b7d220d200d200c5622021b3703080240024020020d00200b417f4c0d0a024002400240200b0d004101210e02402001280214280208200341014100102241026a220241024b0d00200141146a210f20020e03040002040b41fcd4c5001058000b0240200b1034220e450d00024020012802142802082003200e200b102241026a220241024b0d00200141146a210f20020e03030002030b41fcd4c5001058000b200b4101102c000b41002102200441003a00f00102400340200b2002460d01200441d0016a20026a200e20026a2d00003a00002004200241016a22033a00f0012003210220034120470d000b20044180026a41086a2202200441d0016a41086a29030037030020044180026a41106a2203200441d0016a41106a29030037030020044180026a41186a2210200441d0016a41186a290300370300200420042903d001370380020240200b450d00200e102e0b200441306a41086a2002290300370300200441306a41106a2003290300370300200441306a41186a20102903003703002004200429038002370330200441106a200128021029034842002006ad420010fb042001280218220242002002290308220c427f200429031020042903184200521b7d220d200d200c5622021b3703082002450d030c100b0240200241ff0171450d00200441003a00f0010b200b450d010b200e102e0b200441f0006a41186a20044180026a41186a290300370300200441f0006a41106a20044180026a41106a290300370300200441f0006a41086a20044180026a41086a2903003703002004200429038002370370410521020c0e0b2006417f4c0d080240024002400240024020060d004101210b0240200f280200280208200541014100102241026a220241024b0d0020020e03120002120b41fcd4c5001058000b024020061034220b450d000240200f2802002802082005200b2006102241026a220241024b0d0020020e03030002030b41fcd4c5001058000b20064101102c000b41002102200441003a00f0010240034020062002460d01200441d0016a20026a200b20026a2d00003a00002004200241016a22033a00f0012003210220034120470d000b20044180026a41086a2202200441d0016a41086a29030037030020044180026a41106a2203200441d0016a41106a29030037030020044180026a41186a220e200441d0016a41186a290300370300200420042903d0013703800202402006450d00200b102e0b200441d0006a41086a2002290300370300200441d0006a41106a2003290300370300200441d0006a41186a200e29030037030020042004290380023703502004200128021029034842002008ad420010fb042001280218220242002002290308220c427f200429030020042903084200521b7d220d200d200c5622031b3703084105210220030d112008417f4c0d0c20080d03200f280200280208200741014100102241026a220341024b0d0220030e03110211110b0240200241ff0171450d00200441003a00f0010b2006450d0f0b200b102e410521020c0f0b41fcd4c5001058000b02400240024002400240200810342203450d000240200f280200280208200720032008102241026a220b41024b0d00200b0e03030002030b41fcd4c5001058000b20084101102c000b2008410f4d0d00200341086a2900002111200329000021122003102e024002400240200a0d004101210e4100210b0c010b20044180026a41186a210620044180026a41106a210520044180026a41086a21084100211041002102410021034100210b4101210e03402006420037030020054200370300200842003703002001280218220742002007290308220d427f2001280210290348220c420586200c42ffffffffffffffff0783200c521b7d220c200c200d5622071b370308200442003703800220070d1102400240200f280200280208200920026a221320044180026a4120102241026a220741024b0d0020070e03130001130b41fcd4c5001058000b200341016a2107200441d0016a41186a22142006290300370300200441d0016a41106a22152005290300370300200441d0016a41086a2216200829030037030020042004290380023703d00102402003200b470d002010200720072010491b220b41ffffff3f71200b470d03200b41057422174100480d030240024020030d0020171029210e0c010b200e20022017102a210e0b200e450d110b200e20026a220320042903d001370000200341186a2014290300370000200341106a2015290300370000200341086a2016290300370000201341206a2013490d11201041026a2110200241206a210220072103200a2007470d000b0b2001280200280218210320044190016a41086a200441306a41086a29030037030020044190016a41106a2201200441306a41106a29030037030020044190016a41186a2206200441306a41186a290300370300200441b0016a41086a200341d4006a290000370300200441b0016a41106a2205200341dc006a290000370300200441b0016a41186a2208200341e4006a29000037030020042004290330370390012004200329004c3703b00120044180026a41186a2207200441d0006a41186a29030037030020044180026a41106a2209200441d0006a41106a29030037030020044180026a41086a200441d0006a41086a2903003703002004200429035037038002200341386a2802002202200341346a280200470d03200241016a220f2002490d0020024101742210200f200f2010491b220fad42b0017e220c422088a70d00200ca7221041004e0d020b102d000b2003102e0c0f0b0240024020020d002010102921020c010b2003280230200241b0016c2010102a21020b2002450d0a20032002360230200341346a200f360200200328023821020b2003280230200241b0016c6a220241023a0000200220042903b0013700012002200429039001370021200241096a200441b0016a41086a290300370000200241116a2005290300370000200241196a2008290300370000200241296a20044190016a41086a290300370000200241316a2001290300370000200241396a20062903003700002002200e3600642002200b3600682002200a36006c20022012370370200241f8006a20113703002002200429038002370041200241c9006a20044180026a41086a290300370000200241d1006a2009290300370000200241d9006a2007290300370000200220042f00703b0061200241e3006a200441f0006a41026a2d00003a0000200220042903d0013703800120024188016a200441d0016a41086a29030037030020024190016a200441d0016a41106a29030037030020024198016a200441d0016a41186a290300370300200241a0016a200441f0016a290300370300200241a8016a200441f8016a2903003703002003200328023841016a360238410421020c0d0b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000b20104108102c000b20174101102c000b41052102200b450d01200e102e0c010b410521020b20002002360200200441a0026a24000b16002000410036020020002001410c6a2802003602040bae0202057f027e230041106b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d024105210302402001410c6a2802002205200241146a2802002206490d00200520066b200241246a2802002205470d0020022802042107200128020421082004200128021029035042002005ad420010fb0420012802182202420020022903082209427f200429030020042903084200521b7d220a200a20095622021b37030820020d000240024020012802142802082007200820066a2005102341026a220241024b0d0020020e03020001020b418cd6c5001058000b410421030b20002003360200200441106a24000f0b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000bf80102037f027e230041106b22042400024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200420012802102903484200200241146a2802002206ad420010fb0420012802182202420020022903082207427f200429030020042903084200521b7d2208200820075622031b37030841052102024020030d00200141046a20061036024002402001280214280208200520012802042001410c6a280200102241026a220141024b0d0020010e03020001020b41fcd4c5001058000b410421020b20002002360200200441106a24000f0b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000bbe0b05047f027e037f017e037f230041e0016b2204240002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d03200241246a2802002105200241346a280200210602400240024002400240200241146a2802002203450d0020022802042107200441306a200128021029034842002003ad420010fb0420012802182202420020022903082208427f200429033020042903384200521b7d22092009200856220a1b37030841052102200a0d0e2003417f4c0d0920031034220a450d0a024020012802142802082007200a2003102241026a220741024b0d0020070e03040002040b41fcd4c5001058000b4101210b410021074100210c0c010b2004200336028c012004200a36028801200441c0006a20044188016a1030200429024421082004280240210b200a102e200b450d0c2008a7210c200128021028025c2008422088a72207490d0b0b200b2007410041202007676b1063024020074102490d00200b21022007210303402002200241206a220a412010f804450d0c200a21022003417f6a220341024f0d000b0b200441206a200128021029034842002006ad220d420010fb0420012802182202420020022903082208427f200429032020042903284200521b7d2209200920085622021b37030820020d0a2006417f4c0d060240024020060d004101210a02402001280214280208200541014100102241026a220241024b0d0020020e030d00020d0b41fcd4c5001058000b0240024020061034220a450d00024020012802142802082005200a2006102241026a220241024b0d0020020e03020003020b41fcd4c5001058000b20064101102c000b200a102e0c0b0b20042001280210220329032842002007ad420010fb04200441106a20032903204200200d420010fb0420012802182102427f2109024020042903184200520d0020042903084200520d002004290310220820042903007c220d2008540d00427f200d20032903307c22082008200d541b21090b200242002002290308220820097d220920092008561b37030820092008580d012006450d0a200a102e0c0a0b200a102e0c0a0b200441b8016a41086a22052001280200280218220341d4006a290000370300200441b8016a41106a2201200341dc006a290000370300200441b8016a41186a220e200341e4006a2900003703002004200329004c3703b8010240200341386a2802002202200341346a280200470d00200241016a220f2002490d0820024101742210200f200f2010491b2210ad42b0017e2208422088a70d082008a7220f4100480d080240024020020d00200f102921020c010b2003280230200241b0016c200f102a21020b2002450d0720032002360230200341346a2010360200200328023821020b2003280230200241b0016c6a220241003a0000200220042f00dd013b0001200241053a00102002200736000c2002200c3600082002200b360004200220042903b801370011200241036a200441dd016a41026a2d00003a0000200241196a2005290300370000200241216a2001290300370000200241296a200e2903003700002002200a360034200220063600382002200636003c200220042f00b5013b0031200241336a200441b5016a41026a2d00003a00002002200429038801370340200241c8006a20044188016a41086a290300370300200241d0006a20044188016a41106a290300370300200241d8006a20044188016a41186a290300370300200241e0006a200441a8016a290300370300200241e8006a200441c0006a41c80010f6041a2003200328023841016a360238410421020c090b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000b20034101102c000b200f4108102c000b102d000b41052102200c450d00200b102e0b20002002360200200441e0016a24000be70804027f027e057f047e230041e00b6b220424000240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200441086a20012802102903484200200241146a2802002202ad420010fb0420012802182203420020032903082206427f200429030820042903104200521b7d2207200720065622081b3703084105210320080d052002417f4c0d02024020020d0002402001280214280208200541014100102241026a220241024b0d0020020e03070007070b41fcd4c5001058000b0240024002400240200210342208450d0002402001280214280208200520082002102241026a220541024b0d0020050e03030002030b41fcd4c5001058000b20024101102c000b2002410f4b0d010b2008102e0c060b200841086a2900002106200829000021072008102e200128020028021822092802140d032009417f360214200441386a41186a200941e4006a290000370300200441c8006a200941dc006a290000370300200441386a41086a200941d4006a2900003703002004200929004c37033802400240200941186a220a280200220841e08dc000460d002009411c6a280200210b0c010b4100210b20044180096a410041e00210f5041a200441e0006a410041a00810f5041a41880b10292208450d05200841003b010620084100360200200841086a20044180096a41e00210f6041a200841e8026a200441e0006a41a00810f6041a2009411c6a4100360200200920083602180b02400240034020082f0106220c410574210541002102410021010240034020052002460d01200441386a200820026a41086a412010f8042203450d03200241206a2102200141016a21012003417f4a0d000b2001417f6a210c0b0240200b450d00200b417f6a210b2008200c4102746a41880b6a28020021080c010b0b200441186a41186a200441386a41186a290300220d370300200441186a41106a200441386a41106a290300220e370300200441186a41086a200441386a41086a290300220f3703002004200429033822103703182004419c096a200f370200200441a4096a200e370200200441ac096a200d3702002004200941206a360290092004200c36028c092004200a3602880920042008360284092004410036028009200420103702940920044194016a42003702002004419c016a41003a0000200441e08dc00036029001200442003703782004420037036020044180096a200441e0006a104f21020c010b200441f8006a4200370300200441f4006a41e08dc00036020020044100360280012004410036027020044200370368200441e08dc000360264200441003602602008200141e0006c6a41e8026a2102200441e0006a10ee010b200241286a2006370300200241206a2007370300200242013703182009200928021441016a360214410421030c050b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000b41aed9c1004110200441e0006a41c0d9c1001053000b41880b4108102c000b20002003360200200441e00b6a24000bac04020b7f027e230041206b220424002001410c6a41003602000240024002402001280200280218220528021441016a220641004c0d00200541cc006a210720052006360214200541186a21082005411c6a28020021090240024003402008280200220a41086a210b200a2f0106220c41057421084100210d0240024003402008450d012007200b412010f804220e450d02200841606a2108200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a210c0b2009450d022009417f6a2109200a200c4102746a41880b6a21080c010b0b200a200d41e0006c6a22084180036a280200220b450d0020084190036a290300210f20084188036a29030021100c010b2004200541246a2802002007200541286a280200280214110300200441106a290300210f20052802142106200429030821102004280200210b0b20052006417f6a36021402400240200141086a280200220d2001410c6a28020022086b4110490d002001280204210d0c010b200841106a220e2008490d03200d4101742208200e200e2008491b22084100480d0302400240200d0d0020081029210d0c010b2001280204200d2008102a210d0b200d450d022001200d360204200141086a20083602002001410c6a28020021080b2001410c6a200841106a360200200d20086a2208200f427f200b1b37000820082010427f200b1b37000020004104360200200441206a24000f0b41e3d7c1004118200441186a41fcd7c1001053000b20084101102c000b102d000bf10203027f027e017f230041206b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200420012802102903484200200241146a2802002202ad420010fb0420012802182203420020032903082206427f200429030020042903084200521b7d2207200720065622081b37030841052103024020080d002002417f4c0d0302400240024020020d004101210802402001280214280208200541014100102241026a220141024b0d0020010e03040002040b41fcd4c5001058000b0240200210342208450d0002402001280214280208200520082002102241026a220141024b0d0020010e03030002030b41fcd4c5001058000b20024101102c000b200441106a2008200210cd02024020042802100d002004280214200441186a28020010090b410421032002450d010b2008102e0b20002003360200200441206a24000f0b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000bbe0101037f410021042001410c6a4100360200200128020028021c21050240024002400240200141086a28020022064104490d00200128020421060c010b200641017422044104200441044b1b22044100480d020240024020060d002004102921060c010b200128020420062004102a21060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441046a360200200620046a2005360000200041043602000f0b20044101102c000b102d000bc505020a7f017e230041c0006b220424002004200136020c2004200041c8ecc50020011b3602082004200441086a1031024020042802000d000240024002400240024002400240200428020c22014170712200417f4c0d002004280204210502400240200141047622060d00410821070c010b200010292207450d020b02402005450d00200441206a4104722108410021094100210a410021000340200441206a200441086a10fc02200441306a41086a220b200841086a2802003602002004200829020037033002402004280220220c4104470d002006450d0a2007102e0c0a0b200041016a2101200441106a41086a220d200b28020036020020042004290330370310024020002006470d002009200120012009491b220641ffffffff00712006470d062006410474220b4100480d060240024020000d00200b102921070c010b2007200a200b102a21070b2007450d050b2007200a6a2200200c360200200041046a20042903103702002000410c6a200d280200360200200941026a2109200a41106a210a2001210020052001470d000b0b2007450d07200441206a200220072005200311060020042802202100410110292201450d042004428180808010370234200420013602300240024020004105460d00200141003a0000200141014102102a2101024020004104470d002001450d08200141003a00012004428280808020370234200420013602304202210e0c020b2001450d08200141013a0001200442828080802037023420042001360230200441206a200441306a10fd022004350238210e200428023021010c010b200141013a00004201210e0b2001ad422086200e84210e02402006450d002007102e0b200441c0006a2400200e0f0b1032000b20004108102c000b200b4108102c000b102d000b41014101102c000b41024101102c000b41024101102c000b41a5a3c20041f000200441206a41b8a2c2001053000bde0202047f017e02400240024002400240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a3602002004417f6a220441034b0d0520040e0401020304010b200041043602000f0b0240200541034b0d00200041043602000f0b200041003602002003280001210420012002417b6a3602042001200341056a360200200020043602040f0b024020054108490d0020004101360200200329000121062001200241776a3602042001200341096a360200200041086a20063703000f0b200041043602000f0b0240200541034b0d00200041043602000f0b200041023602002003280001210420012002417b6a3602042001200341056a360200200020043602040f0b024020054108490d0020004103360200200329000121062001200241776a3602042001200341096a360200200041086a20063703000f0b200041043602000f0b200041043602000b840b02037f017e024002400240024002400240024002400240024002400240024020002802000e0400010203000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0c20024101742204200320032004491b22044100480d0c0240024020020d002004102921030c010b200128020020022004102a21030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a00002000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0c20024101742200200420042000491b22004100480d0c0240024020020d002000102921020c010b200128020020022000102a21020b2002450d0520012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0b20024101742204200320032004491b22044100480d0b0240024020020d002004102921030c010b200128020020022004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a00002000290308210502400240200141046a2802002202200428020022006b4108490d00200128020021020c010b200041086a22032000490d0b20024101742200200320032000491b22004100480d0b0240024020020d002000102921020c010b200128020020022000102a21020b2002450d0620012002360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200220006a20053700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0a20024101742204200320032004491b22044100480d0a0240024020020d002004102921030c010b200128020020022004102a21030b2003450d0620012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a00002000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0a20024101742200200420042000491b22004100480d0a0240024020020d002000102921020c010b200128020020022000102a21020b2002450d0720012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0920024101742204200320032004491b22044100480d090240024020020d002004102921030c010b200128020020022004102a21030b2003450d0720012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a00002000290308210502400240200141046a2802002202200428020022006b4108490d00200128020021020c010b200041086a22032000490d0920024101742200200320032000491b22004100480d090240024020020d002000102921020c010b200128020020022000102a21020b2002450d0820012002360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200220006a20053700000f0b20044101102c000b20004101102c000b20044101102c000b20004101102c000b20044101102c000b20004101102c000b20044101102c000b20004101102c000b102d000bfd0102057f017e230041306b220224002002410036022020014110200241206a10082101024002400240024020022802202203417f460d0020010d010b200041003602040c010b20022003360214200220013602102003450d0120022003417f6a3602142002200141016a36021020012d00002103200241206a200241106a103020022802202204450d012002410c6a41026a2002411d6a41026a2d000022053a0000200220022f001d22063b010c20022902242107200020033a0000200020063b0001200041036a20053a000020002007370208200020043602042001102e0b200241306a24000f0b41eff0c2004133200241206a4184f4c2001053000bcf0201057f230041b0026b22012400200141a0016a41086a22024200370300200142003703a0014198cbc4004116200141a0016a100320014190016a41086a22032002290300370300200120012903a00137039001200141a0016a20014190016a10b1030240024020012d00a80222044103460d0020014190016a411010062001200141a0016a41880110f604220541013a008f0120024200370300200542003703a00141a199c500411f200541a0016a100320032002290300370300200520052903a0013703900120054190016a41102005418f016a41011004200241023a0000200541053a00a0014100210241c8ecc5004100200541a0016a1072200541a0016a200541880110f6041a20054190016a20004180ce186a200541a0016a20044180af1a10f0032005280290014101470d0120052802940121020c010b41aecbc40021020b200141b0026a240020020bda1008057f037e017f017e017f0f7e017f047e230041e0026b2201240041082102200141a8016a41086a22034200370300200142003703a80141c7c9c4004115200141a8016a1003200141c0026a41086a2003290300370300200120012903a8013703c002200141a8016a200141c0026a10b0030240024020012802a80122030d0041002104410021050c010b200141b0016a280200210420012802ac012105200321020b0240024002400240024002402004450d00200141a8016a20022802880110f1030240024020012802b80122030d0042002106420021070c010b200141106a20012903a801200141a8016a41086a290300200141c0016a350200420010fb04200141106a41086a29030021072001290310210620012802bc01450d002003102e0b2002ad4220862108024020044101460d00200241b0016a2103200441b0016c41d07e6a21094201210a0340200141a8016a20034188016a28020010f1030240024020012802b801220b0d004200210c4200210d0c010b200120012903a801200141a8016a41086a29030020013502c001420010fb04200141086a290300210d2001290300210c20012802bc01450d00200b102e0b02402006200c562007200d562007200d511b0d002003ad422086200a842108200c2106200d21070b200341b0016a2103200a42017c210a200941d07e6a22090d000b0b02402008428080808010540d0020042008a722034d0d0220022004417f6a220b41b0016c6a22094180016a290300210d20094188016a290300210720094190016a290300210a20094198016a290300210c200941e0006a2903002106200941e8006a2903002108200941f0006a290300210e200941f8006a290300210f200941c0006a2903002110200941c8006a2903002111200941d0006a2903002112200941d8006a2903002113200941206a2903002114200941286a2903002115200941306a2903002116200941386a290300211720092903002118200929030821192009290310211a2002200341b0016c6a220341186a221b290300211c200941a8016a290300211d200941a0016a290300211e201b200941186a2903003703002003290310211f2003201a3703102003290308211a200320193703082003290300211920032018370300200341386a2209290000211820092017370000200341306a2209290000211720092016370000200341286a2209290000211620092015370000200341206a2209290000211520092014370000200341d8006a2209290000211420092013370000200341d0006a2209290000211320092012370000200341c8006a2209290000211220092011370000200341c0006a2209290000211120092010370000200341f8006a220929000021102009200f370000200341f0006a2209290000210f2009200e370000200341e8006a2209290000210e20092008370000200341e0006a220929000021082009200637000020034198016a200c37000020034190016a200a37000020034188016a2209280000211b2009200737000020034180016a220929000021072009200d370000200341a0016a201e370200200341a8016a201d370200200141206a41f8006a2010370300200141206a41f0006a200f370300200141206a41e8006a200e370300200141206a41e0006a2008370300200141206a41d8006a2014370300200141206a41d0006a2013370300200141206a41c8006a2012370300200141206a41c0006a2011370300200141206a41386a2018370300200141206a41306a2017370300200141206a41286a2016370300200141206a41206a2015370300200141206a41186a201c370300200141206a4180016a20073703002001201f3703302001201a37032820012019370320200141a8016a41086a22034200370300200142003703a80141c7c9c4004115200141a8016a1003200141c0026a41086a2003290300370300200120012903a8013703c002200141103602ac012001200141c0026a3602a8012002200b200141a8016a10ff010240200b450d00200441b0016c41d07e6a21092002210303402003102f200341b0016a2103200941d07e6a22090d000b0b02402005450d002002102e0b411310292203450d032003410f6a41002800fcc844360000200341086a41002900f5c844370000200341002900edc844370000200341134126102a2203450d042003201b360013200141a8016a41186a22094200370300200141a8016a41106a220b4200370300200141a8016a41086a22024200370300200142003703a80120034117200141a8016a1000200141c0026a41186a2009290300370300200141c0026a41106a200b290300370300200141c0026a41086a2002290300370300200120012903a8013703c002200141a8016a200141c0026a10af03024020012802b801220b450d00200141c0026a412010060b200141b0016a290300210d2009280200210220012903a801210720012802bc0121042003102e0240200b0d00200141206a102f0c060b024020024105742209450d00200b2103034020032007200d109401200341206a2103200941606a22090d000b0b200141d0016a200d370300200141c8016a2007370300200141c0016a2002360200200141bc016a2004360200200141b8016a200b360200200141b4016a201b360200200141b0016a41013a0000200141053a00a80141c8ecc5004100200141a8016a1072200141a8016a200141206a41880110f6041a200141c0026a20004180ce186a200141a8016a41004180af1a10f00320012802c0024101470d0520012802c40221030c060b200441b0016c21092002210303402003102f200341b0016a2103200941d07e6a22090d000b0b41ecc9c40021032005450d042002102e0c040b41dcc9c400200320041038000b41134101102c000b41264101102c000b410021030b200141e0026a240020030b9e0501077f230041d0026b2202240002400240411a10292203450d00200341186a41002f00ebc8443b0000200341106a41002900e3c844370000200341086a41002900dbc844370000200341002900d3c8443700002003411a4134102a2203450d012003200136001a200241c0016a41186a22014200370300200241c0016a41106a22044200370300200241c0016a41086a22054200370300200242003703c0012003411e200241c0016a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903c001370300200241003602c00120024120200241c0016a1008210102400240024020022802c0012204417f460d002001450d00200220013602282002200436022c024020044104490d002001280000210620022004417c6a36022c2002200141046a360228200241c0016a200241286a10b80120022d00c0014113460d00200241386a200241c0016a41880110f6041a0240200228022c2207450d00200228022822052d0000210420022007417f6a220836022c2002200541016a360228200441034f0d00200841034b0d03200241386a102f0c010b200241386a102f0b41eff0c2004133200241c8026a4184f4c2001053000b410321040c010b2005280001210820022007417b6a36022c2002200541056a360228200241c0016a200241386a41880110f6041a200220022800303602202002200241336a280000360023200241386a200241c0016a41880110f6041a20022002280023360033200220022802203602302001102e2000200241386a41880110f6042201200836028c012001200636028801200120022802303600910120014194016a20022800333600000b200020043a0090012003102e200241d0026a24000f0b411a4101102c000b41344101102c000bfc0202047f017e230041d0006b22022400024002400240411310292203450d002003410f6a41002800a6c944360000200341086a410029009fc94437000020034100290097c944370000200341134126102a2203450d0120032001360013200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034117200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002002410036022020024120200241206a100821040240024020022802202201417f460d002002200136024420022004360240200241206a200241c0006a103020022802202205450d042002290224210602402001450d002004102e0b20002006370204200020053602000c010b20004100360208200042013702000b2003102e200241d0006a24000f0b41134101102c000b41264101102c000b41eff0c2004133200241c8006a4184f4c2001053000ba40301067f230041c0006b22022400024002400240411010292203450d00200341002900aec844370000200341086a41002900b6c8443700002002429080808080023702242002200336022020012802002104200341104120102a2203450d0120032004360010200242a0808080c00237022420022003360220200141046a200241206a104a200228022421042002280228210120022802202103200241206a41186a22054200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032001200241206a1000200241186a2005290300370300200241106a2006290300370300200241086a2007290300370300200220022903203703002002410036022020024120200241206a100821010240024020022802202205417f460d002005450d0420012d0000220641ff0071220541074f0d042001102e200641077621010c010b41002105410021010b02402004450d002003102e0b200020053a0001200020013a0000200241c0006a24000f0b41104101102c000b41204101102c000b41eff0c2004133200241206a4184f4c2001053000be20c04017f047e107f087e230041b0036b220524000240024002400240024020040d00420021064200210742002108420021090c010b4200210820054190036a41186a220a420037030020054190036a41106a220b420037030020054190036a41086a220c4200370300200542003703900341aac9c400411d20054190036a1000200541c8026a41186a200a290300370300200541c8026a41106a200b290300370300200541c8026a41086a200c29030037030020052005290390033703c802200541e0016a200541c8026a412010dc0141281029220c450d01200c41c8ecc500360200200c20052903e001370204200c20052f0098013b0025200c410c6a200541e0016a41086a290300370200200c41146a200541e0016a41106a290300370200200c411c6a200541e0016a41186a290300370200200c41246a200541e0016a41206a2d00003a0000200c41276a2005419a016a2d00003a000020054198016a200c10d703420021094200210642002107024020052d00d8014107460d002004417f6a210d200541e8026a410472210a200541a0026a210e200541e0016a41206a210f200541e0016a41186a2110200341ff0171211142002106420021074200210842002109034020102007370300200520063703f001200520083703e001200520093703e801200f20054198016a41c10010f604210402400240200e2002460d00200e2002412010f8040d010b200a2004290200370200200a41086a200441086a2212290200370200200a41106a200441106a2213290200370200200a41186a200441186a2214290200370200200520013602e80241101029220b450d05200b41002900aec844370000200b41086a41002900b6c844370000200542908080808002370294032005200b3602900320052802e8022115200b41104120102a220b450d062005200528029803221641046a360298032005200b360290032005412036029403200b20166a2015360000200a20054190036a104a20052802940321172005280298032118200528029003211920054190036a41186a220b420037030020054190036a41106a2215420037030020054190036a41086a2216420037030020054200370390032019201820054190036a1000200541c8026a41186a200b290300370300200541c8026a41106a2015290300370300200541c8026a41086a201629030037030020052005290390033703c802200541c8026a412041c8ecc500410041001005211802402017450d002019102e0b2018417f470d0020052d00c0022119200b20142900003703002015201329000037030020162012290000370300200520042900003703900302404100417f4101201920114b1b20192011461b41016a41014b0d00200321190b20054188016a20054190036a10840120054188016a41086a290300211a200529038801211b02400240201941ff01710d00200541086a201b201a420a420010fc04200541e8026a41186a200b290300370300200541e8026a41106a2015290300370300200541e8026a41086a201629030037030020052005290390033703e802200541186a2001200541e8026a4100200d108403200541186a41186a290300211c200541186a41086a290300211d2005290328211e2005290318211f20052903082220211b200541086a41086a2903002221211a0c010b200541c8006a201a42002019ad42ff01832220420010fb04200541d8006a201b42002020420010fb04200541e8026a41186a200b290300370300200541e8026a41106a2015290300370300200541e8026a41086a201629030037030020052005290390033703e802200541e8006a2001200541e8026a2019200d108403200541386a42004200201b420010fb04427f200541d8006a41086a2903002220200529034820052903387c7c221c2005290350200529034084420052201c2020547222041b2121427f200529035820041b2120200541e8006a41186a290300211c200541e8006a41086a290300211d2005290378211e2005290368211f0b201a20077c201b20067c2207201b54ad7c201c7c2007201e7c2206200754ad7c2107202120097c202020087c2209202054ad7c201d7c2009201f7c2208200954ad7c21090b20054198016a200c10d70320052d00d8014107470d000b0b200c102e0b2000200637031020002008370300200041186a200737030020002009370308200541b0036a24000f0b41284104102c000b41104101102c000b41204101102c000bc107030b7f037e037f23004190016b22012400024002400240024002400240411a10292202450d00200241186a41002f00ebc8443b0000200241106a41002900e3c844370000200241086a41002900dbc844370000200241002900d3c8443700002002411a4134102a2202450d012002200036001a200141f0006a41186a22034200370300200141f0006a41106a22044200370300200141f0006a41086a22054200370300200142003703702002411e200141f0006a1000200141d0006a41186a2003290300370300200141d0006a41106a2004290300370300200141d0006a41086a200529030037030020012001290370370350200141d0006a412010062002102e411310292202450d022002410f6a41002800a6c944360000200241086a410029009fc94437000020024100290097c944370000200241134126102a2202450d0320022000360013200141f0006a41186a22054200370300200141f0006a41106a22064200370300200141f0006a41086a220342003703002001420037037020024117200141f0006a1000200141d0006a41186a22072005290300370300200141d0006a41106a22082006290300370300200141d0006a41086a200329030037030020012001290370370350200141d0006a412010062002102e200141086a2000108203200128020c21092001280208210a024020012802102202450d002002410574210b200141086a4104722103200a21020340200241186a290000210c200241106a290000210d200241086a290000210e20032002290000370000200341086a200e370000200341106a200d370000200341186a200c37000020012000360208411010292204450d06200441002900aec844370000200441086a41002900b6c844370000200142908080808002370274200120043602702001280208210f200441104120102a2204450d072001412036027420012001280278221041046a36027820012004360270200420106a200f3600002003200141f0006a104a2001280274210f20012802782110200128027021042005420037030020064200370300200141f0006a41086a221142003703002001420037037020042010200141f0006a10002007200529030037030020082006290300370300200141d0006a41086a201129030037030020012001290370370350200141d0006a412010060240200f450d002004102e0b200241206a2102200b41606a220b0d000b0b02402009450d00200a102e0b20014190016a24000f0b411a4101102c000b41344101102c000b41134101102c000b41264101102c000b41104101102c000b41204101102c000bab0201047f230041c0006b2202240002400240411710292203450d002003410f6a410029008fc944370000200341086a4100290088c94437000020034100290080c94437000020034117412e102a2203450d0120032001360017200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a22054200370300200242003703202003411b200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a200529030037030020022002290320370300200241206a2002108703024002402002280220450d0020002002290320370200200041086a200241206a41086a2802003602000c010b20004100360208200042083702000b2003102e200241c0006a24000f0b41174101102c000b412e4101102c000beb05020d7f017e230041c0056b22022400200241003602b80420014120200241b8046a1008210302400240024002400240024020022802b8042204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a103120022802080d0420022802144190016e22054190016c2201417f4c0d01200228020c21060240024020010d00410821070c010b200110292207450d030b02402006450d00200241b0036a4101722108410021094100210a4100210b03400240024002402002280214220c450d002002280210220d2d000021012002200c417f6a3602142002200d41016a360210200141014b0d004113210c02400240024020010e020100010b200241b8046a200241106a10b80120022d00b8044113460d02200241b0036a200241b8046a41880110f6041a200228021422014104490d012002280210220c280000210e20022001417c6a3602142002200c41046a36021020022d00b003210c200241a9026a200841870110f6041a200c4113460d02200241a2016a200241a9026a41870110f6041a200c4114460d020b200b41016a21012002411b6a200241a2016a41870110f6041a200b2005470d0302402009200120012009491b2205ad4290017e220f422088a70d00200fa7220d41004e0d030b102d000b200241b0036a102f0b0240200b450d00200721010340024020012d00004113460d002001102f0b20014190016a2101200a41f07e6a220a0d000b0b2005450d082007102e0c080b02400240200b0d00200d102921070c010b2007200a200d102a21070b2007450d060b2007200a6a220b200c3a0000200b41016a2002411b6a41870110f6041a200b4188016a200e360200200941026a2109200a4190016a210a2001210b20062001470d000b0b2007450d042000200536020420002007360200200041086a20063602002004450d002003102e0b200241c0056a24000f0b1032000b20014108102c000b200d4108102c000b41eff0c2004133200241b8046a4184f4c2001053000b13002000410436020420004184acc2003602000b3400200041e5b2c20036020420004100360200200041146a4101360200200041106a41f8b2c200360200200041086a42133702000bcd0101047f200020014105746a210320002104024003400240200320046b41e0004b0d00024020042003460d00200020014105746a210503404101210620022004460d0420042002412010f804450d042005200441206a2204470d000b0b41000f0b4101210620042002460d0120042002412010f804450d01200441206a22052002460d0120052002412010f804450d01200441c0006a22052002460d0120052002412010f804450d01200441e0006a22052002460d0120044180016a210420052002412010f8040d000b0b20060bc40401067f0240024002400240024020012d0000417f6a220241034b0d0020020e0401020304010b41c8a2c2001058000b200041013a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041023a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041033a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000f0b024002402001410c6a280200220341ffffff3f712003470d0020034105742202417f4c0d00200141046a28020021040240024020020d00410121050c010b200210292205450d020b0240024020030d0041002103410021010c010b20034105742106416020046b21072005210120042102034020012002290000370000200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a290000370000200141206a2101200241206a2102200641606a22060d000b200420034105746a20076a41057641016a21010b200041043a00002000410c6a2001360200200041086a2003360200200041046a20053602000f0b1032000b20024101102c000b340020004188c7c20036020420004100360200200041146a4102360200200041106a4190c7c200360200200041086a42073702000b870402077f017e230041e0006b220224000240024002400240411a10292203450d00200341186a41002f00dec9423b0000200341106a41002900d6c942370000200341086a41002900cec942370000200341002900c6c9423700002002429a808080a003370244200220033602402001200241c0006a1046200228024421042002280248210120022802402103200241c0006a41186a22054200370300200241c0006a41106a22064200370300200241c0006a41086a220742003703002002420037034020032001200241c0006a1000200241186a41186a2005290300370300200241186a41106a2006290300370300200241186a41086a20072903003703002002200229034037031820024100360240200241186a4120200241c0006a1008210520022802402201417f460d022002200136023c20022005360238200241c0006a200241386a108f0320022802482206450d01200241086a2207200241c0006a41146a290200370300200241106a2208200241c0006a411c6a2802003602002002200229024c3703002002290340210902402001450d002005102e0b20002006360208200020093702002000200229030037020c200041146a20072903003702002000411c6a20082802003602000c030b411a4101102c000b41eff0c200413320024184f4c2001053000b200041003602080b02402004450d002003102e0b200241e0006a24000ba20301067f230041106b22022400200241003602082002420137030020002802002103024002400240410410292204450d0020024284808080c0003702042002200436020020042003360000200028020421050240024020022802042206200228020822046b4104490d00200441046a2103200228020021060c010b200441046a22032004490d0320064101742207200320032007491b22074100480d030240024020060d002007102921060c010b200228020020062007102a21060b2006450d0220022007360204200220063602000b20022003360208200620046a200536000020002802082104200041106a28020022032002104702402003450d0020034105742103034020042002104a200441206a2104200341606a22030d000b0b200028021421042000411c6a28020022032002104702402003450d0020034105742103034020042002104a200441206a2104200341606a22030d000b0b2002280204210420012802002001280204200228020022032002280208100402402004450d002003102e0b200241106a24000f0b41044101102c000b20074101102c000b102d000bb40202067f017e230041206b220224000240024002400240200128020422034104490d0020012802002204280000210520012003417c6a22063602042001200441046a36020020064104490d01200428000421062001200341786a3602042001200441086a360200200241106a20011030200228021022030d02200041003602080c030b200041003602080c020b200041003602080c010b200241106a41086a280200210720022802142104200241106a2001103002402002280210450d00200241086a200241106a41086a2802002201360200200220022903102208370300200041106a20073602002000200436020c200020033602082000200636020420002005360200200041146a20083702002000411c6a20013602000c010b200041003602082004450d002003102e0b200241206a24000b870402077f017e230041e0006b220224000240024002400240411a10292203450d00200341186a41002f0095ca423b0000200341106a410029008dca42370000200341086a4100290085ca42370000200341002900fdc9423700002002429a808080a003370244200220033602402001200241c0006a1046200228024421042002280248210120022802402103200241c0006a41186a22054200370300200241c0006a41106a22064200370300200241c0006a41086a220742003703002002420037034020032001200241c0006a1000200241186a41186a2005290300370300200241186a41106a2006290300370300200241186a41086a20072903003703002002200229034037031820024100360240200241186a4120200241c0006a1008210520022802402201417f460d022002200136023c20022005360238200241c0006a200241386a108f0320022802482206450d01200241086a2207200241c0006a41146a290200370300200241106a2208200241c0006a411c6a2802003602002002200229024c3703002002290340210902402001450d002005102e0b20002006360208200020093702002000200229030037020c200041146a20072903003702002000411c6a20082802003602000c030b411a4101102c000b41eff0c200413320024184f4c2001053000b200041003602080b02402004450d002003102e0b200241e0006a24000be20201047f230041c0006b2202240002400240410f10292203450d00200341076a410029008fc24237000020034100290088c2423700002003410f411e102a2204450d012004200036000f200241206a41186a22034200370300200241206a41106a22004200370300200241206a41086a220542003703002002420037032020044113200241206a1000200241186a2003290300370300200241106a2000290300370300200241086a200529030037030020022002290320370300200128020021052001280208210320024100360228200242013703202003200241206a104702402003450d00200341057421002005210303402003200241206a104a200341206a2103200041606a22000d000b0b2002280224210320024120200228022022002002280228100402402003450d002000102e0b2004102e0240200141046a280200450d002005102e0b200241c0006a24000f0b410f4101102c000b411e4101102c000b130020004101360204200041accac2003602000b34002000418bcec20036020420004100360200200041146a4102360200200041106a4194cec200360200200041086a42093702000b130020004101360204200041e0d0c2003602000b3101017f02404108102922020d0041084101102c000b20004288808080800137020420002002360200200242b8173700000b13002000410436020420004184d4c2003602000b340020004183dcc20036020420004100360200200041146a4105360200200041106a4198dcc200360200200041086a42133702000b3400200041cce2c20036020420004100360200200041146a4105360200200041106a41e0e2c200360200200041086a42133702000bd11e03037f027e047f23004190026b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e13000102030405060708090a0b0c0d0e0f101112000b20024188016a200141086a109a03200041003a0000200041106a20024188016a41086a290300370300200041086a2002290388013703000c120b200041013a00002000410220012d0001220141004720014102461b3a00010c110b200041023a0000200041086a200141086a2903003703000c100b20024188016a200141046a1039200041033a00002000410c6a20024190016a280200360200200041046a2002290388013702000c0f0b109b03000b0240024002400240200141086a280200417f6a220341014b0d0020030e020102010b41f8b3c0001058000b41012103024002402001410c6a2d00004101460d00200241026a2001410f6a2d00003a000020024190016a2001411c6a29020037030020024188016a41106a200141246a290200370300200241a0016a2001412c6a2d00003a000020022001410d6a2f00003b01002002200141146a29020037038801200141106a2802002104410021030c010b200141106a28020021040b200241246a41026a200241026a2d00003a0000200241286a41086a20024188016a41086a290300370300200241286a41106a20024188016a41106a290300370300200241286a41186a20024188016a41186a280200360200200220022f01003b01242002200229038801370328200141386a29030021052001290330210641012107200241106a21010c010b41012103024002402001410c6a2d00004101460d002002418e026a2001410f6a2d00003a000020024190016a2001411c6a29020037030020024188016a41106a200141246a290200370300200241a0016a2001412c6a2d00003a000020022001410d6a2f00003b018c022002200141146a29020037038801200141106a2802002104410021030c010b200141106a28020021040b41022107200241246a41026a2002418c026a41026a2d00003a0000200241286a41086a20024188016a41086a290300370300200241286a41106a20024188016a41106a290300370300200241286a41186a20024188016a41186a280200360200200220022f018c023b01242002200229038801370328200220012903303703102002200141386a290300370318200141c8006a290300210520012903402106200221010b20012006370300200120053703082000410c6a20033a0000200041086a20073602002000410d6a20022f01243b00002000410f6a200241266a2d00003a0000200041106a2004360200200041146a20022903283702002000411c6a200241286a41086a290300370200200041246a200241286a41106a2903003702002000412c6a200241c0006a280200360200200041386a200241106a41086a290300370300200041306a2002290310370300200041c0006a2002290300370300200041c8006a200241086a290300370300200041053a00000c0d0b20024188016a200141086a109c03200041063a0000200041386a20024188016a41306a290300370300200041306a20024188016a41286a290300370300200041286a20024188016a41206a290300370300200041206a20024188016a41186a290300370300200041186a20024188016a41106a290300370300200041106a20024188016a41086a290300370300200041086a2002290388013703000c0c0b20024188016a41186a200141286a29000037030020024188016a41106a200141206a29000037030020024190016a200141186a29000037030020024188016a41286a200141386a29000037030020024188016a41306a200141c0006a29000037030020024188016a41386a200141c8006a29000037030020024188016a41c8006a200141d8006a29000037030020024188016a41d0006a200141e0006a29000037030020024188016a41d8006a200141e8006a2900003703002002200141106a290000370388012002200141306a2900003703a8012002200141d0006a2900003703c8012001410c6a2802002203417f4c0d0c0240024020030d00410121010c010b200141046a2802002104200310292201450d0e20012004200310f6041a0b200241286a20024188016a41e00010f6041a2000410c6a2003360200200041086a2003360200200041046a2001360200200041106a200241286a41e00010f6041a200041073a00000c0b0b20024188016a200141086a109d03200041083a0000200041306a20024188016a41286a290300370300200041286a20024188016a41206a290300370300200041206a20024188016a41186a290300370300200041186a20024188016a41106a290300370300200041106a20024188016a41086a290300370300200041086a2002290388013703000c0a0b20024188016a200141046a109e03200041093a0000200041246a200241a8016a2903003702002000411c6a200241a0016a290300370200200041146a20024198016a2903003702002000410c6a20024190016a290300370200200041046a2002290388013702000c090b024002400240024002400240200141046a2d0000417f6a220341034b0d0020030e0401020304010b41dcc3c2001058000b200141106a280200220741ffffff3f712007470d0d20074105742203417f4c0d0d200141086a2802002108410121014101210902402003450d00200310292209450d100b024020070d0041002103410021070c040b20074105742104416020086b210a2009210120082103034020012003290000370000200141186a200341186a290000370000200141106a200341106a290000370000200141086a200341086a290000370000200141206a2101200341206a2103200441606a22040d000b41012101200820074105746a200a6a41057641016a21030c030b41880110292209450d0f2009200141086a280200109903410221010c020b200141086a280200210941880110292207450d0f20072001410c6a280200109903410321010c010b2002412a6a200141076a2d00003a000020024188016a41086a2001411c6a29000037030020024188016a41106a200141246a2d00003a00002002200141056a2f00003b01282002200141146a29000037038801200141256a2d00004100472108200141286a2802002104200141106a28000021032001410c6a2800002107200141086a2800002109410421010b2000410a3a0000200041046a20013a0000200041056a20022f01283b0000200041106a20033602002000410c6a2007360200200041086a2009360200200041146a200229038801370200200041286a2004360200200041256a20083a0000200041076a2002412a6a2d00003a00002000411c6a20024188016a41086a290300370200200041246a20024188016a41106a2d00003a00000c080b20024188016a200141086a10d8012000410b3a0000200041c0006a20024188016a41386a290300370300200041386a20024188016a41306a290300370300200041306a20024188016a41286a290300370300200041286a20024188016a41206a290300370300200041206a20024188016a41186a290300370300200041186a20024188016a41106a290300370300200041106a20024188016a41086a290300370300200041086a2002290388013703000c070b20024188016a200141046a108b03200041046a20024188016a41c40010f6041a2000410c3a00000c060b2000410d3a0000200041046a200141046a2802003602000c050b2001410c6a2802002203417f4c0d050240024020030d00410121010c010b200141046a2802002104200310292201450d0b20012004200310f6041a0b2000410e3a00002000410c6a2003360200200041086a2003360200200041046a20013602000c040b024002400240024002400240200141086a280200417f6a220341024b0d0020030e03010203010b4184dbc0001058000b200141386a2903002105200141306a290300210641012103024002402001410c6a2d00004101460d0020024190016a2001411c6a29020037030020024188016a41106a200141246a290200370300200241a0016a2001412c6a2d00003a00002002200141146a290200370388012001410d6a2f00002001410f6a2d0000411074722104200141106a2802002101410021030c010b200141106a28020021010b200241286a41186a20024188016a41186a280200360200200241286a41106a20024188016a41106a290300370300200241286a41086a20024188016a41086a2903003703002002200229038801370328410121070c030b2001410c6a28020022034108762104410221070c010b2001410c6a28020022034108762104410321070b0b2000410f3a0000200041386a2005370300200041306a2006370300200041106a2001360200200041086a2007360200200041146a20022903283702002000410c6a2004410874200341ff0171723602002000411c6a200241286a41086a290300370200200041246a200241286a41106a2903003702002000412c6a200241c0006a2802003602000c030b20024188016a200141086a109f03200041086a20024188016a41800110f6041a200041103a00000c020b0240024002400240200141046a280200417f6a220341014b0d0020030e020102010b41a8c2c2001058000b41880110292203450d0a2003200141086a280200109903410121010c010b4101210302400240200141086a2d00004101460d0020024188016a41086a200141186a29000037030020024188016a41106a200141206a29000037030020024188016a41186a200141286a2d00003a00002002200141106a29000037038801200141096a2f00002001410b6a2d00004110747241087421072001410c6a2800002104410021030c010b2001410c6a2802002104410021070b200241286a41186a20024188016a41186a280200360200200241286a41106a20024188016a41106a290300370300200241286a41086a20024188016a41086a290300370300200220022903880137032820032007722103410221010b200041113a00002000410c6a2004360200200041086a2003360200200041046a2001360200200041106a2002290328370200200041186a200241286a41086a290300370200200041206a200241286a41106a290300370200200041286a200241286a41186a2802003602000c010b20024188016a200141046a108002200041046a20024188016a41e40010f6041a200041123a00000b20024190026a24000f0b1032000b20034101102c000b20034101102c000b4188014108102c000b4188014108102c000b20034101102c000b4188014108102c000bac0703037f017e077f0240024002400240024002400240024002400240024002400240024002402001280200417f6a220241054b0d0020020e06010203040506010b4194f4c2001058000b200041013602000f0b2001410c6a2802002202417f4c0d04200128020421010240024020020d00410121030c010b200210292203450d060b20032001200210f60421012000410c6a2002360200200041086a200236020020002001360204200041023602000f0b20004103360200200041086a200141086a2903003703000f0b2001410c6a2802002202417f4c0d02200128020421010240024020020d00410121030c010b200210292203450d050b20032001200210f60421012000410c6a2002360200200041086a200236020020002001360204200041043602000f0b2001410c6a2802002204ad42187e2205422088a70d012005a72203417f4c0d01200128020421020240024020030d00410421060c010b200310292206450d050b0240024020040d00410021070c010b2002200441186c6a210841002107200621010340200241086a2802002203417f4c0d030240024020030d00410121090c010b2002280200210a200310292209450d082009200a200310f6041a0b200241146a280200220a417f4c0d0302400240200a0d004101210b0c010b2002410c6a280200210c200a1029220b450d09200b200c200a10f6041a0b20012009360200200141146a200a360200200141106a200a3602002001410c6a200b360200200141086a2003360200200141046a2003360200200141186a2101200741016a2107200241186a22022008470d000b0b20002006360204200041053602002000410c6a2007360200200041086a20043602000f0b2001410c6a280200220cad420c7e2205422088a70d002005a72202417f4c0d00200128020421030240024020020d00410421080c010b200210292208450d070b02400240200c0d004100210a0c010b2003200c410c6c6a21074100210a200821020340200341086a2802002201417f4c0d02200328020021090240024020010d004101210b0c010b20011029220b450d0a0b200b2009200110f6042109200241086a2001360200200241046a2001360200200220093602002002410c6a2102200a41016a210a2003410c6a22032007470d000b0b20002008360204200041063602002000410c6a200a360200200041086a200c3602000f0b1032000b20024101102c000b20024101102c000b20034104102c000b20034101102c000b200a4101102c000b20024104102c000b20014101102c000b0a004180c3c2001058000bcc0c03047f017e057f230041206b22022400024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2203410d4b0d0020030e0e0102030405060708090a0b0c0d0e010b41b8bfc4001058000b4101210302400240200141046a2d00004101460d002002411e6a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b011c20022001410c6a290000370300200141086a2800002104410021030c010b200141086a28020021040b200041286a2001290328370300200041046a20033a0000200041056a20022f011c3b0000200041086a20043602002000410c6a2002290300370200200041306a200141306a290300370300200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a28020036020020012d00012101200041013a0000200020013a00010c0d0b200041023a0000200041106a200141106a290300370300200041086a200141086a2903003703000c0c0b200041033a0000200041106a200141106a290300370300200041086a200141086a2903003703000c0b0b200041043a00000c0a0b200041053a0000200041106a200141106a290300370300200041086a200141086a290300370300200041186a200141186a2802003602000c090b2001410c6a2802002205ad42247e2206422088a70d092006a72204417f4c0d09200141046a28020021030240024020040d00410421070c010b200410292207450d0b0b0240024020050d00410021040c010b200541246c2108410021042002411e6a21092007210103400240024020032d00004101460d002009200341036a2d00003a0000200341046a280000210a200341016a2f0000210b200241086a200341106a290000370300200241106a200341186a290000370300200241186a200341206a2d00003a00002002200b3b011c2002200341086a2900003703004100210b0c010b200341046a280200210a4101210b0b200341246a21032001200b3a0000200141046a200a360200200141016a20022f011c3b0000200141036a20092d00003a0000200141086a2002290300370200200141106a200241086a290300370200200141186a200241106a290300370200200141206a200241186a280200360200200141246a2101200441016a21042008415c6a22080d000b0b200041063a00002000410c6a2004360200200041086a2005360200200041046a20073602000c080b200041073a00000c070b200041083a0000200020012d00013a00010c060b4101210302400240200141046a2d00004101460d002002411e6a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b011c20022001410c6a290000370300200141086a2800002101410021030c010b200141086a28020021010b200041093a0000200041046a20033a0000200041056a20022f011c3b0000200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c050b2000410a3a0000200041046a200141046a2802003602000c040b2000410b3a00000c030b2000410c3a00000c020b2000410d3a0000200041046a200141046a2802003602000c010b2001410c6a280200220841ffffff3f712008470d0120084105742203417f4c0d01200141046a280200210a0240024020030d004101210b0c010b20031029220b450d040b0240024020080d0041002108410021010c010b200841057421044160200a6b2109200b2101200a2103034020012003290000370000200141186a200341186a290000370000200141106a200341106a290000370000200141086a200341086a290000370000200141206a2101200341206a2103200441606a22040d000b200a20084105746a20096a41057641016a21010b2000410e3a00002000410c6a2001360200200041086a2008360200200041046a200b3602000b200241206a24000f0b1032000b20044104102c000b20034101102c000bab0701017f024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a220241104b0d0020020e110102030405060708090a0b0c0d0e0f1011010b41e890c5001058000b41880110292202450d102002200141046a28020010fd03200041046a2002360200200041013a0000200041106a200141106a290300370300200041086a200141086a2903003703000f0b200041023a0000200041046a200141046a2802003602000f0b200041033a0000200041046a200141046a280200360200200041026a200141026a2d00003a0000200020012d00014101713a00010f0b200041043a0000200041046a200141046a280200360200200041026a200141026a2d00003a0000200020012d00014101713a00010f0b200041053a0000200041046a200141046a2802003602000f0b41880110292202450d0c2002200141046a28020010fd03200041063a0000200041046a20023602000f0b41880110292202450d0c2002200141046a28020010fd03200041073a0000200041046a20023602000f0b41880110292202450d0c2002200141046a28020010fd03200041083a0000200041046a20023602000f0b200041093a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2902003702000f0b2000410a3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b2000410b3a0000200041046a200141046a2802003602000f0b2000410c3a00002000410c6a2001410c6a280200360200200041046a200141046a2902003702000f0b2000410d3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b2000410e3a00000f0b2000410f3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041103a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000f0b200041113a00000f0b4188014108102c000b4188014108102c000b4188014108102c000b4188014108102c000b9f0401067f02400240024002400240024002400240024020012d0000417f6a220241034b0d0020020e0401020304010b41dcc3c2001058000b2001410c6a280200220341ffffff3f712003470d0320034105742202417f4c0d03200141046a28020021040240024020020d00410121050c010b200210292205450d050b0240024020030d0041002103410021010c010b20034105742106416020046b21072005210120042102034020012002290000370000200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a290000370000200141206a2101200241206a2102200641606a22060d000b200420034105746a20076a41057641016a21010b200041013a00002000410c6a2001360200200041086a2003360200200041046a20053602000f0b41880110292202450d042002200141046a280200109903200041023a0000200041046a20023602000f0b200141046a280200210641880110292202450d042002200141086a280200109903200041086a2002360200200041046a2006360200200041033a00000f0b200041043a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a280200360200200041216a200141216a2d00004100473a00000f0b1032000b20024101102c000b4188014108102c000b4188014108102c000bee0b05027f017e027f027e017f230041c0006b220224000240024002400240024002400240024002400240024020012d0000417f6a220341044b0d0020030e050102030405010b41c4e0c3001058000b200041f9006a2002280020360000200041086a200141086a290300370300200041fc006a200241236a280000360000200041106a200141106a290300370300200041186a200141186a290300370300200041206a200141206a290300370300200041286a200141286a290300370300200041306a200141306a290300370300200041386a200141386a290300370300200041c0006a200141c0006a290300370300200041c8006a200141c8006a290300370300200041d0006a200141d0006a290300370300200041d8006a200141d8006a290300370300200041e0006a200141e0006a290300370300200041e8006a200141e8006a290300370300200041f0006a200141f0006a290300370300200041f8006a200141f8006a2d00004100473a0000200041013a00000c040b2001410c6a2802002203417f4c0d04200141106a29030021040240024020030d00410121010c010b200141046a2802002105200310292201450d0620012005200310f6041a0b200041023a00002000410c6a2003360200200041086a2003360200200041046a2001360200200041106a20043703000c030b4101210502400240200141046a2d00004101460d00200241026a200141076a2d00003a0000200241206a41086a200141146a290000370300200241306a2001411c6a290000370300200241386a200141246a2d00003a00002002200141056a2f00003b010020022001410c6a290000370320200141086a2800002106410021050c010b200141086a28020021060b200141306a2802002203417f4c0d03200141c0006a290300210420012903382107200129034821080240024020030d00410121010c010b20012802282109200310292201450d0620012009200310f6041a0b200041c0006a2004370300200041386a2007370300200041046a20053a0000200041056a20022f01003b0000200041086a20063602002000410c6a2002290320370200200041c8006a2008370300200041306a20033602002000412c6a2003360200200041286a2001360200200041076a200241026a2d00003a0000200041146a200241206a41086a2903003702002000411c6a200241306a290300370200200041246a200241386a280200360200200041033a00000c020b200141386a2903002104200141306a2903002107200141c0006a2903002108200241386a200141196a290000370300200241306a200141116a290000370300200241286a200141096a290000370300200220012900013703202001412c6a2802002203417f4c0d020240024020030d00410121010c010b200141246a2802002105200310292201450d0620012005200310f6041a0b20002002290320370001200041043a0000200041386a2004370300200041306a2007370300200041c0006a20083703002000412c6a2003360200200041286a2003360200200041246a2001360200200041096a200241286a290300370000200041116a200241306a290300370000200041196a200241386a2903003700000c010b200241186a2205200141196a290000370300200241106a2206200141116a290000370300200241086a2209200141096a29000037030020022001290001370300410021030240200141216a2d00004101470d00200241206a41186a2001413a6a290000370300200241206a41106a200141326a290000370300200241206a41086a2001412a6a2900003703002002200141226a290000370320410121030b20002002290300370001200041216a20033a0000200041226a2002290320370000200041196a2005290300370000200041116a2006290300370000200041096a20092903003700002000412a6a200241206a41086a290300370000200041326a200241206a41106a2903003700002000413a6a200241206a41186a290300370000200041053a00000b200241c0006a24000f0b1032000b20034101102c000b20034101102c000b20034101102c000b130020004102360204200041a8eac2003602000b3400200041cdeec20036020420004100360200200041146a4101360200200041106a41d4eec200360200200041086a42043702000bcf0101017f024002400240024002400240410110292202450d00200241003a0000200241014102102a2202450d01200241003a0001200241024104102a2202450d02200241003b0002200241044108102a2202450d0320024100360004200241084110102a2202450d0420024200370008200241104120102a2202450d052002420037001820024200370010200042a08080808004370204200020023602000f0b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000bd40201027f0240024002402002450d002002417f6a2103024020012d0000220241037122044103460d000240024020040e03040001040b2003450d0220012d0001410874200272220241ffff0371418002490d02200241fcff037141027621020c040b20034103490d0120012f0001200141036a2d000041107472410874200272220241808004490d01200241027621020c030b200241034b0d0020034104490d002001280001220241ffffffff034b0d020b200041013602000f0b200241027621020b410121040240200241016a220120024f0d00200041013602000f0b0240200241c000490d0041022104200241808001490d00410441052002418080808004491b21040b410121020240200141c000490d0041022102200141808001490d00410441052001418080808004491b21020b20002001360204200041003602002000410c6a2002360200200041086a20043602000bdf0401047f02400240024002400240024020002802704101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0620024101742204200320032004491b22044100480d060240024020020d002004102921030c010b200128020020022004102a21030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a00002000280274210502400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d0620034101742202200420042002491b22024100480d060240024020030d002002102921030c010b200128020020032002102a21030b2003450d0420012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20053600000c010b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0520024101742204200320032004491b22044100480d050240024020020d002004102921030c010b200128020020022004102a21030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a00000b200020011084022000280278210220004180016a28020022002001104702402000450d00200041057421000340200220011046200241206a2102200041606a22000d000b0b0f0b20044101102c000b20024101102c000b20044101102c000b102d000be80101017f024020002d0000417b6a220141074b0d00024002400240024020010e080004040104020403000b200041086a2d00004101470d03200041146a280200450d03200041106a280200102e0c030b200041046a2d00004103470d0202402000410c6a280200450d00200041086a280200102e0b200041186a280200450d02200041146a280200102e0c020b200041046a2802000d012000410c6a280200450d01200041086a280200102e0c010b200041086a2d00004105490d00200041306a280200450d002000412c6a280200102e0b0240200041fc006a280200450d002000280278102e0b0b130020004106360204200041b8f6c2003602000b3400200041c3fcc20036020420004100360200200041146a410f360200200041106a41ccfcc200360200200041086a42063702000b6701017f230041306b22022400200241186a4200370300200241106a4200370300200241086a42003703002002420037030020024100360228200242013703202002200241206a1046200041086a200228022836020020002002290320370200200241306a24000b5c01027f230041106b2202240002404101102922030d0041014101102c000b200341003a0000200242818080801037020420022003360200410020021047200041086a200228020836020020002002290300370200200241106a24000b130020004100360204200041c8ecc5003602000b9609030b7f017e027f230041c0016b2202240020024100360298012001412020024198016a1008210302400240024002402002280298012204417f470d00200041023a000c0c010b2002200436020420022003360200200241086a2002103020022802082205450d02200228020c210620022802042201450d01200241106a280200210720022001417f6a220836020420022002280200220941016a220a36020020092d0000220141014b0d014100210b0240024020010e020100010b41002101200241003a00b8010340024020082001470d0020024100360204200141ff0171450d04200241003a00b8010c040b20024198016a20016a200920016a220c41016a2d00003a00002002200c41026a3602002002200141016a220c3a00b801200c2101200c4120470d000b200241d8006a41086a20024198016a41086a290300220d370300200241386a41186a20024198016a41186a290300370300200241386a41106a20024198016a41106a290300370300200241386a41086a200d37030020022008200c6b22083602042002200229039801220d3703582002200d3703384101210b2009200c6a41016a210a0b200241186a41186a200241386a41186a290300370300200241186a41106a200241386a41106a290300370300200241186a41086a200241386a41086a290300370300200220022903383703182008450d0120022008417f6a22083602042002200a41016a360200200a2d0000220c41014b0d014100210102400240200c0e020100010b41002101200241003a00b8010340024020082001470d0020024100360204200141ff0171450d04200241003a00b8010c040b20024198016a20016a200a20016a220c41016a2d00003a00002002200c41026a3602002002200141016a220c3a00b801200c2101200c4120470d000b200241d8006a41086a20024198016a41086a290300220d370300200241386a41186a20024198016a41186a290300370300200241386a41106a20024198016a41106a290300370300200241386a41086a200d37030020022008200c6b3602042002200229039801220d3703582002200d370338410121010b200241f8006a41186a220c200241386a41186a290300370300200241f8006a41106a2208200241386a41106a290300370300200241f8006a41086a220a200241386a41086a29030037030020024198016a41086a2209200241186a41086a29030037030020024198016a41106a220e200241186a41106a29030037030020024198016a41186a220f200241186a41186a290300370300200220022903383703782002200229031837039801200b4102460d022000200b3a000c200020073602082000200636020420002005360200200020022903980137000d2000412d6a20013a00002000412e6a2002290378370000200041156a20092903003700002000411d6a200e290300370000200041256a200f290300370000200041366a200a2903003700002000413e6a2008290300370000200041c6006a200c290300370000200041ce006a20022f01583b01002004450d002003102e0b200241c0016a24000f0b2006450d002005102e0b41eff0c2004133200241386a4184f4c2001053000b850101037f230041106b22022400410021032002410036020420014110200241046a1008210102400240024020022802042204417f470d000c010b024020010d000c010b20044104490d01200128000021042001102e410121030b2000200436020420002003360200200241106a24000f0b41eff0c2004133200241086a4184f4c2001053000beb0905047f027e057f017e037f230041e0016b22022400200241003602b80120014120200241b8016a1008210302400240024020022802b8012204417f470d00200041023a00180c010b2002200436022c20022003360228200241206a200241286a103120022802200d0120022802242105200241086a200241286a10652002290308a70d01200228022c2201450d01200241186a29030021062002290310210720022001417f6a220836022c20022002280228220941016a220a36022820092d0000220141014b0d014100210b0240024020010e020100010b41002101200241003a00d8010340024020082001470d002002410036022c200141ff0171450d04200241003a00d8010c040b200241b8016a20016a200920016a220c41016a2d00003a00002002200c41026a3602282002200141016a220c3a00d801200c2101200c4120470d000b200241f8006a41086a200241b8016a41086a290300220d370300200241d8006a41186a200241b8016a41186a290300370300200241d8006a41106a200241b8016a41106a290300370300200241d8006a41086a200d37030020022008200c6b220836022c200220022903b801220d3703782002200d3703584101210b2009200c6a41016a210a0b200241386a41186a200241d8006a41186a290300370300200241386a41106a200241d8006a41106a290300370300200241386a41086a200241d8006a41086a290300370300200220022903583703382008450d0120022008417f6a220836022c2002200a41016a360228200a2d0000220c41014b0d014100210102400240200c0e020100010b41002101200241003a00d8010340024020082001470d002002410036022c200141ff0171450d04200241003a00d8010c040b200241b8016a20016a200a20016a220c41016a2d00003a00002002200c41026a3602282002200141016a220c3a00d801200c2101200c4120470d000b200241f8006a41086a200241b8016a41086a290300220d370300200241d8006a41186a200241b8016a41186a290300370300200241d8006a41106a200241b8016a41106a290300370300200241d8006a41086a200d37030020022008200c6b36022c200220022903b801220d3703782002200d370358410121010b20024198016a41186a220c200241d8006a41186a29030037030020024198016a41106a2208200241d8006a41106a29030037030020024198016a41086a220a200241d8006a41086a290300370300200241b8016a41086a2209200241386a41086a290300370300200241b8016a41106a220e200241386a41106a290300370300200241b8016a41186a220f200241386a41186a2903003703002002200229035837039801200220022903383703b801200241f8006a41046a2210200241326a41046a2f01003b010020022002280132360278200b4102460d01200020073703002000200b3a001820002005360210200020022903b80137001920002006370308200041396a20013a00002000413a6a200229039801370000200041216a2009290300370000200041296a200e290300370000200041316a200f290300370000200041c2006a200a290300370000200041ca006a2008290300370000200041d2006a200c290300370000200041de006a20102f01003b0100200041da006a20022802783601002004450d002003102e0b200241e0016a24000f0b41eff0c2004133200241d8006a4184f4c2001053000bca0708047f047e067f027e017f017e017f017e230041b0016b2202240020024100360288012001412020024188016a10082103024002400240024002400240024002402002280288012204417f460d0020030d010b200041003602200c010b200220043602642002200336026041002101200241003a00a8010340024020042001470d0020024100360264200141ff0171450d07200241003a00a8010c070b20024188016a20016a200320016a22052d00003a00002002200541016a3602602002200141016a22053a00a8012005210120054120470d000b200241e8006a41086a20024188016a41086a290300370300200241e8006a41106a20024188016a41106a290300370300200241e8006a41186a20024188016a41186a29030037030020022002290388013703682002200420056b360264200241c8006a200241e0006a10652002290348a70d05200241c8006a41106a290300210620022903502107200241306a200241e0006a10652002290330a70d05200241306a41106a290300210820022903382109200241286a200241e0006a103120022802280d05200228026441186e220a41186c2201417f4c0d01200228022c210b0240024020010d004108210c0c010b20011029220c450d030b0240200b450d00200241106a41106a210d4100210e4100210f410021050340200241106a200241e0006a1065024002402002290310a70d00200d290300211020022903182111200241086a200241e0006a10312002280208450d010b200a450d08200c102e0c080b200541016a2101200228020c211202402005200a470d00200e20012001200e491b220aad42187e2213422088a70d072013a722144100480d070240024020050d0020141029210c0c010b200c200f2014102a210c0b200c450d060b200c200f6a2205201037030820052011370300200541106a2012360200200e41026a210e200f41186a210f20012105200b2001470d000b0b200c450d0520024188016a41186a200241e8006a41186a290300221037030020024188016a41106a200241e8006a41106a290300221137030020024188016a41086a200241e8006a41086a290300221337030020022002290368221537038801200041186a20083703002000200937031020002006370308200020073703002000200bad422086200aad843702242000200c3602202000412c6a2015370200200041346a20133702002000413c6a2011370200200041c4006a20103702002004450d002003102e0b200241b0016a24000f0b1032000b20014108102c000b20144108102c000b102d000b41eff0c2004133200241e8006a4184f4c2001053000bdb0102027f037e230041206b220224002002410036021020014120200241106a10082101024002400240024020022802102203417f460d0020010d010b200041003602100c010b200220013602082002200336020c20034110490d012002200341706a36020c2002200141106a360208200141086a290000210420012900002105200241106a200241086a103020022802102203450d0120022902142106200020043703082000200537030020002006370214200020033602102001102e0b200241206a24000f0b41eff0c2004133200241106a4184f4c2001053000bcb0702107f017e230041a0056b22022400200241003602f00320014110200241f0036a1008210302400240024002400240024020022802f0032204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a103120022802080d04200228021441b0016e220541b0016c2201417f4c0d01200228020c21060240024020010d00410821070c010b200110292207450d030b02402006450d00200241e8026a4101722108410021094100210a0340024002400240200228021422014104490d002002280210220b280000210c20022001417c6a3602142002200b41046a360210200241f0036a200241106a10b80120022d00f0034113460d00200a41016a210d200241e8026a200241f0036a41880110f6041a4100210b200241003a0098052002280214417f6a2101024003402001417f460d01200241f8046a200b6a2002280210220e2d00003a00002002200e41016a3602102002200b41016a220e3a009805200220013602142001417f6a2101200e210b200e4120470d000b200241c0016a41186a2201200241f8046a41186a290300370300200241c0016a41106a220e200241f8046a41106a290300370300200241c0016a41086a220f200241f8046a41086a290300370300200220022903f8043703c00120022d00e802210b200241e1016a200841870110f6041a200b4113460d01200241396a200241e1016a41870110f6041a200241186a41186a22102001290300370300200241186a41106a2211200e290300370300200241186a41086a220e200f290300370300200220022903c0013703182005200a470d030240200a4101742201200d200d2001491b2205ad42b0017e2212422088a70d002012a7220141004e0d030b102d000b0240200b41ff0171450d00200241003a0098050b200241e8026a102f0b0240200a450d002007210103402001102f200141b0016a2101200941d07e6a22090d000b0b2005450d082007102e0c080b02400240200a0d002001102921070c010b2007200a41b0016c2001102a21070b2007450d060b2007200a41b0016c6a2201200b3a0000200141016a200241396a41870110f6041a2001200c360288012001200229031837028c0120014194016a200e2903003702002001419c016a2011290300370200200141a4016a2010290300370200200941b0016a2109200d210a200d2006470d000b0b2007450d042000200536020420002007360200200041086a20063602002004450d002003102e0b200241a0056a24000f0b1032000b20014108102c000b20014108102c000b41eff0c2004133200241f0036a4184f4c2001053000bab0201057f230041b0026b22022400200241003602a80120014110200241a8016a100821030240024020022802a8012201417f470d00200041033a0088010c010b2002200136021420022003360210200241a8016a200241106a10b8010240024020022d00a8014113460d00200241206a200241a8016a41880110f6041a024020022802142204450d00200228021022052d0000210620022004417f6a3602142002200541016a36021020064103490d020b200241206a102f0b41eff0c2004133200241a8016a4184f4c2001053000b2000200241206a41880110f60421002002200241196a41036a28000036000b20022002280019360208200020063a00880120002002280208360089012000418c016a200228000b3600002001450d002003102e0b200241b0026a24000bc50b03087f017e067f230041d0016b22022400200241003602a80120014120200241a8016a10082103024002400240024020022802a8012204417f460d0020030d010b200041023a00210c010b41002101200241003a00c8012004417e6a21050340024020042001470d00200141ff0171450d03200241003a00c8010c030b200241a8016a20016a200320016a2d00003a00002002200141016a22063a00c8012005417f6a21052006210120064120470d000b20024188016a41186a200241a8016a41186a29030037030020024188016a41106a200241a8016a41106a29030037030020024188016a41086a200241a8016a41086a290300370300200220022903a8013703880120042006460d01200320066a22072d0000220841074f0d01200241086a41186a20024188016a41186a290300370300200241086a41106a20024188016a41106a290300370300200241086a41086a20024188016a41086a29030037030020022002290388013703082004417f6a2006460d01200741016a2d0000220141014b0d01200420066b210902400240024020010e020100010b41002101200241003a00c8012009417e6a21090340024020092001470d00200141ff0171450d05200241003a00c8010c050b200241a8016a20016a200720016a41026a2d00003a00002002200141016a22063a00c8012006210120064120470d000b200241e8006a41086a200241a8016a41086a290300220a370300200241c8006a41186a200241a8016a41186a290300370300200241c8006a41106a200241a8016a41106a290300370300200241c8006a41086a200a370300200220022903a801220a3703682002200a370348200520066b210b200720066a41026a2106410121090c010b200741026a21062009417e6a210b410021090b200241286a41186a200241c8006a41186a290300370300200241286a41106a200241c8006a41106a290300370300200241286a41086a200241c8006a41086a29030037030020022002290348370328200b450d0120062d0000220541014b0d01410021010240024020050e020100010b41002101200241003a00c801200641016a2105200b417f6a21070340024020072001470d00200141ff0171450d04200241003a00c8010c040b200241a8016a20016a200520016a2d00003a00002002200141016a22063a00c8012006210120064120470d000b200241e8006a41086a200241a8016a41086a290300220a370300200241c8006a41186a200241a8016a41186a290300370300200241c8006a41106a200241a8016a41106a290300370300200241c8006a41086a200a370300200220022903a801220a3703682002200a370348410121010b200241e8006a41186a2206200241c8006a41186a290300370300200241e8006a41106a2205200241c8006a41106a290300370300200241e8006a41086a2207200241c8006a41086a29030037030020024188016a41086a220b200241286a41086a29030037030020024188016a41106a220c200241286a41106a29030037030020024188016a41186a220d200241286a41186a290300370300200220022903483703682002200229032837038801200241a8016a41186a220e200241086a41186a290300370300200241a8016a41106a220f200241086a41106a290300370300200241a8016a41086a2210200241086a41086a290300370300200220022903083703a80120094102460d01200020022903a801370000200020093a0021200020083a00202000200229038801370022200041186a200e290300370000200041106a200f290300370000200041086a20102903003700002000412a6a200b290300370000200041326a200c2903003700002000413a6a200d290300370000200041c2006a20013a0000200041c3006a2002290368370000200041cb006a2007290300370000200041d3006a2005290300370000200041db006a20062903003700002004450d002003102e0b200241d0016a24000f0b41eff0c2004133200241c8006a4184f4c2001053000bc40101037f230041206b220224002002410036021020014110200241106a10082101024002400240024020022802102203417f460d0020010d010b200041003602040c010b200220013602082002200336020c20034104490d0120022003417c6a36020c2002200141046a36020820012800002103200241106a200241086a104120022802102204450d012000200229021437020820002004360204200020033602002001102e0b200241206a24000f0b41eff0c2004133200241106a4184f4c2001053000b0a004198f3c2001058000b0a0041a8f2c2001058000bcd6704167f017e087f017e23004180036b2204240041002105200441003602f002200420023602ec02200420013602e8020240024002400240024002400240200241034b0d0041012106200441013a00d002200441ec016a4101360200200442013702dc01200441e8d4c5003602d801200441213602b4022004200441b0026a3602e8012004200441d0026a3602b00220044180016a200441d8016a108a042004280280012107200428028401210820042802880121094105210a4100210b0c010b200441043602f002024020012800004180c2cdeb06460d004101210a410121060c010b024002402002417c714104460d00200241074b0d0141082002105e000b41012106200441013a00d002200441ec016a4101360200200442013702dc01200441e8d4c5003602d801200441213602b4022004200441b0026a3602e8012004200441d0026a3602b00220044180016a200441d8016a108a042004280280012107200428028401210820042802880121094105210a410021054100210b0c010b200441083602f002410121060240200128000422074101460d004102210a0c010b200441d8016a200441e8026a10960402400240024020042802d8014101470d00410421084100210c410021090c010b200441d8016a410572210d410421084128210a410021054100210c410021094100210b02400340200441d0026a41026a2201200d41026a2d00003a00002004200d2f00003b01d002200428028402210e200428028002210f20042802fc01211020042802f801211120042802f401211220042802f001211320042802ec01211420042802e801211520042802e401211620042802e0012117024020042d00dc012206417e6a41ff0171410a4b0d004100211802400240024002400240024002400240024002400240024020060e0f0b0b000102030405060708090a0b0b0b0b410121180c0a0b410221180c090b410321180c080b410421180c070b410521180c060b410621180c050b410721180c040b410821180c030b410921180c020b410a21180c010b410b21180b0240200b41ff0171221920184d0d004113210a0c030b4100211802400240024002400240024002400240024002400240024020060e0f0b0b000102030405060708090a0b0b0b0b410121180c0a0b410221180c090b410321180c080b410421180c070b410521180c060b410621180c050b410721180c040b410821180c030b410921180c020b410a21180c010b410b21180b024020192018470d004114210a0c030b4100210b0240024002400240024002400240024002400240024020060e0f0b0b000102030405060708090a0b0b0b0b4101210b0c0a0b4102210b0c090b4103210b0c080b4104210b0c070b4105210b0c060b4106210b0c050b4107210b0c040b4108210b0c030b4109210b0c020b410a210b0c010b410b210b0b20044180016a41026a221820012d00003a0000200420042f01d0023b01800102400240200c2009470d00200c41016a2201200c490d072005200120012005491b2209ad422c7e221a422088a70d07201aa722014100480d0702400240200c0d002001102921080c010b2008200a41586a2001102a21080b2008450d010b2008200a6a220141586a20063a00002001200e3602002001417c6a200f360200200141786a2010360200200141746a2011360200200141706a20123602002001416c6a2013360200200141686a2014360200200141646a2015360200200141606a20163602002001415c6a2017360200200141596a220120042f0180013b0000200141026a20182d00003a0000200541026a2105200a412c6a210a200c41016a210c200441d8016a200441e8026a10960420042802d8014101460d030c010b0b20014104102c000b024002402006410d4b0d00024002400240024002400240024002400240024002400240024020060e0e0001020304050607080e090a0b0c000b2016450d0d2017102e0c0d0b02402016450d002017102e0b2013450d0c2014102e0c0c0b02402015450d00201541047421062017210103400240200141046a280200450d002001280200102e0b200141106a2101200641706a22060d000b0b2016450d0b2017102e0c0b0b02402015450d00201541286c21062017210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200641586a22060d000b0b2016450d0a2017102e0c0a0b2016450d092017102e0c090b2016450d082017102e0c080b2016450d072017102e0c070b02402015450d00201720154104746a210d201721050340024020052802082206450d0020052802002101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200641706a22060d000b0b200541106a21010240200541046a280200450d002005280200102e0b200121052001200d470d000b0b2016450d062017102e0c060b02402015450d00201541146c21062017210103400240200141046a280200450d002001280200102e0b200141146a21012006416c6a22060d000b0b2016450d052017102e0c050b02402015450d0020172015411c6c6a210d20172105034002402005410c6a2802002206450d0020052802042101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200641706a22060d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21010240200541146a280200450d002005280210102e0b200121052001200d470d000b0b2016450d042017102e0c040b02402015450d002017201541186c6a210d2017210503400240200541046a280200450d002005280200102e0b0240200541146a2802002206450d00200528020c2101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200641706a22060d000b0b200541186a21010240200541106a280200450d00200528020c102e0b200121052001200d470d000b0b2016450d032017102e0c030b02402015450d0020172015411c6c6a210d20172105034002402005410c6a2802002206450d0020052802042101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200641706a22060d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21010240200541146a280200450d002005280210102e0b200121052001200d470d000b0b2016450d022017102e0c020b0240201741ff0171220141024b0d0002400240024020010e03000102000b2015450d042016102e0c040b02402013450d002013410c6c2106201521010340024020012802002205450d00200141046a280200450d002005102e0b2001410c6a2101200641746a22060d000b0b2014450d032015102e0c030b02402013450d00201520134104746a21162015211703402017220d41106a21170240200d2802042201450d000240200d410c6a2802002206450d002006410c6c21060340024020012802002205450d00200141046a280200450d002005102e0b2001410c6a2101200641746a22060d000b0b200d41086a280200450d00200d280204102e0b20172016470d000b0b2014450d022015102e0c020b2015450d012016102e0c010b02402016450d002017102e0b02402013450d002012450d002013102e0b200f450d002010102e0b0c010b024020042d00dc010d00200c412c6c210641002105410021010240034020062001460d01200820016a210a2001412c6a220b2101200a2d0000410b470d000b2008200b6a41606a28020021050b200c412c6c21064100210d410021010240034020062001460d01200820016a210a2001412c6a220b2101200a2d00004104470d000b200441f8006a2008200b6a41586a10b703200428027c210d0b02402005200d470d004100210a4101210741e100210b41f3da012105410021060c030b0240200c450d00200c412c6c210a200821010340200110bf032001412c6a2101200a41546a220a0d000b0b410121064119210a024020090d000c030b2008102e0c020b20042802dc01220a4110762105200a410876210b200441d8016a41106a280200210d200441e4016a2802002117200441d8016a41086a28020021070b0240200c450d00200c412c6c2106200821010340200110bf032001412c6a2101200641546a22060d000b0b4101210602402009450d002008102e0b200d2109201721080b02402006450d00200821060c040b20042802f0022002470d022005411074200b41ff017141087472200a41ff017172211b2008200c412c6c6a210a20082101024002400340200a2001460d0120012d000021022001412c6a2206210120024102470d000b200441f0006a200641586a10b7034104211c200428027021024100211002400240024002400240200428027422010d004100211d0c010b2001410474220a4100480d06200a1029221c450d012001211d0b02402001450d002001410474210641002110201c21010340200241086a280200220a417f4c0d032002410c6a2d0000210b2002280200210502400240200a0d004101210d0c010b200a1029220d450d050b200d2005200a10f60421052001410d6a2002410d6a2d00003a00002001410c6a200b3a0000200141086a200a360200200141046a200a36020020012005360200200141106a2101201041016a2110200241106a2102200641706a22060d000b0b201c450d030c040b200a4104102c000b1032000b200a4101102c000b4100211d4104211c410021100b2008200c412c6c6a210a20082101024003404100210641c8ecc500210b0240200a2001470d00410021010c020b20012d000021022001412c6a2205210120024103470d000b200441e8006a200541586a10b7034100210120042802682202450d00200428026c21012002210b0b0240024020010d0041012112410021134100210a4100210e410421154100210b4100211e41042114410421174100210241002105410021164100211f410121190c010b200141286c210d200b411c6a2101410421154100210641002113410121124100210a4100210e4100210b4100211e41042114410421174100210241002105410021164100211f41012119024002400240024002400340024002400240024002402001417c6a2d00000e0400010203000b2001280200210f0240024020052002460d00200521110c010b200241016a22112002490d0c20024101742218201120112018491b221841ffffffff03712018470d0c201841027422114100480d0c0240024020020d002011102921170c010b201720024102742011102a21170b2017450d0620022111201821020b201720114102746a200f360200200541016a21050c030b200441d8016a41086a220f200141086a280200360200200420012902003703d8010240200a200e470d00200a41016a220e200a490d0b200a4101742211200e200e2011491b220ead420c7e221a422088a70d0b201aa722114100480d0b02400240200a0d002011102921150c010b2015200a410c6c2011102a21150b2015450d060b2015200a410c6c6a221120042903d801370200201141086a200f280200360200200a41016a210a0c020b200441d8016a41086a220f200141086a280200360200200420012902003703d8010240200b201e470d00200b41016a2211200b490d0a200b4101742218201120112018491b221ead420c7e221a422088a70d0a201aa722114100480d0a02400240200b0d002011102921140c010b2014200b410c6c2011102a21140b2014450d060b2014200b410c6c6a221120042903d801370200201141086a200f280200360200200b41016a210b0c010b2001417e6a220f2d000021112001417d6a22182d00002120024020062013470d00200641016a22132006490d0920064101742221201320132021491b221320136a22222013490d0920224100480d090240024020060d002022102921120c010b201220212022102a21120b2012450d060b201220064101746a222220114101713a0001202220203a0000200f2d0000210f20182d000021110240201f2016470d00201641016a22182016490d0920164101742220201820182020491b221f201f6a2218201f490d0920184100480d090240024020160d002018102921190c010b201920202018102a21190b2019450d070b200641016a2106201920164101746a2218200f4101713a0001201820113a0000201641016a21160b200141286a2101200d41586a220d450d060c000b0b20114104102c000b20114104102c000b20114104102c000b20224101102c000b20184101102c000b2008200c412c6c6a210f200821010240024002400240024002400240024002400240024002400240024003400240200f2001470d002002210d0c020b20012d0000210d2001412c6a22112101200d4104470d000b200441e0006a201141586a10b70302402004280264220d0d002002210d0c010b20042802602101200d410274210f0340200128020021110240024020052002460d002002210d200521180c010b200241016a220d2002490d1020024101742218200d200d2018491b220d41ffffffff0371200d470d10200d41027422184100480d100240024020020d002018102921170c010b201720024102742018102a21170b2017450d0320022118200d21020b200141046a2101201720184102746a2011360200200541016a2105200f417c6a220f0d000b0b2008200c412c6c6a210f20082101024002400340200f2001460d0120012d000021022001412c6a2211210120024105470d000b200441d8006a201141586a10b703200428025c410c6c2218450d0020042802582101200a410174210f200a410c6c21020340200141086a2111024002400240200141046a2802004101470d002004201128020022203602c0022001280200222220204b0d010b20044100360280010c010b200441023602ec01200442023702dc01200441d0b1c5003602d801200441013602f402200441013602ec02200420223602d0022004200441e8026a3602e8012004200441d0026a3602f0022004200441c0026a3602e80220044180016a200441d8016a108a04200428028001450d0020044180016a21010c0e0b2001290200211a200441d8016a41086a222020112802003602002004201a3703d8010240200a200e470d00200a41016a220e200a490d11200f200e200e200f491b220ead420c7e221a422088a70d11201aa722114100480d1102400240200a0d002011102921150c010b201520022011102a21150b2015450d030b2001410c6a2101201520026a221120042903d801370200201141086a2020280200360200200f41026a210f2002410c6a2102200a41016a210a201841746a22180d000b0b2008200c412c6c6a210f20082101024002400340200f2001460d0120012d000021022001412c6a2211210120024106470d000b200441d0006a201141586a10b70320042802542202450d00200428025021012002410c6c2111200b410174210f200b410c6c21020340200441d8016a2001109904024020042802d801450d00200441d8016a21010c0f0b2001290200211a200441d8016a41086a2218200141086a2802003602002004201a3703d8010240200b201e470d00200b41016a221e200b490d12200f201e201e200f491b221ead420c7e221a422088a70d12201aa722204100480d1202400240200b0d002020102921140c010b201420022020102a21140b2014450d030b2001410c6a2101201420026a222020042903d801370200202041086a2018280200360200200f41026a210f2002410c6a2102200b41016a210b201141746a22110d000b0b2008200c412c6c6a210f20082101024002400240024002400340200f2001460d0120012d000021022001412c6a2211210120024107470d000b200441c8006a201141586a10b703200428024c2202450d002004280248220120024104746a212220064101742102200441d8016a41047221200340200441d8016a200120192016109a0402400240024020042d00d8014101460d00200420042d00d901220f3a00c0020240200f2001410c6a2d00002211470d0020044100360280010c030b200441023602ec01200442023702dc01200441e4b2c5003602d801200441223602f402200441223602ec02200420113a00d0022004200441e8026a3602e8012004200441c0026a3602f0022004200441d0026a3602e80220044180016a200441d8016a108a040c010b20044180016a41086a202041086a28020036020020042020290200370380010b0240200428028001450d0020044180016a21010c140b2001410c6a2d0000210f0b2001410d6a2d00002111024020062013470d00200641016a22132006490d162002201320132002491b221320136a22182013490d1620184100480d160240024020060d002018102921120c010b201220022018102a21120b2012450d030b201220026a2218200f3a0000201841016a20114101713a0000200241026a2102200641016a2106200141106a22012022470d000b0b200441b8016a2005360200200441b4016a200d36020020044180016a412c6a2010360200200441a8016a201d360200200441a0016a20063602002004419c016a201336020020044194016a200a36020020044190016a200e360200200420173602b0012004201c3602a40120042012360298012004201536028c012004200b360288012004201e3602840120042014360280012008200c412c6c6a210a20082101024003400240200a2001470d004100210b0c020b20012d000021022001412c6a2206210120024104470d000b200441c0006a200641586a10b7032004280244210b0b2004200b3602bc012008200c412c6c6a210a20082101024003400240200a2001470d00410021010c020b20012d000021022001412c6a220621012002410b470d000b200641606a28020021010b200420013602c001200b2001470d0d0240200b450d002008200c412c6c6a210a200821010340200a2001460d0520012d000021022001412c6a2206210120024104470d000b2008200c412c6c6a210b200821010340200b2001460d0420012d000021022001412c6a220a21012002410b470d000b200441386a200641586a10b703200428023c2201450d002004280238220d20014102746a2115200a41606a2117200a41586a211620044191026a2111410021050340200420053602c4012017280200210120162802002102200442013702dc01200441e8a7c5003602d801200441013602d402200441013602ec012004200441d0026a3602e8012004200441c4016a3602d002200441e8026a200441d8016a108a0420042802e802210a20042902ec02211a200120054d0d110240201aa7450d00200a102e0b2004200d28020022013602d002024002400240024020042802ac0120014b0d00200441013602ec01200442023702dc01200441dcb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a108a0420042902ec02221a422088a7210120042802e8022106201aa721020c010b0240024002402002200541186c6a22022802142210450d0020042802a40120014104746a220a2d000d2113200a280200210e200228020c210120022802002114200a280208220f2106024020022802082212450d002012410374210b200f21022014210a034002402002200a2802006a220620024f0d0002404120102922060d0041204101102c000b200641186a41002900acb845370000200641106a41002900a4b845370000200641086a410029009cb84537000020064100290094b8453700000c040b200a41086a210a20062102200b41786a220b0d000b0b0240410810292202450d0020022013ad42ff0183422886370200200441d0026a41026a220a200441e8026a41026a2d00003a0000200420042f00e8023b01d002200420133a00900220044180800136028c022004428180808010370284022004200236028002200442808080808080103703f801200442013703f001200420063602ec01200420123602e801200420143602e4012004200f3602e0012004200e3602dc01200420044180016a3602d801201120042f01d0023b0000201141026a200a2d00003a00002010410474210a41002102034020042002360298022004200136029c02200441b0026a200441d8016a2001109c04024020042802b002450d00200441c0026a41086a200441b0026a41086a280200360200200420042903b0023703c002200441033602e402200442033702d4022004419c9fc5003602d002200441233602fc02200441013602f402200441243602ec022004200441e8026a3602e0022004200441c0026a3602f802200420044198026a3602f00220042004419c026a3602e802200441a0026a200441d0026a108a04024020042802c402450d0020042802c002102e0b20042802a0022206450d0020042902a402211a024020042802f401450d0020042802f001102e0b201a42208821230240200428028402450d00200428028002102e0b2023a72101201aa721020c070b200141106a2101200241016a2102200a41706a220a0d000b02402004280288020d00024020042802f401450d0020042802f001102e0b200428028402450d07200428028002102e0c070b41b49fc5001058000b41084104102c000b412010292206450d01200641186a41002900919f45370000200641106a41002900899f45370000200641086a41002900819f45370000200641002900f99e453700000b41202102412021010c010b41204101102c000b2006450d010b200420063602d00220042001ad4220862002ad843702d4022004200441d0026a3602c002200441023602ec01200442023702dc01200441f0a7c5003602d801200441253602f402200441013602ec022004200441e8026a3602e8012004200441c0026a3602f0022004200441c4016a3602e802200441c8016a200441d8016a108a04024020042802d402450d0020042802d002102e0b20042802c801220a450d0020042902cc01211a0c120b200541016a2105200d41046a220d2015470d000b0b2008200c412c6c6a210a2008210102400340200a2001460d0120012d000021022001412c6a2206210120024109470d000b2004200641586a28020022013602b002024020042802b80120014b0d00200441ec016a4101360200200442023702dc01200441ccb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441e8026a200441d8016a108a040c0d0b200420042802b00120014102746a28020022013602d002024020042802ac0120014b0d00200441ec016a4101360200200442023702dc01200441dcb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a108a040c0d0b024020042802a40120014104746a22013502084200520d00200131000d4220864280808080f000834280808080c000510d010b412d1029220a450d02200a41256a41002900a5a845370000200a41206a41002900a0a845370000200a41186a4100290098a845370000200a41106a4100290090a845370000200a41086a4100290088a845370000200a4100290080a84537000042ad808080d005211a0c100b2008200c412c6c6a210a200821010340200a2001460d0b20012d000021022001412c6a2206210120024108470d000b200441306a200641586a220110b703200441d8016a2004280234109f04200441e8026a41086a200441e4016a290200370300200441e8026a41106a200441d8016a41146a280200360200200420042902dc013703e802200441286a200110b703200428022c2201450d0920042802282215200141146c6a210e034020152217450d0a410021022017280208220d210120172802002216210a0240200d4104490d004100210220162101200d210a0340200128000020024105777341b9f3ddf1796c2102200141046a2101200a417c6a220a41034b0d000b200d417c6a22012001417c71220a6b2101200a20166a41046a210a0b02400240200141014b0d00200a21060c010b200a41026a21062001417e6a21012002410577200a2f00007341b9f3ddf1796c21020b02402001450d00200241057720062d00007341b9f3ddf1796c21020b201741146a2115200241057741ff017341b9f3ddf1796c22024119762213410874201372220141107420017221054100210f20042802f002211220042802e802210b20042802ec0221062002210103400240200b200120067122016a2800002214200573220a417f73200a41fffdfb776a7141808182847871220a450d00024003400240200d2012200a6841037620016a2006714103746a221041046a280200470d00201620102802002210460d0220162010200d10f804450d020b200a417f6a200a71220a450d020c000b0b200441ec016a4101360200200442013702dc01200441b0a8c5003602d8012004411c3602b4022004200d3602c402200420163602c0022004200441b0026a3602e8012004200441c0026a3602b002200441d0026a200441d8016a108a040c0a0b200f41046a220f20016a2101201420144101747141808182847871450d000b024020042802f8020d00200441e8026a10a00420042802e802210b20042802ec0221060b200620027121024104210103402002220a20016a2006712102200141046a2101200b200a6a280000418081828478712205450d000b0240200b200568410376200a6a20067122016a2c000022024100480d00200b200b280200418081828478716841037622016a2d000021020b200b20016a20133a00002001417c6a200671200b6a41046a20133a000020042802f00220014103746a200dad4220862016ad84370200200420042802f40241016a3602f402200420042802f80220024101716b3602f802024002400240024002400240201728020c0e0400030201000b2004201728021022013602a002024020042802b80120014b0d00200441ec016a4101360200200442023702dc01200441ccb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441a0026a3602c002200441d0026a200441d8016a108a040c0e0b200420042802b00120014102746a28020022013602b00220042802ac0120014b0d03200441013602ec01200442023702dc01200441dcb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441d0026a200441d8016a108a040c0d0b2004201728021022013602a002024020042802a00120014b0d00200441ec016a4101360200200442023702dc01200441fcb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441a0026a3602c002200441d0026a200441d8016a108a040c0d0b20042802980120014101746a2d0001450d02200441ec016a4101360200200442023702dc012004419cb6c5003602d801200441013602c4022004200441c0026a3602e8012004200441a0026a3602c002200441d0026a200441d8016a108a040c0c0b2004201728021022013602b00220042802880120014b0d01200441013602ec01200442023702dc01200441fcb4c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441d0026a200441d8016a108a0420042802d002220a0d0c0c010b2004201728021022013602b00220042802940120014d0d010b2015200e470d010c0b0b0b200441ec016a4101360200200442023702dc01200441acb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441d0026a200441d8016a108a040c070b20184101102c000b412d4101102c000b419ea7c50041c800109b01000b4180a7c500411e109b01000b20204104102c000b20114104102c000b20184104102c000b20042802d002210a0b20042902d402211a2006450d060240200641016a220141ffffffff01712001470d00200641086a417c712202200641056a490d00200220014103746a2002491a0b200b102e0c060b20042802ec022201450d000240200141016a220241ffffffff01712002470d00200141086a417c71220a200141056a490d00200a20024103746a200a491a0b20042802e802102e0b2008200c412c6c6a210a2008210102400340200a2001460d0120012d000021022001412c6a2206210120024103470d000b200441206a200641586a10b70320042802242201450d0020042802202106200141286c210b41002101034002400240024002400240200620016a220241186a2d00000e0400030201000b20042002411c6a28020022023602d00220042802ac0120024b0d03200441ec016a4101360200200442023702dc01200441dcb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a108a040c060b2002411a6a2d0000450d022002410c6a2802002101200241146a2802002102200441d8016a41146a4101360200200420023602d402200420013602d0022004411c3602c402200442013702dc01200441b8a8c5003602d8012004200441d0026a3602c0022004200441c0026a3602e801200441e8026a200441d8016a108a040c050b200441d8016a2002411c6a10990420042802d801220a450d0120042902dc01211a0c080b200241206a2802004101470d002002411c6a280200210a2004200241246a28020022023602b002200a20024d0d00200441023602ec01200442023702dc01200441d0b1c5003602d801200441013602f402200441013602ec022004200a3602c0022004200441e8026a3602e8012004200441c0026a3602f0022004200441b0026a3602e802200441d0026a200441d8016a108a0420042802d002220a0d060b200b200141286a2201470d000b0b024002400240200428029401220141014b0d00200428028801220141014b0d012008200c412c6c6a210a2008210102400240024002400340200a2001460d0120012d000021022001412c6a220621012002410c470d000b200441186a200641586a10b70320042802182201200428021c411c6c6a2106034020012006460d012004200128020022023602d002024020042802880120024b0d00200441013602ec01200442023702dc01200441fcb4c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a108a0420042802e802220a450d0020042902ec02211a0c0d0b200441d8016a200141046a220120042802980120042802a001109a0420042d00d8014101460d02200141186a210120042d00d901450d000b41201029220a450d06200a41186a41002900e8a845370000200a41106a41002900e0a845370000200a41086a41002900d8a845370000200a41002900d0a84537000042a08080808004211a0c0b0b2008200c412c6c6a210a2008210102400340200a2001460d0120012d000021022001412c6a220621012002410a470d000b200441106a200641586a10b70320042802142201450d002004280210220b2001411c6c6a21050340200b450d012004200b28020022013602d00220042802940120014d0d03200441d8016a200b41046a20042802980120042802a001109a0420042d00d8014101460d0420042d00d9010d09200441086a200b10a10402400240200428020c2201450d00200428020821022001410274210a20042802b801210603402004200228020022013602b0020240200620014b0d00200441ec016a4101360200200442023702dc01200441ccb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441e8026a200441d8016a108a040c0c0b200420042802b00120014102746a28020022013602d00220042802ac0120014d0d02200241046a2102200a417c6a220a0d000b0b200b411c6a220b2005460d020c010b0b200441013602ec01200442023702dc01200441dcb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a108a040c070b0240200428028401450d00200428028001102e0b0240200428029001450d00200428028c01102e0b0240200428029c01450d00200428029801102e0b024020042802ac012202450d0020042802a40121012002410474210203400240200141046a280200450d002001280200102e0b200141106a2101200241706a22020d000b0b024020042802a801450d0020042802a401102e0b024020042802b401450d0020042802b001102e0b201f450d0d2019102e0c0d0b200441e0016a290300211a20042802dc01210a0c090b200441ec016a4101360200200442023702dc01200441acb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a108a040c040b200441e0016a290300211a20042802dc01210a0c070b200441ec016a4101360200200442013702dc01200441c0a8c5003602d801200441013602d402200420013602c0022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a108a040c020b200441ec016a4101360200200442013702dc01200441c8a8c5003602d801200441013602d402200420013602c0022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a108a040c010b41204101102c000b20042802e802210a20042902ec02211a0c030b024041201029220a450d00200a41186a41002900e8a845370000200a41106a41002900e0a845370000200a41086a41002900d8a845370000200a41002900d0a84537000042a08080808004211a0c030b41204101102c000b200441ec016a4102360200200441f4026a4101360200200442023702dc01200441f0a6c5003602d801200441013602ec022004200441e8026a3602e8012004200441c0016a3602f0022004200441bc016a3602e802200441d0026a200441d8016a108a0420042802d002210a0b20042902d402211a0b0240200428028401450d00200428028001102e0b0240200428029001450d00200428028c01102e0b0240200428029c01450d00200428029801102e0b024020042802ac012202450d0020042802a40121012002410474210203400240200141046a280200450d002001280200102e0b200141106a2101200241706a22020d000b0b024020042802a801450d0020042802a401102e0b024020042802b401450d0020042802b001102e0b201f450d012019102e200a0d040c020b2001290204211a2001280200210a0240201f450d002019102e0b0240201e450d002014102e0b0240200e450d002015102e0b02402013450d002012102e0b02402010450d0020104104742102201c210103400240200141046a280200450d002001280200102e0b200141106a2101200241706a22020d000b0b0240201d450d00201c102e0b200d450d002017102e0b200a0d020b2000201b36020420004100360200200041186a2003360200200041146a200c360200200041106a20093602002000410c6a2008360200200041086a20073602000c040b102d000b0240201aa7450d00200a102e0b200041e8a1c50036020420004101360200200041086a41133602000240200c450d00200c412c6c2102200821010340200110bf032001412c6a2101200241546a22020d000b0b2009450d022008102e0c020b200441003a00d002200441ec016a4101360200200442013702dc01200441e8d4c5003602d801200441213602b4022004200441b0026a3602e8012004200441d0026a3602b00220044180016a200441d8016a108a04200428028001210720042802840121060240200c450d00200c412c6c2102200821010340200110bf032001412c6a2101200241546a22020d000b0b4105210a2009450d002008102e0b02402006450d00200a41ff01714105470d002007102e0b200041d2a1c50036020420004101360200200041086a41163602000b20044180036a24000b160020002001280208360204200020012802003602000bd41301177f23004190026b220224000240024002400240024002402000280200220341e08dc000460d00200028020421040c010b41002104200241b8016a410041d80010f5041a2002411f6a220542003700002002420037011a41ec0010292203450d0120034100360200200320022902183702042003410b6a2005290000370000200341136a200241b7016a41d90010f6041a20004100360204200020033602000b200141ff01712106024003402003410c6a2107200341086a210820032f010621094100210502400240034020092005460d01200820056a210a200741086a2107200541016a210502404100417f4101200a2d0000220a20064b1b200a2006461b41016a0e03000301000b0b2005417f6a21090b2004450d022004417f6a2104200320094102746a41ec006a28020021030c010b0b200742013702000c030b2000200028020841016a360208024002400240024020032f01062205410b490d00200241276a41016a410041d80010f5041a200241003a001941ec0010292204450d03200441003602002004410036000f20044200370007200420022f01183b0005200441136a200241276a41d90010f6041a2003410e6a2d0000210b2003280248210c2003280244210d200441086a2003410f6a20032f010641796a220510f6042107200441146a200341cc006a200541037410f6042106200341063b0106200420053b010620094107490d0120072009417a6a220a6a2007200941796a22096a2207200541ffff037120096b10f7041a200720013a00002006200a4103746a200620094103746a2207200441066a22052f010020096b41037410f7041a2007410136020020052f010021070c020b200341086a2207200941016a22066a200720096a2207200520096b220a10f7041a200720013a0000200341146a220720064103746a200720094103746a2207200a41037410f7041a200741013602002003200541016a3b01060c050b200341086a2205200941016a22066a200520096a220a200341066a22052f0100220720096b220810f7041a200a20013a0000200341146a220a20064103746a200a20094103746a2209200841037410f7041a200941013602000b2005200741016a3b01002003280200220a450d02200341046a2105200241276a41016a210e200241a8016a210f200241a0016a211020024198016a211120024190016a211220024180016a41086a2113034020052f0100210602400240024002400240200a2f01062205410b490d00200e410041d80010f5041a200241003a0019200220022f01183b0108200241b7016a200241276a41d90010f6041a200f4200370300201042003703002011420037030020124200370300201342003703002002420037038001419c0110292207450d03200741003602002007410036000f20074200370007200720022f01083b0005200741136a200241b7016a41d90010f6041a20074194016a200f2903003702002007418c016a201029030037020020074184016a2011290300370200200741fc006a2012290300370200200741f4006a2013290300370200200720022903800137026c200a41c8006a2802002114200a41c4006a2802002115200a410e6a2d00002116200741086a200a410f6a200a2f0106220341796a220510f6042117200741146a200a41cc006a200541037410f6042118200741ec006a200a4188016a2003417a6a220841027410f6042101200a41063b0106200720053b010602402008450d00410021052001210303402003280200220920053b010420092007360200200341046a21032008200541016a2205470d000b0b20064107490d0120172006417a6a22036a2017200641796a22056a220920072f010620056b10f7041a2009200b3a0000201820034103746a201820054103746a220920072f010620056b41037410f7041a2009200d3602002009200c360204200720072f010641016a22093b01062006410274220b20016a416c6a200120034102746a2208200941ffff0371220620036b41027410f7041a2008200436020020062003490d022007200b6a41d4006a2103034020032802002209200541016a22053b010420092007360200200341046a210320052006490d000c030b0b200a41086a2207200641016a22036a200720066a2207200520066b220910f7041a2007200b3a0000200a41146a220720034103746a200720064103746a2207200941037410f7041a2007200d3602002007200c360204200a200541016a22053b01062006410274200a41ec006a22076a41086a200720034102746a2207200541ffff0371220920036b41027410f7041a20072004360200200620094f0d08200a2003417f6a22054102746a41f0006a2103034020032802002207200541016a22053b01042007200a360200200341046a210320052009490d000c090b0b200a41086a2203200641016a22056a200320066a2203200a2f0106220920066b220810f7041a2003200b3a0000200a41146a220320054103746a200320064103746a2203200841037410f7041a2003200d3602002003200c360204200a200941016a22033b010620064102742201200a41ec006a22096a41086a200920054102746a2208200341ffff0371220920056b41027410f7041a20082004360200200620094f0d00200a20016a41f0006a2105034020052802002203200641016a22063b01042003200a360200200541046a210520092006470d000b0b200a28020022030d01200721042014210c2015210d2016210b0c050b419c014104102c000b200a41046a21052003210a2016210b2015210d2014210c200721040c000b0b41ec004104102c000b41ec004104102c000b200241b7016a41016a410041d80010f5041a2002411f6a220542003700002002420037011a200220022902183703082002200529000037000f200241276a200241b7016a41d90010f6041a200241a8016a22034200370300200241a0016a2207420037030020024180016a41186a2209420037030020024190016a2206420037030020024180016a41086a220a42003703002002420037038001419c0110292205450d0120054100360200200520022903083702042005410b6a200229000f370000200541136a200241276a41d90010f6041a20054194016a20032903003702002005418c016a200729030037020020054184016a2009290300370200200541fc006a2006290300370200200541f4006a200a290300370200200520022903800137026c20052000280200220336026c200020053602002000200028020441016a360204200341003b010420032005360200200520052f010622034103746a220741186a200c360200200741146a200d360200200520036a41086a200b3a0000200541ec006a200341016a22034102746a2004360200200520033b0106200420033b0104200420053602000b20024190026a24000f0b419c014104102c000bd11e01387f23004190016b2202240020024184016a4200370200200241fc006a4280808080c000370200200241ec006a4200370200200241e4006a4280808080c000370200200241d0006a4200370300200241c0006a4200370300200241386a4280808080c000370300200241286a4200370300200241206a4280808080c000370300200241106a4200370300200242043702742002420437025c20024204370348200242043703302002420437031820024280808080c000370308200242043703002001410c6a280200210320024180016a210420012802082105024002400240200141106a28020022060d00410421014100210741002108410021094100210a4104210b4100210c4100210d4104210e4100210f41002110410421114100211241002113410421144100210641002115410421164100211741002118410421194100211a4100211b4104211c4100211d4100211e4104211f41002120410021210c010b410021224100211f41002123410021244100211c410021254100212641002127410021284100212941002107024003402001212a2007211520052006417f6a2206412c6c6a2201280024211720012800202119200128001821182001280014211420012800102116200128000c210c2001280008210b200128000421094101210741012112024002400240024002400240024020012d0000220a417e6a2208410d4d0d00410121130c010b4101211341012110410121114101210f4101210d4101210e20092101024002400240024002400240024002400240024020080e0e000102030405060f0708090e0e11000b02402029450d000240202b450d00202b41047421072029210103400240200141046a280200450d002001280200102e0b200141106a2101200741706a22070d000b0b202c450d002029102e0b4101211341002112200c212b200b212c200921290c090b02402028450d000240202d450d00202d41286c21072028210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200741586a22070d000b0b202e450d002028102e0b4100211341012112200c212d200b212e200921280c080b0240202f450d002027450d002027102e0b20152107202a210120092127200b212f200c21300c0c0b02402031450d002026450d002026102e0b20152107202a210120092126200b2131200c21320c0b0b02402033450d002025450d002025102e0b20152107202a210120092125200b2133200c21340c0a0b0240201c450d000240201a450d00201c201a4104746a210d201c21080340024020082802082207450d0020082802002101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b200841106a21010240200841046a280200450d002008280200102e0b200121082001200d470d000b0b2035450d00201c102e0b4100211041012112200c211a200b21352009211c410121130c050b02402024450d000240201e450d00201e41146c21072024210103400240200141046a280200450d002001280200102e0b200141146a21012007416c6a22070d000b0b2036450d002024102e0b4100211141012112200c211e200b21362009212441012113410121100c050b02402023450d000240201d450d002023201d411c6c6a210d20232108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b0240200841086a280200450d002008280204102e0b2008411c6a21010240200841146a280200450d002008280210102e0b200121082001200d470d000b0b2037450d002023102e0b4100210f41012112200c211d200b2137200921234101211341012110410121110c050b0240201f450d000240201b450d00201f201b41186c6a210d201f210803400240200841046a280200450d002008280200102e0b0240200841146a2802002207450d00200828020c2101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b200841186a21010240200841106a280200450d00200828020c102e0b200121082001200d470d000b0b2020450d00201f102e0b4100210d41012112200c211b200b21202009211f4101211341012110410121114101210f4101210e0c050b02402022450d0002402038450d0020222038411c6c6a210d20222108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b0240200841086a280200450d002008280204102e0b2008411c6a21010240200841146a280200450d002008280210102e0b200121082001200d470d000b0b2039450d002022102e0b4100210e41012112200c2138200b2139200921224101211341012110410121114101210f4101210d0c040b410121100b410121110b4101210f0b4101210d4101210e0b02400240024002400240200a410d4b0d0020152107202a210102400240024002400240024002400240024002400240200a0e0e080900010202020304100506070a080b2012450d0e0240200c450d00200c41047421072009210103400240200141046a280200450d002001280200102e0b200141106a2101200741706a22070d000b0b200b450d0e0c0d0b2013450d0d200c450d00200c41286c21072009210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200741586a22070d000b0b200b0d0b0c0c0b2010450d0b0240200c450d002009200c4104746a210a200921080340024020082802082207450d0020082802002101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b200841106a21010240200841046a280200450d002008280200102e0b200121082001200a470d000b0b200b0d0a0c0b0b2011450d0a0240200c450d00200c41146c21072009210103400240200141046a280200450d002001280200102e0b200141146a21012007416c6a22070d000b0b200b0d090c0a0b200f450d090240200c450d002009200c411c6c6a210a20092108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b0240200841086a280200450d002008280204102e0b2008411c6a21010240200841146a280200450d002008280210102e0b200121082001200a470d000b0b200b0d080c090b200d450d080240200c450d002009200c41186c6a210a2009210803400240200841046a280200450d002008280200102e0b0240200841146a2802002207450d00200828020c2101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b200841186a21010240200841106a280200450d00200828020c102e0b200121082001200a470d000b0b200b0d070c080b200e450d07200c450d002009200c411c6c6a210a20092108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b0240200841086a280200450d002008280204102e0b2008411c6a21010240200841146a280200450d002008280210102e0b200121082001200a470d000b0b200b0d050c060b0240200b450d002009102e0b2014450d052016102e0c050b0240200941ff0171220141024b0d0002400240024020010e03000102000b200c450d070c050b02402014450d002014410c6c2107200c21010340024020012802002208450d00200141046a280200450d002008102e0b2001410c6a2101200741746a22070d000b0b2016450d060c030b02402014450d00200c20144104746a210b200c210a0340200a220941106a210a024020092802042201450d0002402009410c6a2802002207450d002007410c6c21070340024020012802002208450d00200141046a280200450d002008102e0b2001410c6a2101200741746a22070d000b0b200941086a280200450d002009280204102e0b200a200b470d000b0b20160d020c050b200c0d020c040b0240200b450d002009102e0b02402014450d002018450d002014102e0b2017450d032019102e0c030b200c102e0c020b200b102e0c010b2009102e0b20152107202a21010b20060d000b410021062001212a200721150b201b4100201f1b210720204100201f1b2108201d410020231b21212037410020231b2120201e410020241b21092036410020241b210a201a4100201c1b211e20354100201c1b211d2034410020251b210c2033410020251b210d2032410020261b211b2031410020261b211a2030410020271b210f202f410020271b2110202d410020281b2118202e410020281b2117202b410020291b2112202c410020291b2113201f4104201f1b21012023410420231b211f2024410420241b210b201c4104201c1b211c2025410420251b210e2026410420261b21192027410420271b21112028410420281b21162029410420291b211420220d010b4104212241002139410021380b200410c8040240200228028401450d00200228028001102e0b200241d8006a202a3602002002200636028801200220033602840120022005360280012002203836027c2002203936027820022022360274200220073602702002200836026c2002200136026820022021360264200220203602602002201f36025c20022015360254200220093602502002200a36024c2002200b3602482002201e3602442002201d3602402002201c36023c2002200c3602382002200d3602342002200e3602302002201b36022c2002201a360228200220193602242002200f3602202002201036021c2002201136021820022018360214200220173602102002201636020c20022012360208200220133602042002201436020020002002418c0110f6041a20024190016a24000bc30a01107f230041106b220224000240024002400240024020012802004101470d00200141106a2d000021032001410c6a2802002104200141086a280200210520012f0112210620012d0011210720012802042108200241086a200010b70320022802082201200228020c22094104746a210a4100210b20094104490d01200341ff0171210c024002400340024020012d000c200c470d0020012802082004470d002001280200210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d000d2209410446220f200741ff0171220d410446220e470d002009200d460d06200e0d06200f0d060b024002402001411c6a2d0000200c470d00200141186a2802002004470d002001280210210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d001d2209410446220f200741ff0171220d410446220e470d002009200d460d01200e0d01200f0d010b02402001412c6a2d0000200c470d00200141286a2802002004470d002001280220210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d002d2209410446220f200741ff0171220d410446220e470d002009200d460d03200e0d03200f0d030b02402001413c6a2d0000200c470d00200141386a2802002004470d002001280230210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d003d2209410446220f200741ff0171220d410446220e470d002009200d460d04200e0d04200f0d040b200b41046a210b200a200141c0006a22016b41304d0d050c010b0b200b410172210b0c040b200b410272210b0c030b200b410372210b0c020b2001280204210b0c030b2001200a460d0102400240200741ff017122114104460d00200341ff0171210c0c010b200341ff0171210c0340024020012d000c200c470d0020012802082004470d002001280200210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d000d4104460d030b200b41016a210b200141106a2201200a470d000c030b0b0340024020012d000c200c470d0020012802082004470d002001280200210e200421092008210d024003402009450d012009417f6a2109200d2d0000210f200e2d00002110200d41016a210d200e41016a210e2010200f460d000c020b0b20012d000d22092011470d0020094104470d020b200b41016a210b200141106a2201200a460d020c000b0b2005450d012008102e0c010b02400240200041046a28020020002802082201460d00200028020021090c010b02400240200141016a22092001490d002001410174220d20092009200d491b220d41ffffffff0071200d470d00200d410474220e4100480d000240024020010d00200e102921090c010b20002802002001410474200e102a21090b2009450d0120002009360200200041046a200d360200200028020821010c020b102d000b200e4104102c000b200920014104746a220120063b010e200120073a000d200120033a000c2001200436020820012005360204200120083602002000200028020841016a3602082002200010b7032002280204417f6a210b0b200241106a2400200b0bcc21032d7f017e017f230041306b2202240020012802042103200128020021044101210502400240024002400240024002400240024002400240024002400240024002400240200128020822060d004104210741002108410121090c010b412c10292207450d01200741023a0000200720022f002d3b00012007200636000c200720033600082007200436000420072002290208370210200741036a2002412d6a41026a2d00003a0000200741186a200241106a290200370200200741206a200241186a290200370200200741286a200241086a41186a28020036020041002109410121080b200141106a280200210a200128020c210b02400240200141146a280200220c0d002008210d0c010b2008410174220d200841016a220e200e200d491b220d412c6c210e0240024020080d00200e102921070c010b20072008412c6c200e102a21070b2007450d0220072008412c6c6a220e41033a0000200e20022f002d3b0001200e200c36000c200e200a360008200e200b360004200e2002290208370210200e41036a2002412f6a2d00003a0000200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021050b2001411c6a280200210f200128021821104100211102400240200141206a28020022120d00410021130c010b0240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22142014200e491b220ead422c7ea722144100480d0e02400240200d0d002014102921070c010b2007200d412c6c2014102a21070b2007450d04200e210d0b20072008412c6c6a220e41043a0000200e201236000c200e200f360008200e2010360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a28020036020041012113200841016a21080b200141286a28020021122001280224211502402001412c6a2802002214450d000240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22112011200e491b220ead422c7ea722114100480d0e02400240200d0d002011102921070c010b2007200d412c6c2011102a21070b2007450d05200e210d0b20072008412c6c6a220e41053a0000200e201436000c200e2012360008200e2015360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a28020036020041012111200841016a21080b200141346a28020021142001280230211602400240200141386a28020022170d00410021180c010b0240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22192019200e491b220ead422c7ea722194100480d0e02400240200d0d002019102921070c010b2007200d412c6c2019102a21070b2007450d06200e210d0b20072008412c6c6a220e41063a0000200e201736000c200e2014360008200e2016360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a28020036020041012118200841016a21080b200141c0006a280200211a200128023c211b4101211702400240200141c4006a280200221c0d004101211d0c010b0240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22192019200e491b220ead422c7ea722194100480d0e02400240200d0d002019102921070c010b2007200d412c6c2019102a21070b2007450d07200e210d0b20072008412c6c6a220e41073a0000200e201c36000c200e201a360008200e201b360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a21084100211d0b200141cc006a280200211e2001280248211f0240200141d0006a2802002220450d000240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22172017200e491b220ead422c7ea722174100480d0e02400240200d0d002017102921070c010b2007200d412c6c2017102a21070b2007450d08200e210d0b20072008412c6c6a220e41083a0000200e202036000c200e201e360008200e201f360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241086a41086a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021170b41012119024020012802544101470d00200141d8006a28020021210240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22222022200e491b220ead422c7ea722224100480d0e02400240200d0d002022102921070c010b2007200d412c6c2022102a21070b2007450d09200e210d0b20072008412c6c6a220e41093a0000200e2021360204200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370208200e41106a200241106a290200370200200e41186a200241086a41106a290200370200200e41206a200241086a41186a290200370200200e41286a200241086a41206a280200360200200841016a21080b200141e0006a2802002123200128025c21220240200141e4006a2802002224450d000240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22192019200e491b220ead422c7ea722194100480d0e02400240200d0d002019102921070c010b2007200d412c6c2019102a21070b2007450d0a200e210d0b20072008412c6c6a220e410a3a0000200e202436000c200e2023360008200e2022360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021190b200141ec006a2802002125200128026821264101212102400240200141f0006a28020022270d00410121280c010b0240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22292029200e491b220ead422c7ea722294100480d0e02400240200d0d002029102921070c010b2007200d412c6c2029102a21070b2007450d0b200e210d0b20072008412c6c6a220e410b3a0000200e202736000c200e2025360008200e2026360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021280b200141f8006a280200212a200128027421290240200141fc006a280200222b450d000240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22212021200e491b220ead422c7ea722214100480d0e02400240200d0d002021102921070c010b2007200d412c6c2021102a21070b2007450d0c200e210d0b20072008412c6c6a220e410c3a0000200e202b36000c200e202a360008200e2029360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021210b20014184016a280200212c200128028001210e02400240200d20086b20014188016a280200412c6c222d412c6d2201490d00200820016a21010c010b200820016a22012008490d0d200d410174222e20012001202e491b222ead422c7e222f422088a70d0d202fa722304100480d0d02400240200d0d002030102921070c010b2007200d412c6c2030102a21070b2007450d0c202e210d0b20072008412c6c6a200e202d10f6041a0240202c450d00200e102e0b41c00510292208450d0d2000200736020820004280c2cdeb16370200200241086a410c6a4210370200200041106a20013602002000410c6a200d3602002002200836021020024280c2cdeb16370308200241106a10c8042008102e2021450d0e0240202b450d002029202b411c6c6a210d20292107034002402007410c6a2802002208450d0020072802042101200841047421080340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200841706a22080d000b0b0240200741086a280200450d002007280204102e0b2007411c6a21010240200741146a280200450d002007280210102e0b200121072001200d470d000b0b202a450d0e2029102e0c0e0b412c4104102c000b200e4104102c000b20144104102c000b20114104102c000b20194104102c000b20194104102c000b20174104102c000b20224104102c000b20194104102c000b20294104102c000b20214104102c000b20304104102c000b102d000b41c0054104102c000b02402028450d0002402027450d002026202741186c6a210d2026210703400240200741046a280200450d002007280200102e0b0240200741146a2802002208450d00200728020c2101200841047421080340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200841706a22080d000b0b200741186a21010240200741106a280200450d00200728020c102e0b200121072001200d470d000b0b2025450d002026102e0b02402019450d0002402024450d0020222024411c6c6a210d20222107034002402007410c6a2802002208450d0020072802042101200841047421080340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200841706a22080d000b0b0240200741086a280200450d002007280204102e0b2007411c6a21010240200741146a280200450d002007280210102e0b200121072001200d470d000b0b2023450d002022102e0b02402017450d0002402020450d00202041146c2108201f210103400240200141046a280200450d002001280200102e0b200141146a21012008416c6a22080d000b0b201e450d00201f102e0b0240201d450d000240201c450d00201b201c4104746a210d201b21070340024020072802082208450d0020072802002101200841047421080340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200841706a22080d000b0b200741106a21010240200741046a280200450d002007280200102e0b200121072001200d470d000b0b201a450d00201b102e0b02402014410047201841017371450d002016102e0b02402012410047201141017371450d002015102e0b0240200f410047201341017371450d002010102e0b02402005450d000240200c450d00200c41286c2108200b210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200841586a22080d000b0b200a450d00200b102e0b02402009450d0002402006450d00200641047421082004210103400240200141046a280200450d002001280200102e0b200141106a2101200841706a22080d000b0b2003450d002004102e0b200241306a24000b860501017f411021010240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710eac010001020202020202020202020202020303030404050506060707080809090a0a0b0b0c0d0d0e0e0f0f1010111213131414151516161717181819191a1a1b1b1c1c1d1d1e1e1f1f2020212122222323242425252627272828292a2a2b2b2c2d2d2e2e2f2f303031313232333434353536363737383839393a3a3b3b3c3c3d3d3e3e3f3f40404141424243434444454546464747484a4a4a4a49494a4a4a4a4a4a4a4a4a4a4a4a4a4a4b4b4b4b000b41110f0b41120f0b410a0f0b41080f0b41080f0b41040f0b41040f0b41040f0b41040f0b41040f0b41040f0b41040f0b41050f0b41050f0b41050f0b41050f0b41050f0b41130f0b41140f0b41060f0b41070f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410c0f0b410c0f0b410c0f0b410c0f0b410c0f0b410c0f0b41000f0b41000f0b41010f0b41020f0b41030f0b41030f0b41000f0b41000f0b41000f0b41000f0b41000f0b41000f0b41010f0b41020f0b41030f0b41030f0b41000f0b41000f0b41000f0b41000f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410e0f0b410e0f0b410f21010b20010bfe0101057f02400240024002400240200041086a28020022032001490d002003200041046a280200460d01200341016a2104200028020021050c020b41c0c6c5001058000b200341016a22042003490d0220034101742205200420042005491b220641ffffffff00712006470d02200641047422074100480d020240024020030d002007102921050c010b200028020020034104742007102a21050b2005450d0120002005360200200041046a20063602000b200520014104746a220541106a2005200320016b41047410f7041a200541086a200241086a29030037030020052002290300370300200041086a20043602000f0b20074108102c000b102d000b800502067f017e230041306b22022400200241106a200141246a290200370300200241086a2001411c6a29020037030020022001290214370300200241186a41106a200141106a280200360200200241186a41086a200141086a290200370300200220012902003703182000200241186a10ba032103024002400240024002402000411c6a280200200041206a2802002204460d00200028021821050c010b200441016a22052004490d0320044101742206200520052006491b220641ffffffff03712006470d03200641027422074100480d030240024020040d002007102921050c010b200028021820044102742007102a21050b2005450d01200020053602182000411c6a2006360200200028022021040b200520044102746a20033602002000200028022041016a360220200241186a41106a200241106a290300370300200241186a41086a200241086a2903003703002002200229030037031802400240200041ec006a280200200041f0006a2802002204460d00200028026821050c010b200441016a22052004490d0320044101742203200520052003491b2203ad42187e2208422088a70d032008a722064100480d030240024020040d002006102921050c010b2000280268200441186c2006102a21050b2005450d0220002005360268200041ec006a2003360200200041f0006a28020021040b2005200441186c6a22042002290318370200200441106a200241186a41106a290300370200200441086a200241186a41086a290300370200200041f0006a22042004280200220441016a360200024020012d002c450d0020004101360254200041d8006a20043602000b200241306a24000f0b20074104102c000b20064104102c000b102d000bcf0d01067f0240024020002d00002201410d4b0d00024002400240024002400240024002400240024002400240024020010e0e0001020304050607080e090a0b0c000b200041086a280200450d0d200041046a280200102e0f0b0240200041086a280200450d00200041046a280200102e0b200041146a280200450d0c200041106a280200102e0f0b02402000410c6a2802002202450d00200041046a28020021012002410474210203400240200141046a280200450d002001280200102e0b200141106a2101200241706a22020d000b0b200041086a280200450d0b2000280204102e0f0b02402000410c6a2802002202450d00200041046a2802002101200241286c210203400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200241586a22020d000b0b200041086a280200450d0a2000280204102e0f0b200041086a280200450d09200041046a280200102e0f0b200041086a280200450d08200041046a280200102e0f0b200041086a280200450d07200041046a280200102e0f0b02402000410c6a2802002201450d00200041046a280200220320014104746a21040340024020032802082202450d0020032802002101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b200341106a21010240200341046a280200450d002003280200102e0b2001210320012004470d000b0b200041086a280200450d062000280204102e0f0b02402000410c6a2802002202450d00200041046a2802002101200241146c210203400240200141046a280200450d002001280200102e0b200141146a21012002416c6a22020d000b0b200041086a280200450d052000280204102e0f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a2104034002402003410c6a2802002202450d0020032802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b0240200341086a280200450d002003280204102e0b2003411c6a21010240200341146a280200450d002003280210102e0b2001210320012004470d000b0b200041086a280200450d042000280204102e0f0b02402000410c6a2802002201450d00200041046a2802002203200141186c6a210403400240200341046a280200450d002003280200102e0b0240200341146a2802002202450d00200328020c2101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b200341186a21010240200341106a280200450d00200328020c102e0b2001210320012004470d000b0b200041086a280200450d032000280204102e0f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a2104034002402003410c6a2802002202450d0020032802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b0240200341086a280200450d002003280204102e0b2003411c6a21010240200341146a280200450d002003280210102e0b2001210320012004470d000b0b200041086a280200450d022000280204102e0f0b0240200041046a2d0000220141024b0d0002400240024020010e03000102000b2000410c6a280200450d04200041086a280200102e0f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c21020340024020012802002203450d00200141046a280200450d002003102e0b2001410c6a2101200241746a22020d000b0b200041106a280200450d03200028020c102e0f0b0240200041146a2802002201450d002000410c6a280200220520014104746a210603402005220441106a2105024020042802042201450d0002402004410c6a2802002202450d002002410c6c21020340024020012802002203450d00200141046a280200450d002003102e0b2001410c6a2101200241746a22020d000b0b200441086a280200450d002004280204102e0b20052006470d000b0b200041106a280200450d02200028020c102e0c020b2000410c6a280200450d01200041086a280200102e0f0b0240200041086a280200450d00200041046a280200102e0b0240200041146a2802002201450d00200041186a280200450d002001102e0b200041246a280200450d00200041206a280200102e0f0b0bb07e07087f017e1b7f027e017f017e197f23002203210420034180096b41607122032400024002400240024002400240024002400240024002400240024002400240411010292205450d00200541063a0000412010292206450d01200641063a00104100210720064100360204200620032f00f0053b00012006412d3a0000200641036a200341f2056a2d00003a0000024020052d00004109470d00200528020841ffffffff0371450d002005280204102e0b2005102e200141106a2802002208412c6c21092001280208210a02400340024020092007470d00411010292205450d0520054180023b010c200542828080802037020420052006360200200520032f01d0033b010e02402001410c6a2802002008470d00200841016a22072008490d0f20084101742209200720072009491b2207ad422c7e220b422088a70d0f200ba722094100480d0f0240024020080d0020091029210a0c010b200a2008412c6c2009102a210a0b200a450d072001200a3602082001410c6a20073602000b2001200841016a220c360210200a2008412c6c6a220741073a0000200720032f00e0043b0001200742818080801037000820072005360004200720032902f005370210200741036a200341e2046a2d00003a0000200741186a200341f8056a290200370200200741206a20034180066a290200370200200741286a200341f0056a41186a2802003602004100210d0c020b200a20076a21052007412c6a220e210720052d00004107470d000b200320032f01d0033b01f005200a200e6a220541586a210a024002402005415c6a220c280200200541606a22092802002207460d00200a280200210e0c010b200741016a220e2007490d0d20074101742208200e200e2008491b220841ffffffff00712008470d0d2008410474220d4100480d0d0240024020070d00200d1029210e0c010b200541586a2802002007410474200d102a210e0b200e450d06200c2008360200200541586a200e360200200928020021070b200e20074104746a22074180023b010c200742828080802037020420072006360200200720032f01f0053b010e2009200928020041016a360200200341c0006a200a10b7032003280244417f6a210d2001280210210c2001280208210a0b200c412c6c2107200a41586a210502400340410021062007450d01200741546a2107200541286a21092005412c6a220e210520092d00004103470d000b200e41086a2802002207450d00200741286c2105200e28020041186a2107410021060340200620072d0000456a2106200741286a2107200541586a22050d000b0b200c412c6c2107200a41586a210502400340410021092007450d01200741546a2107200541286a210e2005412c6a22082105200e2d00004103470d000b200841086a2802002207450d00200741286c2105200828020041186a2107410021090340200920072d0000456a2109200741286a2107200541586a22050d000b0b200c412c6c2107200a41606a210502400340024020070d00410021070c020b200741546a2107200541206a210e2005412c6a220a2105200e2d00004104470d000b200a28020021070b200720096a220f41ffffffff0371200f470d0c200f4102742207417f4c0d0c0240024020070d00410421100c010b200710342210450d060b024002400240024002400240200f450d002010200f4102746a211141002112201021130340024020122006490d0020012802102214412c6c220921072001280208221541586a220e2105024003404100210a2007450d01200741546a2107200541286a21082005412c6a220c210520082d00004103470d000b200c41086a2802002207450d00200741286c2105200c28020041186a21074100210a0340200a20072d0000456a210a200741286a2107200541586a22050d000b0b2012200a6b220a20124b0d0303402009450d05200941546a2109200e41286a2107200e412c6a2205210e20072d0000410b470d000b200541086a280200200a4d0d052005280200200a41186c6a2802082105200341f0056a200a200110ba0420032802f405210720032802f0054101460d072013200720056a3602000b201241016a2112201341046a22132011470d000b0b20012802102114200128020821150c0f0b412c10292207450d0a200741286a4100280082c145360000200741206a41002900fac045370000200741186a41002900f2c045370000200741106a41002900eac045370000200741086a41002900e2c045370000200741002900dac04537000042ac808080c005210b0c020b412c10292207450d0a200741286a41002800aec145360000200741206a41002900a6c145370000200741186a410029009ec145370000200741106a4100290096c145370000200741086a410029008ec14537000020074100290086c14537000042ac808080c005210b0c010b411e10292207450d0a200741166a41002900c8c145370000200741106a41002900c2c145370000200741086a41002900bac145370000200741002900b2c145370000429e808080e003210b0b2010102e0c0a0b20032903f805210b2010102e20070d09410021100c0a0b41104108102c000b41204108102c000b41104104102c000b20094104102c000b200d4104102c000b20074104102c000b412c4101102c000b412c4101102c000b411e4101102c000b410021100c030b02402014450d0020152014412c6c6a2116200341e0046a41146a2117200341e0076a2118200341f0056a41017221190340024020152d0000410b470d00201528020c2207450d002015280204220a200741186c6a211a03400240200a41146a220c2802002207450d00200a410c6a21124100210e0240024002400240024002400340200e20074f0d014101210702402012280200200e41047422136a22052d0000410b470d002003200541046a22053602c0022010450d04200f200528020022054d0d03201020054102746a2802002209450d00201920032f00e0043b0000201941026a200341e0046a41026a2d00003a0000200341123a00f0052003200d3602d407200341133a00d007200341d7003a00c007200320093602b4072003412d3a00b0072003200d3602a407200341123a00a00720032005360294072003410b3a009007200341063a008007200341003a00f00620034184083b01e006200341373a00d006200320023602c4062003412d3a00c0062003200d3602b406200341123a00b0062003200d3602a406200341133a00a006200341d6003a00900620032009360284062003412d3a0080062003200d3602f405200c2802002211200e4d0d05200c200e360200200a28020c2107200320183602f804200320123602f0042003200720136a220841106a22063602e8042003200e41016a22143602e0042003201120146b221b3602e404200320072014410474221c6a221d3602ec042003200341f0056a3602f40420062107024020082d0000220941ac01460d004100210702400340200820076a21050240200941ff01714109470d00200541086a28020041ffffffff0371450d00200541046a280200102e0b2007450d012003200541206a3602e804200741106a2107200541106a2d0000220941ac01470d000b200820076a41106a21070c010b200541106a21070b02402007201d460d00034020032007220541106a22073602e8040240024020052d000022094109460d00200941ac01470d010c030b200541086a28020041ffffffff0371450d00200541046a280200102e0b20062007470d000b0b0240024002400240201b450d0002402014200a2802142207470d00200341f0056a2107201821080c030b2013200741047422076b2109200a28020c20076a2105200341f0056a21072018210603400240024020072006470d00410021070c010b2003200741106a3602f4040b200341d0036a200710c00420032d00d00341ac01460d04200520032903d003370300200541086a200341d0036a41086a290300370300200a200a28021441016a3602142009450d02200541106a2105200941706a210920032802f804210620032802f40421070c000b0b2012201710c1040c020b20032802f804210820032802f40421070b0240200820076b2205450d000240024020032802f004220641046a221d280200221320116b20054104762209490d00200628020021050c010b201120096a22052011490d1020134101742211200520052011491b221141ffffffff00712011470d102011410474221e4100480d100240024020130d00201e102921050c010b20062802002013410474201e102a21050b2005450d0920062005360200201d20113602000b2005201420096a22134104746a2005201c6a201b41047410f7041a200320133602e004201320062802082205460d00200e20096a410474200541047422056b2109200628020020056a210503400240024020072008470d00410021070c010b2003200741106a3602f4040b200341d0036a200710c00420032d00d00341ac01460d02200520032903d003370300200541086a200341d0036a41086a2903003703002006200628020841016a3602082009450d01200541106a2105200941706a210920032802f804210820032802f40421070c000b0b200341003602d803200342083703d003200341d0036a201710c10420032802d003221b20032802d803220541047422086a210620032802d403211c201b210702402005450d000240024020032802f004221341046a221d280200220720032802e404221420032802e00422056a22116b20084104752209490d00201328020021070c010b201120096a221e2011490d1020074101742211201e201e2011491b221141ffffffff00712011470d102011410474221e4100480d100240024020070d00201e102921070c010b20132802002007410474201e102a21070b2007450d0a20132007360200201d20113602000b2007200520096a220941047422116a200720054104746a201441047410f7041a200320093602e004201b2107200920132802082205460d002013280200220720116a211d200720054104746a2109201b21050340024020080d00200621070c020b200341d0036a41026a2207200541036a2d00003a0000200320052f00013b01d003024020052d0000221441ac01470d00200541106a21070c020b200541046a290200210b2005410c6a2802002111200920143a00002009410c6a2011360200200941046a200b37020020032f01d0032114200941036a20072d00003a0000200941016a20143b00002013201328020841016a360208200841706a2108200541106a22072105200941106a2209201d470d000b0b024020072006460d0003400240024020072d000022054109460d00200541ac01470d010c030b200741086a28020041ffffffff0371450d00200741046a280200102e0b200741106a22072006470d000b0b201c450d00201b102e0b024020032802e804220720032802ec042206460d00034020032007220541106a22073602e8040240024020052d000022094109460d00200941ac01470d010c030b200541086a28020041ffffffff0371450d00200541046a280200102e0b20062007470d000b0b024020032802e4042207450d00024020032802e004220620032802f004220841086a22092802002205460d002008280200220820054104746a200820064104746a200741047410f7041a0b2009200720056a3602000b024020032d00f0054109470d0020032802f80541ffffffff0371450d0020032802f405102e0b024020032d0080064109470d0020032802880641ffffffff0371450d00200328028406102e0b024020032d0090064109470d0020032802980641ffffffff0371450d00200328029406102e0b024020032d00a0064109470d0020032802a80641ffffffff0371450d0020032802a406102e0b024020032d00b0064109470d0020032802b80641ffffffff0371450d0020032802b406102e0b024020032d00c0064109470d0020032802c80641ffffffff0371450d0020032802c406102e0b024020032d00d0064109470d0020032802d80641ffffffff0371450d0020032802d406102e0b024020032d00e0064109470d0020032802e80641ffffffff0371450d0020032802e406102e0b024020032d00f0064109470d0020032802f80641ffffffff0371450d0020032802f406102e0b024020032d0080074109470d0020032802880741ffffffff0371450d00200328028407102e0b024020032d0090074109470d0020032802980741ffffffff0371450d00200328029407102e0b024020032d00a0074109470d0020032802a80741ffffffff0371450d0020032802a407102e0b024020032d00b0074109470d0020032802b80741ffffffff0371450d0020032802b407102e0b024020032d00c0074109470d0020032802c80741ffffffff0371450d0020032802c407102e0b024020032d00d0074109470d0020032802d80741ffffffff0371450d0020032802d407102e0b410f21070b2007200e6a220e200c2802002207490d000c070b0b41d0c1c500200e20071038000b2003410136028406200342013702f405200341e0c1c5003602f005200341263602d4032003200341d0036a360280062003200341c0026a3602d003200341e0046a200341f0056a108a0420032802e0042207450d0420032902e404210b0c0b0b418ec0c50041cc00109b01000b418cc6c5001058000b201e4108102c000b201e4108102c000b200a41186a220a201a470d000b0b2015412c6a22152016470d000b0b200341c8006a41106a200141106a280200221f360200200341c8006a41086a200141086a290200220b37030020032001290200370348201f412c6c2107200ba7222041586a210502400340024020070d00410021070c020b200741546a2107200541286a21092005412c6a220e210520092d00004108470d000b200341386a200e10b70320032802382107200328023c21050b2005410020071b2106201f412c6c2105202041586a2109200741c8ecc50020071b210702400340024020050d004100210e0c020b200541546a2105200941286a210e2009412c6a220a2109200e2d0000410a470d000b200341306a200a10b7032003280230210e200328023421050b20054100200e1b2108201f412c6c2105202041586a2109200e41c8ecc500200e1b211e02400340024020050d00410021210c020b200541546a2105200941286a210e2009412c6a220a2109200e2d00004109470d000b200a2802002109410121210b20034200370274200341e08dc000360270201e2008411c6c6a21222007200641146c6a2106200341e0046a410272220141266a2123200141186a21244100211741002125410021264100210c4100211c4104211a410421110240024002400240410041ff01710e03000102000b410021050c020b410221050c010b410121050b03400240024002400240024002400240024002400240024020050e03000105050b0240201741ff01710e03020700020b20264101470d02410021050c030b2021450d0441022119410021214100211d200921050c060b024002400240034002400240024002400240200620076b413c4b0d00024020072006460d002007410c6a21050340200728020c450d03200541146a2105200741146a22072006470d000b200621070b20264101470d02410021050c030b200728020c0d032007410c6a2105200741146a21070c070b200541086a21070c060b410121050b0340024002400240024020050e020001010b20182025470d014101212620252118410121050c030b41022117201e2022460d0e200341106a201e10a104201e411c6a211e20032802102205450d0f200520032802144102746a2125200521180c010b201841046a210e024020180d004101212641022117200e21180c0f0b201828020021054101212641022117410021192009211d200e21180c0c0b410021050c000b0b200741206a2205280200450d01200741346a2205280200450d02200741c8006a2105200741d0006a220e210720052802000d000b200e21070c020b200741286a21070c010b2007413c6a21070b20052802042105410021192009211d410021170c050b410121050b0340024002400240024020050e020001010b20182025470d014101212620252118410121050c030b41022117201e2022460d07200341186a201e10a104201e411c6a211e20032802182205450d082005200328021c4102746a2125200521180c010b201841046a210e024020180d004101212641022117200e21180c080b201828020021054101212641022117410021192009211d200e21180c050b410021050c000b0b02400240024002400240201741ff01710e03010400010b20264101470d01410021050c020b024002400240034002400240024002400240200620076b413c4b0d00024020072006460d002007410c6a21050340200728020c450d03200541146a2105200741146a22072006470d000b200621070b20264101470d02410021050c030b200728020c0d032007410c6a2105200741146a21070c070b200541086a21070c060b410121050b0340024002400240024020050e020001010b20182025470d01410121050c030b201e2022460d0b200341206a201e10a10420032802202218450d0b201e411c6a211e201820032802244102746a21250c010b2018450d0a2018280200210541012119410221172009211d201841046a2118410121260c0c0b410021050c000b0b200741206a2205280200450d01200741346a2205280200450d02200741c8006a2105200741d0006a220e210720052802000d000b200e21070c020b200741286a21070c010b2007413c6a21070b2005280204210541002117410121192009211d0c050b410121050b0340024002400240024020050e020001010b20182025470d01410121050c030b201e2022460d04200341286a201e10a10420032802282218450d04201e411c6a211e2018200328022c4102746a21250c010b2018450d032018280200210541012119410221172009211d201841046a2118410121260c050b410021050c000b0b024002400240024003400240200620076b413c4b0d0020072006460d06200741106a21050340200728020c450d03200541146a2105200741146a22072006470d000c070b0b0240200728020c0d002007410c6a2105200741146a2107200528020421050c050b200741206a2205280200450d02200741346a2205280200450d03200741c8006a2105200741d0006a220e210720052802000d000b200e2107200528020421050c030b200541046a2107200528020021050c020b200741286a2107200528020421050c010b2007413c6a2107200528020421050b410121192009211d410121170c020b200341e0006a41086a200341f0006a41086a28020036020020032003290370370360201f412c6c2107202041586a210502400340410021092007450d01200741546a2107200541286a210e2005412c6a220a2105200e2d00004103470d000b200a41086a2802002207450d00200741286c2105200a28020041186a2107410021090340200920072d0000456a2109200741286a2107200541586a22050d000b0b201f412c6c2107202041606a210502400340024020070d00410021070c020b200741546a2107200541206a210e2005412c6a220a2105200e2d00004104470d000b200a28020021070b200341f0056a41106a200341c8006a41106a280200360200200341f0056a41086a200341c8006a41086a290300370300200320032903483703f005200341b0016a200341f0056a10b9030240200c450d002011200c4102746a2118200720096a211b200341e0076a2112200341e7046a211703402011220741046a21112007280200210a200341e0006a21072003280264210803402007280200220641086a210520062f0106220c4102742107417f210902400340024020070d00200c21090c020b2005280200210e2007417c6a2107200941016a2109200541046a210502404100417f4101200e200a4b1b200e200a461b41016a0e03020001020b0b200641346a20094105746a22132802182105201328021c21072003200d3602d407200341133a00d007200341d7003a00c007200320073602b4072003412d3a00b0072003200d3602a407200341123a00a00720032005360294072003410b3a009007200341063a008007200341003a00f00620034184083b01e006200341373a00d006200320023602c4062003412d3a00c0062003200d3602b406200341123a00b0062003200d3602a406200341133a00a006200341d6003a00900620032007360284062003412d3a0080062003200d3602f405200341123a00f0052013280208220a41106a220e41ffffffff0071200e470d0a200e4104742207417f4c0d0a201341086a21190240024002400240024020070d004108210c0c010b20071029220c450d012019280200210a0b0240200a0d00410021050c030b4100210941002107034002402007200e470d00200e41016a2205200e490d0e200e4101742206200520052006491b220541ffffffff00712005470d0e200541047422064100480d0e02400240200e0d0020061029210c0c010b200c200e4104742006102a210c0b200c450d032005210e0b200c20096a2205410f3a0000200541046a2007360200200541016a20032f01d0033b0000200541036a200341d0036a41026a2d00003a0000200941106a2109200741016a22052107200a2005460d030c000b0b20074108102c000b20064108102c000b02400240024002400240024002400240200e20056b410f4f0d002005410f6a22072005490d11200e4101742209200720072009491b220741ffffffff00712007470d11200741047422094100480d1102400240200e0d0020091029210c0c010b200c200e4104742009102a210c0b200c450d012007210e0b200c20054104746a2107200341f0056a2109034020052108024002400240024020092d00002205414f6a41fb004f0d000c010b02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e312c2c0001022c2c0304052c06072c2c08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292c0b20092d00012106410221050c2b0b20092d00012106410321050c2a0b20092d00012106410421050c290b200941046a280200210a410721050c270b200941046a280200210a410821050c260b2009280208221d41ffffffff0371201d470d39201d4102742205417f4c0d390240024020050d004104210a0c010b20051029220a450d2a0b0240201d450d0020092802042105201d4102742114200a2106034020062005280200360200200641046a2106200541046a21052014417c6a22140d000b0b200935020c422086201dad84210b410921050c250b200941046a280200210a410b21050c240b200941046a280200210a20092d00012106410c21050c240b200941046a280200210a410f21050c220b200941046a280200210a411021050c210b200941046a280200210a411121050c200b200941046a280200210a411221050c1f0b200941046a280200210a411321050c1e0b200941046a280200210a2009350208210b411421050c1d0b200941046a280200210a2009350208210b411521050c1c0b200941046a280200210a2009350208210b411621050c1b0b200941046a280200210a2009350208210b411721050c1a0b200941046a280200210a2009350208210b411821050c190b200941046a280200210a2009350208210b411921050c180b200941046a280200210a2009350208210b411a21050c170b200941046a280200210a2009350208210b411b21050c160b200941046a280200210a2009350208210b411c21050c150b200941046a280200210a2009350208210b411d21050c140b200941046a280200210a2009350208210b411e21050c130b200941046a280200210a2009350208210b411f21050c120b200941046a280200210a2009350208210b412021050c110b200941046a280200210a2009350208210b412121050c100b200941046a280200210a2009350208210b412221050c0f0b200941046a280200210a2009350208210b412321050c0e0b200941046a280200210a2009350208210b412421050c0d0b200941046a280200210a2009350208210b412521050c0c0b200941046a280200210a2009350208210b412621050c0b0b200941046a280200210a2009350208210b412721050c0a0b200941046a280200210a2009350208210b412821050c090b200941046a280200210a2009350208210b412921050c080b200941046a280200210a2009350208210b412a21050c070b20092d00012106412b21050c070b20092d00012106412c21050c060b200941046a280200210a412d21050c040b2009290308210b412e21050c020b200941046a280200210a412f21050c020b2009290308210b413021050b0b0b200720063a0001200720053a0000200741086a200b370300200741046a200a360200200841016a2105200741106a2107200941106a22092012470d000b02400240200e2005460d00200e21090c010b200e41016a2207200e490d11200e4101742205200720072005491b220941ffffffff00712009470d11200941047422074100480d1102400240200e0d0020071029210c0c010b200c200e4104742007102a210c0b200c450d03200e21050b200c20054104746a220741063a0000200720032900e004370001200741086a2017290000370000200341e0046a200341b0016a418c0110f6041a411010292205450d03200541063a0000200341d0036a200341e0046a418c0110f6041a20192802002207417f4c0d110240024020070d004101210a41014101200710f6041a2007ad210b410021070c010b2013280200210e20071029220a450d05200a200e200710f604210e20071029220a450d06200a200e200710f6041a200e102e2007ad210b0b200341e0046a200341d0036a418c0110f6041a201331000d2127200341d0036a200341e0046a418c0110f6041a200341e0046a200341d0036a418c0110f6041a200341c0026a200341e0046a418c0110f6041a41101029220e450d06200841026a210620284280808080808040832228200b842027422886844280808080800c84210b200e41063a0000200e102e200341d0036a200341c0026a418c0110f6041a200341e0046a200341d0036a418c0110f6041a024020052d00004109470d00200528020841ffffffff0371450d002005280204102e0b2005102e200341c0026a200341e0046a418c0110f6041a200341e0046a200341c0026a418c0110f6041a200341003602fc03200320063602f803200320093602f4032003200c3602f003200341003602ec03200342043702e4032003200b3702dc03200320073602d8032003200a3602d403200341013602d003200341e0046a200341d0036a10be03200341b0016a200341e0046a418c0110f6041a201341013602102013201b360214024020032d00f0054109470d0020032802f80541ffffffff0371450d0020032802f405102e0b024020032d0080064109470d0020032802880641ffffffff0371450d00200328028406102e0b024020032d0090064109470d0020032802980641ffffffff0371450d00200328029406102e0b024020032d00a0064109470d0020032802a80641ffffffff0371450d0020032802a406102e0b024020032d00b0064109470d0020032802b80641ffffffff0371450d0020032802b406102e0b024020032d00c0064109470d0020032802c80641ffffffff0371450d0020032802c406102e0b024020032d00d0064109470d0020032802d80641ffffffff0371450d0020032802d406102e0b024020032d00e0064109470d0020032802e80641ffffffff0371450d0020032802e406102e0b024020032d00f0064109470d0020032802f80641ffffffff0371450d0020032802f406102e0b024020032d0080074109470d0020032802880741ffffffff0371450d00200328028407102e0b024020032d0090074109470d0020032802980741ffffffff0371450d00200328029407102e0b024020032d00a0074109470d0020032802a80741ffffffff0371450d0020032802a407102e0b024020032d00b0074109470d0020032802b80741ffffffff0371450d0020032802b407102e0b024020032d00c0074109470d0020032802c80741ffffffff0371450d0020032802c407102e0b024020032d00d0074109470d0020032802d80741ffffffff0371450d0020032802d407102e0b20284280808080808c01842128201b41016a211b20112018470d090c0a0b20094108102c000b20054104102c000b20074108102c000b41104108102c000b20074101102c000b20074101102c000b41104108102c000b02402008450d002008417f6a2108200620094102746a4194036a21070c010b0b0b4198c7c500418001109b01000b0240201c450d00201a102e0b200341f0056a200341b0016a418c0110f6041a200341e0046a200341f0056a10bb030240200341e0046a41106a2802002207450d0020032802e80422192007412c6c6a211d0340024020192d000041786a220741024b0d0002400240024020070e03000102000b201928020c2207450d0220192802042209200741146c6a211203400240200928020c0d002009280210210c2003280264210d200341e0006a210703402007280200220841286a210e200841086a210520082f010622134102742107417f210a02400340024020070d002013210a0c020b200528020021062007417c6a2107200a41016a210a200e41206a210e200541046a210502404100417f41012006200c4b1b2006200c461b41016a0e03020001020b0b0240200e417c6a280200450d002009200e2802003602100c030b4198c8c5004135109b01000b200d450d01200d417f6a210d2008200a4102746a4194036a21070c000b0b200941146a22092012470d000c030b0b201928020421082003280264210c200341e0006a210703402007280200220641286a2109200641086a210520062f0106220d4102742107417f210e02400340024020070d00200d210e0c020b2005280200210a2007417c6a2107200e41016a210e200941206a2109200541046a210502404100417f4101200a20084b1b200a2008461b41016a0e03020001020b0b02402009417c6a280200450d00201920092802003602040c040b4198c8c5004135109b01000b200c450d02200c417f6a210c2006200e4102746a4194036a21070c000b0b201928020c2207450d00201928020422112007411c6c6a211b0340024020112802182207450d002011280210220d20074102746a21140340200d221241046a210d201228020021082003280264210c200341e0006a210703402007280200220641286a2109200641086a210520062f010622134102742107417f210e024002400340024020070d002013210e0c020b2005280200210a2007417c6a2107200e41016a210e200941206a2109200541046a210502404100417f4101200a20084b1b200a2008461b41016a0e03020001020b0b02402009417c6a280200450d00201220092802003602000c020b4198c8c5004135109b01000b200c450d00200c417f6a210c2006200e4102746a4194036a21070c010b0b200d2014470d000b0b2011411c6a2211201b470d000b0b2019412c6a2219201d470d000b0b200341ec046a290200210b20032802e004210720032902e404212820032802602003280264200328026810c304200041106a200b370200200041086a202837020020002007360204200041003602002010450d08200f450d082010102e200424000f0b0240024002400240024003400240200620076b413c4b0d004101211720072006460d09200741106a21050340200728020c450d03200541146a2105200741146a22072006470d000b200621070c090b0240200728020c0d002007410c6a2105200741146a21070c050b200741206a2205280200450d02200741346a2205280200450d03200741c8006a2105200741d0006a220e210720052802000d000b200e21070c030b200541046a2107200528020021050c030b200741286a21070c010b2007413c6a21070b200528020421050b41012117410021192009211d0b2003200536027c0240024002400240024002400240024002402010450d000240200f20054b0d002003410136028406200342023702f40520034188c7c5003602f005200341013602d4032003200341d0036a360280062003200341fc006a3602d003200341e0046a200341f0056a108a0420032902e404220b422088a7210920032802e0042113200ba721290c090b201020054102746a2802002209450d0402400240201c200c470d00200c41016a220e200c490d0e200c410174220a200e200e200a491b221c41ffffffff0371201c470d0e201c410274220e4100480d0e02400240200c0d00200e1029211a0c010b201a200c410274200e102a211a0b201a450d01201a21110b2011200c4102746a2005360200200341f0056a200328027c2208200341c8006a10bf0420032802f805212920032802f4052113024020032802f00522164101470d0020032802fc0521090c0a0b20132802082205417f4c0d0e20132d000c210a02400240024020050d004101210e0c010b2013280200211220051029220e450d01200e2012200510f6041a0b2003200a3a008c01200320053602880120032005360284012003200e3602800120132d000d21052003200936029c012003200328027c360298012003410036029001200320053a008d010240024002402003280270220541e08dc000460d002003280274211b0c010b20234200370100200141206a420037010020244200370100200141106a4200370100200141086a420037010020014200370100200341f0056a410041e00210f5041a41940310292205450d014100211b20054100360200200520032903e0043702042005410c6a200341e0046a41086a290300370200200541146a200341e0046a41106a2903003702002005411c6a200341e0046a41186a290300370200200541246a200341e0046a41206a2903003702002005412c6a200341e0046a41286a290300370200200541346a200341f0056a41e00210f6041a20034100360274200320053602700b200c41016a210c0340200541146a210e20052f010622154102742114417f210a4100210902400340024020142009470d002015210a0c020b200520096a2112200941046a2109200a41016a210a200e41206a210e02404100417f4101201241086a280200221220084b1b20122008461b41016a0e03020001020b0b200e290200210b200e200329038001370200200e41186a200329039801370200200e41106a220529020021282005200329039001370200200e41086a200329038801370200202842ffffffff0f83420285500d08200b42808080807083500d08200ba7102e0c080b0240201b450d00201b417f6a211b2005200a4102746a4194036a28020021050c010b0b2003200328027841016a360278200329039801210b20032903900121282003290388012127200329038001212a20052f0106220e410b490d0420234200370100200141206a222b420037010020244200370100200141106a222c4200370100200141086a222d420037010020014200370100200341f0056a410041e00210f5041a024041940310292209450d0020094100360200200920032903e0043702042009410c6a200341e0046a41086a222e290300370200200941146a200341e0046a41106a222f2903003702002009411c6a200341e0046a41186a2230290300370200200941246a200341e0046a41206a22312903003702002009412c6a200341e0046a41286a2232290300370200200941346a200341f0056a41e00210f6042112200341f0056a41086a221b200541fc016a290200370300200341f0056a41106a221520054184026a290200370300200341f0056a41186a22332005418c026a290200370300200320052902f4013703f00520052802202134200941086a200541246a20052f010641796a220e41027410f6042114201220054194026a200e41057410f6042112200541063b01062009200e3b010620302033290300370300202f2015290300370300202e201b290300370300200320032903f0053703e00402400240200a4107490d002014200a417a6a22354102746a2014200a41796a220a4102746a2214200e41ffff0371200a6b41027410f7041a20142008360200201220354105746a2012200a4105746a220e200941066a22122f0100200a6b41057410f7041a200e41186a200b370200200e2028370210200e2027370208200e202a37020020122f010021140c010b200541086a220e200a41016a22354102746a200e200a4102746a220e200541066a22122f01002214200a6b223641027410f7041a200e2008360200200541346a220e20354105746a200e200a4105746a220e203641057410f7041a200e41186a200b370200200e2028370210200e2027370208200e202a3702000b2012201441016a3b0100200341d0036a41186a22372030290300220b370300200341d0036a41106a2238202f2903002228370300200341d0036a41086a2239202e2903002227370300200341b0016a41186a223a200b370300200341b0016a41106a223b2028370300200341b0016a41086a223c2027370300200320032903e004220b3703d0032003200b3703b0010240200528020022120d002009210e0c070b20052f010421352009213d0340200341c0026a41186a223e203a290300370300200341c0026a41106a223f203b290300370300200341c0026a41086a2240203c290300370300200320032903b0013703c002203541ffff037121080240024002400240024020122f01062205410b490d0020234200370100202b420037010020244200370100202c4200370100202d4200370100200142003701002039202e2903003703002038202f29030037030020372030290300370300200341d0036a41206a22052031290300370300200341d0036a41286a22092032290300370300200320032903e0043703d003200341f0056a410041900310f5041a41c4031029220e450d03200e4100360200200e20032903d003370204200e410c6a2039290300370200200e41146a2038290300370200200e411c6a2037290300370200200e41246a2005290300370200200e412c6a2009290300370200200e41346a200341f0056a41900310f6042109201241206a280200214120332012418c026a290200370300201520124184026a290200370300201b201241fc016a2902003703002003201241f4016a2902003703f005200e41086a201241246a20122f0106220a41796a220541027410f6042142200920124194026a200541057410f6042143200e4194036a201241b0036a200a417a6a221441027410f6042136201241063b0106200e20053b010602402014450d00410021052036210903402009280200220a20053b0104200a200e360200200941046a21092014200541016a2205470d000b0b20302033290300220b370300202f20152903002228370300202e201b2903002227370300200320032903f005222a3703e0042033200b37030020152028370300201b20273703002003202a3703f005203541ffff037122094107490d0120422008417a6a220a41027422146a2042200841796a22054102746a2209200e2f010620056b41027410f7041a200920343602002043200a4105746a204320054105746a2209200e2f010620056b41057410f7041a200941186a203e290300370200200941106a203f290300370200200941086a2040290300370200200920032903c002370200200e200e2f010641016a22093b01062008410274223520366a416c6a203620146a2214200941ffff03712208200a6b41027410f7041a2014203d3602002008200a490d02200e20356a41fc026a210903402009280200220a200541016a22053b0104200a200e360200200941046a210920052008490d000c030b0b201241086a2209200841016a220e410274220a6a2009200841027422146a2209200520086b221b41027410f7041a20092034360200201241346a2209200e4105746a200920084105746a2209201b41057410f7041a200941186a203e290300370200200941106a203f290300370200200941086a2040290300370200200920032903c0023702002012200541016a22053b0106201420124194036a22096a41086a2009200a6a2209200541ffff0371220a200e6b41027410f7041a2009203d3602002008200a4f0d0c2012200e417f6a22054102746a4198036a210903402009280200220e200541016a22053b0104200e2012360200200941046a21092005200a490d000c0d0b0b201241086a2205200841016a2214410274220a6a2005200841027422356a220520122f0106223620086b224241027410f7041a20052034360200201241346a220520144105746a200520084105746a2205204241057410f7041a200541186a203e290300370200200541106a203f290300370200200541086a2040290300370200200520032903c0023702002012203641016a22053b0106203520124194036a22366a41086a2036200a6a2236200541ffff0371220a20146b41027410f7041a2036203d3602002009200a4f0d00201220356a4198036a2105034020052802002209200841016a22083b010420092012360200200541046a2105200a2008470d000b0b203a2033290300370300203b2015290300370300203c201b290300370300200320032903f0053703b001201228020022050d01204121340c090b41c4034104102c000b20122f010421352005211220412134200e213d0c000b0b4194034104102c000b4194034104102c000b20054101102c000b200e4104102c000b418ec0c50041cc00109b01000b200541086a2209200a41016a22124102746a2009200a4102746a2209200e200a6b221441027410f7041a20092008360200200541346a220920124105746a2009200a4105746a2209201441057410f7041a200941186a200b37020020092028370210200920273702082009202a3702002005200e41016a3b01060c010b20234200370100202b420037010020244200370100202c4200370100202d4200370100200142003701002039202e2903003703002038202f29030037030020372030290300370300200341d0036a41206a22092031290300370300200341d0036a41286a220a2032290300370300200320032903e0043703d003200341f0056a410041900310f5041a41c40310292205450d0220054100360200200520032903d0033702042005410c6a2039290300370200200541146a20382903003702002005411c6a2037290300370200200541246a20092903003702002005412c6a200a290300370200200541346a200341f0056a41900310f604210820052003280270220936029403200320053602702003200328027441016a36027420092005360200200941003b0104200820052f0106220a4105746a220920032903b001370200200941186a203a290300370200200941106a203b290300370200200941086a203c2903003702002005200a4102746a41086a203436020020054194036a200a41016a22094102746a200e360200200520093b0106200e20093b0104200e20053602000b2016450d002029450d002013102e0b201d2109201941ff01710e03010205010b41c4034104102c000b410021050c040b410221050c030b20032802702003280274200328027810c3040240201c450d00201a102e0b0240201f450d00201f412c6c2105202021070340200710bf032007412c6a2107200541546a22050d000b0b0240200341d4006a280200450d002020102e0b2000201336020420004101360200200041086a2009ad4220862029ad843702002010450d06200f450d062010102e200424000f0b2022211e0b410121050c000b0b102d000b1032000b2000200736020420004101360200200041086a200b37020002402010450d00200f450d002010102e0b20012802082105024020012802102203450d002003412c6c2107200521030340200310bf032003412c6a2103200741546a22070d000b0b2001410c6a280200450d002005102e0b200424000b94830204117f017e037f017e230041e0006b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0f0100021211100f0e0d0c0b0a080706010b200141186a2802002104200141146a2802002105200141106a28020021062001410c6a2802002107200141086a2802002108200141046a28020021090240200241046a280200200241086a280200220a460d002002280200210b0c180b200a41016a220c200a490d14200a410174220d200c200c200d491b220c4100480d1402400240200a0d00200c1029210b0c010b2002280200200a200c102a210b0b200b450d042002200b360200200241046a200c360200200241086a280200210a0c170b2001410c6a280200210c200141086a2802002104200141046a280200210b20012d0001210502400240200241046a280200200241086a280200220a460d002002280200210d0c010b200a41016a220d200a490d14200a4101742206200d200d2006491b22064100480d1402400240200a0d0020061029210d0c010b2002280200200a2006102a210d0b200d450d032002200d360200200241046a2006360200200241086a280200210a0b200241086a2206200a41016a360200200d200a6a20053a000002400240200241046a280200220d2006280200220a6b200c490d002002280200210d0c010b200a200c6a2205200a490d14200d410174220a20052005200a491b220a4100480d1402400240200d0d00200a1029210d0c010b2002280200200d200a102a210d0b200d450d022002200d360200200241046a200a360200200241086a280200210a0b200241086a200a200c6a360200200d200a6a200b200c10f6041a4100210c41012107024020040d004101210d0c220b200b102e4101210d0c210b2001410c6a2802002106200141086a280200210e200141046a280200210f024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d14200a410174220d200c200c200d491b220d4100480d1402400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41013a0000200f20064104746a21104100210d4100210c41002105410121042006210a024003400240200c2005470d00200d200c41016a220b200b200d491b22054100480d1602400240200d0d002005102921040c010b2004200c2005102a21040b2004450d020b2004200c6a200a41807f72200a41ff0071200a410776220b1b3a0000200d41026a210d200c41016a210c200b210a200b0d000b024020060d00200f21080c130b200f210a02400340200a41106a2108200a2d000d22114105460d14200a2d000c210d200a2802082109200a2802042112200a28020021130240024002400240024002402005200c470d00200c41016a220a200c490d1c200c410174220b200a200a200b491b22054100480d1c02400240200c0d002005102921040c010b2004200c2005102a21040b2004450d010b2004200c6a200d3a0000200c41016a210a200c410174220c41046a2107200c41026a210d2009210c0340200721060240200a2005470d00200a41016a220b200a490d1d200d200b200b200d491b22054100480d1d02400240200a0d002005102921040c010b2004200a2005102a21040b2004450d030b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200641026a2107200d41026a210d200a41016a210a200b210c200b0d000b0240024020090d00200a210c0c010b4100210d0340200a200d6a210c41fc00210b02400240024002402013200d6a2d00000e050200010305020b41fe00210b0c020b41fd00210b0c010b41ff00210b0b0240200c2005470d00200c41016a2205200c490d1e2006200520052006491b22054100480d1e02400240200c0d002005102921040c010b2004200c2005102a21040b2004450d050b2004200a6a200d6a200b3a0000200641026a21062009200d41016a220d470d000b200a200d6a210c0b20120d030c040b20054101102c000b20054101102c000b20054101102c000b2013102e0b4100210a024020114104460d0002402005200c470d00200c41016a220a200c490d18200c410174220d200a200a200d491b22054100480d1802400240200c0d002005102921040c010b2004200c2005102a21040b2004450d030b2004200c6a41013a0000200c41016a210c201141077141ff0073210a0b024002402005200c470d00200c41016a220d200c490d18200c410174220b200d200d200b491b22054100480d1802400240200c0d002005102921040c010b2004200c2005102a21040b2004450d010b2004200c6a200a3a0000200c41016a210c2008210a20082010470d010c160b0b20054101102c000b20054101102c000b20054101102c000b200d4101102c000b200a4101102c000b20064101102c000b200c4101102c000b200141286a2802002104200141246a2802002111200141206a28020021092001411c6a2802002106200141186a2802002113200141146a28020021082001410c6a2902002114200141086a280200210d200141046a280200210b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d22200a4101742205200c200c2005491b22054100480d2202400240200a0d0020051029210c0c010b2002280200200a2005102a210c0b200c450d012002200c360200200241046a2005360200200241086a280200210a0b200241086a200a41016a36020041002105200c200a6a41003a0000200341dc006a41003602002003420137025420032002360250200320143e02482003200d3602442003200b360240200341086a200341c0006a200341d0006a109004024020032d0008220a411a460d0020032f000920032d000b41107472210c200341086a41086a2903002114200328020c21044100210d0c1e0b2014422088a7210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d23200a410174220b200d200d200b491b220b4100480d2302400240200a0d00200b1029210d0c010b2003280254200a200b102a210d0b200d450d032003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b4101211202402008450d00200320063602482003201336024420032008360240200341086a200341c0006a200341d0006a109004024020032d0008220a411a460d0020032f000920032d000b41107472210c200341106a2903002114200328020c21044100210d410121050c1f0b410021120b200920044104746a21062004210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d23200a410174220b200d200d200b491b220b4100480d2302400240200a0d00200b1029210d0c010b2003280254200a200b102a210d0b200d450d042003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b024020040d002009210b0c1d0b200441047441706a21072009210d0340200d41106a210b200d410c6a2802002102200d41086a280200210a200d280204210c0240024002400240024002400240024002400240200d2802000e09000102030405060727000b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2c200d4101742205200420042005491b22054100480d2c02400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d0e2003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41003a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2d200d4101742205200420042005491b22054100480d2d02400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d102003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2d200c4101742204200d200d2004491b22044100480d2d02400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d11200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000c080b0b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2b200d4101742205200420042005491b22054100480d2b02400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d102003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41013a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2c200d4101742205200420042005491b22054100480d2c02400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d122003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2c200c4101742204200d200d2004491b22044100480d2c02400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d13200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000c070b0b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2a200d4101742205200420042005491b22054100480d2a02400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d122003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41023a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2b200d4101742205200420042005491b22054100480d2b02400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d142003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2b200c4101742204200d200d2004491b22044100480d2b02400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d15200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000c060b0b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d29200d4101742205200420042005491b22054100480d2902400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d142003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41033a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2a200d4101742205200420042005491b22054100480d2a02400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d162003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2a200c4101742204200d200d2004491b22044100480d2a02400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d17200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000b200341086a2002200341d0006a10850420032d0008220a411a460d0520032f000920032d000b41107472210c0c220b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d28200d4101742205200420042005491b22054100480d2802400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d162003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41043a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d29200d4101742205200420042005491b22054100480d2902400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d182003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d29200c4101742204200d200d2004491b22044100480d2902400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d19200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000b200341086a2002200341d0006a10850420032d0008220a411a460d0420032f000920032d000b41107472210c0c210b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d27200d4101742205200420042005491b22054100480d2702400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d182003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41053a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d28200d4101742205200420042005491b22054100480d2802400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d1a2003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d28200c4101742204200d200d2004491b22044100480d2802400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d1b200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000b200341086a2002200341d0006a10850420032d0008220a411a460d0320032f000920032d000b41107472210c0c200b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d26200d4101742205200420042005491b22054100480d2602400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d1a2003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41063a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d27200d4101742205200420042005491b22054100480d2702400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d1c2003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d27200c4101742204200d200d2004491b22044100480d2702400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d1d200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000c020b0b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d25200d4101742205200420042005491b22054100480d2502400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d1c2003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41073a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d26200d4101742205200420042005491b22054100480d2602400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d1e2003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d26200c4101742204200d200d2004491b22044100480d2602400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d1f200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000b0b2003411a3a00080b200741706a2107200b210d200b2006470d000b2006210b0c1c0b20054101102c000b200b4101102c000b200b4101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20032903102114200328020c2104024003402007450d01200741706a2107200b280200210d200b41106a210b200d4108470d000b0b02402011450d002009102e0b20124521054101210d0c010b024003402006200b460d01200b280200210a200b41106a210b200a4108470d000b0b02402011450d002009102e0b20032802582109200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d08200a4101742206200d200d2006491b22064100480d0802400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d07200c410174220a200d200d200a491b220a4100480d0702400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402009450d002002102e0b41002110410121072008450d032012450d032013450d032008102e0c030b20064101102c000b200a4101102c000b02402003280258450d002003280254102e0b02402008452005720d002013450d002008102e0b0240200d201145720d002009102e0b200a411a470d1141002110410121070b4101210c4101210d4101210b4101210841012109410121044101210541012113410121064101210241012111410121120c350b200141146a280200210f200141106a28020021112001410c6a2802002113200141086a2802002110200141056a2d0000210d200141046a2d00002109024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0c200a410174220b200c200c200b491b220b4100480d0c02400240200a0d00200b1029210c0c010b2002280200200a200b102a210c0b200c450d012002200c360200200241046a200b360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41003a00000240410410292212450d00201241eec2b5ab06360000024020090e0400050403000b410121064100210a4100210c2011210d034002400240200a200c460d00200a21070c010b200a41016a220c200a490d0e200a410174220b200c200c200b491b22074100480d0e02400240200a0d002007102921060c010b2006200a2007102a21060b02402006450d00200a210c2007210a0c010b20074101102c000b2006200c6a200d41807f72200d41ff0071200d410776220b1b3a0000200c41016a210c200b210d200b0d000b0240024002402007200c6b20114f0d00200c20116a220a200c490d0f2007410174220d200a200a200d491b220a4100480d0f0240024020070d00200a102921060c010b20062007200a102a21060b2006450d01200a21070b2006200c6a2010201110f6041a200c20116a21084101210e20130d010c080b200a4101102c000b2010102e0c060b41044101102c000b200b4101102c000b410021154101210e20102106201321072011210841012116410121170c040b2003410036024820034201370340410121044100210d4100210a2010210c02400240024002400240024003400240200a200d470d00200d41016a220b200d490d10200d4101742205200b200b2005491b220b4100480d1002400240200d0d00200b102921040c010b2004200d200b102a21040b2004450d022003200b36024420032004360240200b210d0b2003200a41016a22053602482004200a6a200c41807f72200c41ff0071200c410776220b1b3a00002005210a200b210c200b0d000b2013200f4104746a21060240200f0d002013210b0c040b2013210b2010450d03200641706a21162010210e4100210a2013210803402008210b02400340200b41046a28020022070d01200a41016a210a2006200b41106a220b470d000c070b0b200b41106a2108200a41016a2115200e417f6a210e200b41086a2902002114200b28020021172003280244210d2003280248210c02400240034002400240200c200d460d00200328024021040c010b200d41016a2204200d490d13200d4101742205200420042005491b22054100480d1302400240200d0d002005102921040c010b2003280240200d2005102a21040b2004450d0220032005360244200320043602402005210d0b2003200c41016a22053602482004200c6a200a41807f72200a41ff0071200a41077622041b3a00002005210c2004210a20040d000b200320143703102003200736020c20032017360208200341d0006a200341086a200341c0006a108d0420032d00502204411a460d010c040b20054101102c000b2016200b460d032015210a200e0d000c030b0b200b4101102c000b20032d0053210e20032f0051211720032802542105200329035821140240200641706a200b460d00200b41106a210b0340200b220a41106a210b0240200a2802042207450d00200a28020821080240200a410c6a280200220a450d00200a410c6c210c2007210a03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b2008450d002007102e0b200b2006470d000b0b02402011450d002013102e0b2004411a460d03200e411074210a02402003280244450d002003280240102e0b2017200a72210a02400240200941024b0d000240024020090e03000109000b2013450d080c020b0240200f450d00200f410c6c210d2013210c03400240200c280200220b450d00200c41046a280200450d00200b102e0b200c410c6a210c200d41746a220d0d000b0b02402011450d002013102e0b2004411a470d074100210541012104410021080c0a0b2013450d060b2010102e0c050b200b41106a210b0b200b2006460d000340200b220a41106a210b0240200a2802042204450d00200a28020821050240200a410c6a280200220a450d00200a410c6c210c2004210a03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b2005450d002004102e0b200b2006470d000b0b2011450d002013102e0b2003280248210820032802442107200328024021064102210d410021164101210e41002117410021150c030b4100210e2003410036024820034201370340200341146a200f360200200341086a41086a20113602002003201336020c20032010360208200341d0006a200341086a200341c0006a108d04024020032d00502204411a460d0020032d0053411074210a20032f0051210c200341d0006a41086a29030021142003280254210502402003280244450d002003280240102e0b200c200a72210a0c010b2003280248210820032802442107200328024021064101211641002117410021154101210d0c020b200041086a2014370200200041046a20053602002000200a4108742004723602002012102e0c030b4100211741012116410121154100210d0b024002400240410110292204450d002004200d3a00004102210d4101210a410121052008210c03400240200a2005470d00200d200a41016a220b200b200d491b22054100480d092004200a2005102a2204450d030b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200d41026a210d200a41016a210a200b210c200b0d000b02402005200a6b20084f0d00200a20086a220c200a490d082005410174220d200c200c200d491b220c4100480d080240024020050d00200c102921040c010b20042005200c102a21040b2004450d03200c21050b2004200a6a2006200810f6041a02402007450d002006102e0b2008200a6a21080240200941024b0d00024002400240024020090e03000102000b2015201345720d072010102e0c070b200e450d060240200f450d00200f410c6c210c2013210a03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b20110d010c060b2016450d050240200f450d002013200f4104746a21072013210603402006220b41106a21060240200b280204220a450d000240200b410c6a280200220c450d00200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b200b41086a280200450d00200b280204102e0b20062007470d000b0b2011450d050b2013102e0c040b2017201345720d032010102e0c030b41014101102c000b20054101102c000b200c4101102c000b2003411c6a2008360200200341186a20053602002003200436021420034284808080c00037020c20032012360208200341d0006a200341086a2002109504200320032900513703402003200341d0006a41086a29000037004720032d0050220a411a460d012000200a3a000020002003290340370001200041086a20032900473700000b410021094101210d4101210c4101210b410121044101210541012106410121074101210241012108410121130c1a0b41002112410121074101210c4101210d4101210b41012108410121094101210441012105410121134101210641012102410121110c330b2001410c6a2802002105200141086a2802002113200141046a28020021090240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d15200a410174220d200c200c200d491b220d4100480d1502400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a410b3a0000200341dc006a4100360200200342013702542003200236025020092005411c6c6a21074100210a4100210c2005210d034002400240200a200c460d002003280254210a0c010b200a41016a220b200a490d16200a4101742204200b200b2004491b220b4100480d1602400240200a0d00200b1029210a0c010b2003280254200a200b102a210a0b200a450d032003200b3602582003200a3602540b2003200c41016a36025c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280258210a200328025c210c200d210d0c010b0b200921042005450d062009210a0340200a411c6a2104200a2802042202450d07200a41186a2802002105200a41146a2802002108200a41086a2902002114200a280200210c200a28021021060340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d17200a410174220b200d200d200b491b220b4100480d1702400240200a0d00200b1029210d0c010b2003280254200a200b102a210d0b200d450d052003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b2003201437024420032002360240200341086a200341c0006a200341d0006a108204024020032d0008220d411a470d002005210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d18200a410174220b200d200d200b491b220b4100480d1802400240200a0d00200b1029210d0c010b2003280254200a200b102a210d0b200d450d072003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b024002402003280258220c200328025c220a6b2005490d002003280254210c0c010b200a20056a220d200a490d0b200c410174220a200d200d200a491b220a4100480d0b02400240200c0d00200a1029210c0c010b2003280254200c200a102a210c0b200c450d072003200a3602582003200c360254200328025c210a0b2003200a20056a36025c200c200a6a2006200510f6041a02402008450d002006102e0b2004210a20042007470d010c090b0b20032d000b211220032f0009211020032903102114200328020c21112008450d052006102e0c050b200d4101102c000b200b4101102c000b200b4101102c000b200b4101102c000b200a4101102c000b024020042007460d0003402004280204220b450d01200441146a2802002105200441086a28020021062004280210210202402004410c6a280200220a450d00200a410474210c200b210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b02402006450d00200b102e0b2004411c6a210402402005450d002002102e0b20042007470d000b0b2012411074210a02402013450d002009102e0b2010200a72210a02402003280258450d002003280254102e0b2000200a3b00012000200d3a0000200041036a200a4110763a0000200041086a2014370000200041046a2011360000410021084101210d4101210c4101210b41012104410121054101210641012107410121020c190b20042007460d0003402004280204220d450d01200441146a280200210b200441086a28020021052004280210210602402004410c6a280200220a450d00200a410474210c200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b02402005450d00200d102e0b2004411c6a21040240200b450d002006102e0b20042007470d000b0b02402013450d002009102e0b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d04200a4101742206200d200d2006491b22064100480d0402400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d03200c410174220a200d200d200a491b220a4100480d0302400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b41002111410121074101210c4101210d4101210b41012108410121094101210441012105410121134101210641012102410121120c340b20064101102c000b200a4101102c000b102d000b2001410c6a2802002105200141086a2802002117200141046a280200210e024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0f200a410174220d200c200c200d491b220d4100480d0f02400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a410a3a00002003412c6a41003602002003420137022420032002360220200e200541186c6a210f4100210a4100210c2005210d0240034002400240200a200c460d002003280224210a0c010b200a41016a220b200a490d11200a4101742204200b200b2004491b220b4100480d1102400240200a0d00200b1029210a0c010b2003280224200a200b102a210a0b200a450d022003200b3602282003200a3602240b2003200c41016a36022c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280228210a200328022c210c200d210d0c010b0b200e21092005450d03200341086a4101722102200341086a41026a2107200e210a02400340200a41186a2109200a2802002208450d05200a41146a2802002111200a41106a2802002112200a28020c2113200a29020421144100210c2003410036024c2003420137024420082014422088a7220d4103746a21062003200341206a3602402014a721104100210a024002400240024002400240034002400240200c200a460d002003280244210c0c010b200c41016a220a200c490d19200c410174220b200a200a200b491b220a4100480d1902400240200c0d00200a1029210c0c010b2003280244200c200a102a210c0b200c450d022003200a3602482003200c360244200328024c210a0b2003200a41016a36024c200c200a6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280248210c200328024c210a200d210d0c010b0b0240024020062008470d00200821040c010b2008210a0340200a41086a2104200a2902002214422088a7220a41ff01714104460d01200a41187441187521052014a7210c0340024002402003280248200328024c220a460d002003280244210d0c010b200a41016a220d200a490d1b200a410174220b200d200d200b491b220b4100480d1b02400240200a0d00200b1029210d0c010b2003280244200a200b102a210d0b200d450d052003200b3602482003200d360244200328024c210a0b2003200a41016a36024c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b024002402003280248200328024c220a460d002003280244210c0c010b200a41016a220c200a490d1a200a410174220d200c200c200d491b220d4100480d1a02400240200a0d00200d1029210c0c010b2003280244200a200d102a210c0b200c450d052003200d3602482003200c360244200328024c210a0b2003200a41016a36024c200c200a6a2005417f73220a413f7141c00072200a2005417f4a1b3a00002004210a20042006470d000b200621040b0240034020062004460d0120042d0004210a200441086a2104200a4104470d000b0b02402010450d002008102e0b20132011410474220a6a210b024020110d002013210a0c050b201341186a210c200a41706a21042013210a0340200a2d0000210d2007200a41036a2d00003a00002003200a41016a2f00003b01080240200d41ac01470d00200a41106a210a0c060b200341306a41026a20072d000022053a0000200320032f010822063b0130200a41046a2902002114200a410c6a2802002108200220063b0000200241026a20053a00002003200d3a0008200320083602142003201437020c200341d0006a200341086a200341c0006a108c0420032d00502205411a46220d450d04200c41106a210c200441706a2104200a41106a220a200b470d000c060b0b200a4101102c000b200b4101102c000b200d4101102c000b20032d0053210820032f00512111200328025421062003290358211402402004450d00034002400240200c41786a220a2d000022044109460d00200441ac01470d010c030b200c28020041ffffffff0371450d00200a41046a280200102e0b200c41106a210c200a41106a200b470d000b0b02402012450d002013102e0b02402003280248450d002003280244102e0b200d450d062009210a2009200f470d020c080b200a200b460d00034002400240200a2d0000220c4109460d00200c41ac01470d010c030b200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a220a200b470d000b0b02402012450d002013102e0b20032802482111200328024421132003280240210d200328024c2208210c0240034002400240200d41086a2205280200200d410c6a2204280200220a460d00200d280204210b0c010b200a41016a220b200a490d14200a4101742206200b200b2006491b22064100480d1402400240200a0d0020061029210b0c010b200d280204200a2006102a210b0b200b450d02200d200b360204200520063602002004280200210a0b2004200a41016a360200200b200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b024002402005280200220c2004280200220a6b2008490d00200d280204210c0c010b200a20086a220b200a490d13200c410174220a200b200b200a491b220a4100480d1302400240200c0d00200a1029210c0c010b200d280204200c200a102a210c0b200c450d03200d200c3602042005200a3602002004280200210a0b2004200a20086a360200200c200a6a2013200810f6041a02402011450d002013102e0b2009210a2009200f470d010c070b0b20064101102c000b200a4101102c000b200b4101102c000b200d4101102c000b02402009200f460d0003402009280200220c450d01200941146a280200210a200941106a280200210b200928020c210d02402009280204450d00200c102e0b0240200a450d00200a410474210c200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200941186a21090240200b450d00200d102e0b2009200f470d000b0b2008411074210a02402017450d00200e102e0b2011200a72210a02402003280228450d002003280224102e0b2000200a3b0001200020053a0000200041036a200a4110763a0000200041086a2014370000200041046a2006360000410021024101210d4101210c4101210b410121044101210541012106410121070c160b2009200f460d0003402009280200220c450d01200941146a280200210a200941106a280200210b200928020c210d02402009280204450d00200c102e0b0240200a450d00200a410474210c200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200941186a21090240200b450d00200d102e0b2009200f470d000b0b02402017450d00200e102e0b20032802282108200328022421022003280220220441086a210b200441046a2105200328022c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d0e200a4101742206200d200d2006491b22064100480d0e02400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d0d200c410174220a200d200d200a491b220a4100480d0d02400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b41002102410121074101210c4101210d4101210b4101210841012109410121044101210541012113410121060c220b20064101102c000b200a4101102c000b2001410c6a2802002105200141086a2802002113200141046a28020021090240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d12200a410174220d200c200c200d491b220d4100480d1202400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41093a0000200341dc006a4100360200200342013702542003200236025020092005411c6c6a21024100210a4100210c2005210d034002400240200a200c460d002003280254210a0c010b200a41016a220b200a490d13200a4101742204200b200b2004491b220b4100480d1302400240200a0d00200b1029210a0c010b2003280254200a200b102a210a0b200a450d032003200b3602582003200a3602540b2003200c41016a36025c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280258210a200328025c210c200d210d0c010b0b200921062005450d062009210a0340200a411c6a2106200a2802042205450d07200a41186a2802002104200a41146a2802002108200a41086a2902002114200a2802102107200a280200210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d14200a410174220b200d200d200b491b220b4100480d1402400240200a0d00200b1029210d0c010b2003280254200a200b102a210d0b200d450d052003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b2003201437024420032005360240200341086a200341c0006a200341d0006a108204024020032d0008220d411a470d00200720044102746a21052004210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d15200a410174220b200d200d200b491b220b4100480d1502400240200a0d00200b1029210d0c010b2003280254200a200b102a210d0b200d450d072003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02402004450d002007210403402004280200210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d17200a410174220b200d200d200b491b220b4100480d1702400240200a0d00200b1029210d0c010b2003280254200a200b102a210d0b200d450d0a2003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b200441046a22042005470d000b0b02402008450d002007102e0b2006210a20062002470d010c090b0b20032d000b211220032f0009211020032903102114200328020c21112008450d052007102e0c050b200d4101102c000b200b4101102c000b200b4101102c000b200b4101102c000b200b4101102c000b024020062002460d0003402006280204220b450d01200641146a2802002104200641086a28020021052006280210210702402006410c6a280200220a450d00200a410474210c200b210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b02402005450d00200b102e0b2006411c6a210602402004450d002007102e0b20062002470d000b0b2012411074210a02402013450d002009102e0b2010200a72210a02402003280258450d002003280254102e0b2000200a3b00012000200d3a0000200041036a200a4110763a0000200041086a2014370000200041046a2011360000410021074101210d4101210c4101210b4101210441012105410121060c140b20062002460d0003402006280204220d450d01200641146a280200210b200641086a28020021042006280210210502402006410c6a280200220a450d00200a410474210c200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b02402004450d00200d102e0b2006411c6a21060240200b450d002005102e0b20062002470d000b0b02402013450d002009102e0b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d0d200a4101742206200d200d2006491b22064100480d0d02400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d0c200c410174220a200d200d200a491b220a4100480d0c02400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b41002106410121074101210c4101210d4101210b41012108410121094101210441012105410121130c200b20064101102c000b200a4101102c000b200141046a280200210a0240024002400240024002400240200241046a280200200241086a280200220c460d002002280200210d0c010b200c41016a220d200c490d0e200c410174220b200d200d200b491b220b4100480d0e02400240200c0d00200b1029210d0c010b2002280200200c200b102a210d0b200d450d012002200d360200200241046a200b360200200241086a280200210c0b200241086a200c41016a360200200d200c6a41083a0000410121064100210b4100210c03400240200c200b470d00200b410174220d200b41016a22042004200d491b220d4100480d0f02400240200b0d00200d102921060c010b2006200b200d102a21060b2006450d05200d210b0b2006200c6a200a41807f72200a41ff0071200a410776220d1b3a0000200c41016a210c200d210a200d0d000b200c417f6a2109200241086a2105200241046a2107200c210d03400240024020072802002005280200220a460d00200228020021040c010b200a41016a2204200a490d0f200a4101742208200420042008491b22084100480d0f02400240200a0d002008102921040c010b2002280200200a2008102a21040b2004450d0320022004360200200720083602002005280200210a0b2005200a41016a3602002004200a6a200d41807f72200d41ff0071200d410776220a1b3a0000200a210d200a0d000b02400240200241046a280200220d200241086a280200220a6b20094d0d002002280200210d0c010b200a200c6a2204200a490d0e200d410174220a20042004200a491b220a4100480d0e02400240200d0d00200a1029210d0c010b2002280200200d200a102a210d0b200d450d032002200d360200200241046a200a360200200241086a280200210a0b200241086a200a200c6a360200200d200a6a2006200c10f6041a41012107200b450d042006102e0c040b200b4101102c000b20084101102c000b200a4101102c000b200d4101102c000b4101210c4101210d0c160b2001410c6a2802002109200141086a2802002113200141046a280200210802400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0e200a410174220d200c200c200d491b220d4100480d0e02400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41073a0000200341dc006a410036020020034201370254200320023602502008200941146c6a2107410121044100210d4100210a2009210c03400240200a200d470d00200d41016a220b200d490d0f200d4101742205200b200b2005491b220b4100480d0f02400240200d0d00200b102921040c010b2004200d200b102a21040b2004450d032003200b36025820032004360254200b210d0b2003200a41016a220536025c2004200a6a200c41807f72200c41ff0071200c410776220b1b3a00002005210a200b210c200b0d000b200821062009450d042008210a0340200a41146a2106200a28020c22054104460d05200a41106a280200210c200a29020021142003200a28020836024820032014370340200341086a200341c0006a200341d0006a10900420032d0008220a411a470d04024002402003280258220d200328025c220b460d00200328025421040c010b200b41016a220a200b490d0f200b410174220d200a200a200d491b220d4100480d0f02400240200b0d00200d102921040c010b2003280254200b200d102a21040b2004450d042003200d360258200320043602540b2003200b41016a220a36025c2004200b6a20053a0000024003400240200a200d470d00200d41016a220b200d490d11200d4101742205200b200b2005491b220b4100480d1102400240200d0d00200b102921040c010b2004200d200b102a21040b2004450d02200b210d0b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200a41016a210a200b210c200b0d000b2003200d3602582003200a36025c200320043602542006210a20062007470d010c070b0b200b4101102c000b200d4101102c000b200b4101102c000b200d4101102c000b20032d000b210c20032f0009210d20032903102114200328020c210b024020062007460d0003402006410c6a2802004104460d010240200641046a280200450d002006280200102e0b200641146a22062007470d000b0b200c411074210c02402013450d002008102e0b200d200c72210c02402003280258450d002003280254102e0b2000200c3b00012000200a3a0000200041036a200c4110763a0000200041086a2014370000200041046a200b360000410021064101210d4101210c4101210b41012104410121050c110b20062007460d0003402006410c6a2802004104460d010240200641046a280200450d002006280200102e0b200641146a22062007470d000b0b02402013450d002008102e0b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d0b200a4101742206200d200d2006491b22064100480d0b02400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d0a200c410174220a200d200d200a491b220a4100480d0a02400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b41002113410121074101210c4101210d4101210b410121084101210941012104410121050c1d0b20064101102c000b200a4101102c000b2001410c6a2802002109200141086a2802002113200141046a2802002108024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0e200a410174220d200c200c200d491b220d4100480d0e02400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41063a0000200341dc006a41003602002003420137025420032002360250200820094104746a21054100210a4100210c2009210d034002400240200a200c460d002003280254210a0c010b200a41016a220b200a490d0f200a4101742204200b200b2004491b220b4100480d0f02400240200a0d00200b1029210a0c010b2003280254200a200b102a210a0b200a450d032003200b3602582003200a3602540b2003200c41016a36025c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280258210a200328025c210c200d210d0c010b0b2008210d2009450d054100210d0340200341086a41086a220a2008200d6a220c41086a2802003602002003200c2902003703080240200c410d6a2d000022044102470d00200c41106a210d0c070b200341306a41086a200a280200220a360200200320032903082214370330200c410c6a2d00002106200341206a41086a2207200a36020020032014370320024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d0f200a4101742202200b200b2002491b22024100480d0f02400240200a0d0020021029210b0c010b2003280254200a2002102a210b0b200b450d04200320023602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a41fdf9ff77200641037441187141107376413f7141c000723a0000024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d0f200a4101742206200b200b2006491b22064100480d0f02400240200a0d0020061029210b0c010b2003280254200a2006102a210b0b200b450d05200320063602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a20044100473a0000200341c0006a41086a200728020036020020032003290320370340200341086a200341c0006a200341d0006a10820420032d0008220b411a470d05200d41106a210d200c41106a2005470d000c070b0b200d4101102c000b200b4101102c000b20024101102c000b20064101102c000b20032d000b210720032f00092102200328020c2111200329031021140240200941047441706a200d460d00200c41106a210d0340200d410d6a2d00004102460d01200d2802042106200d28020021040240200d280208220a450d00200a410474210c2004210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200d41106a210d02402006450d002004102e0b200d2005470d000b0b2007411074210a02402013450d002008102e0b2002200a72210a02402003280258450d002003280254102e0b2000200a3b00012000200b3a0000200041036a200a4110763a0000200041086a2014370000200041046a2011360000410021054101210d4101210c4101210b410121040c0f0b200d2005460d000340200d410d6a2d00004102460d01200d2802042104200d280200210b0240200d280208220a450d00200a410474210c200b210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200d41106a210d02402004450d00200b102e0b200d2005470d000b0b02402013450d002008102e0b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d0a200a4101742206200d200d2006491b22064100480d0a02400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d09200c410174220a200d200d200a491b220a4100480d0902400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b41002105410121074101210c4101210d4101210b4101210841012109410121040c1b0b20064101102c000b200a4101102c000b2001410c6a2802002107200141086a2802002108200141046a280200210602400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d09200a410174220d200c200c200d491b220d4100480d0902400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41053a0000200341d0006a410c6a4100360200200342013702542003200236025020062007410c6c6a2102410121044100210d4100210a2007210c03400240200a200d470d00200d41016a220b200d490d0a200d4101742205200b200b2005491b220b4100480d0a02400240200d0d00200b102921040c010b2004200d200b102a21040b2004450d032003200b36025820032004360254200b210d0b2003200a41016a220536025c2004200a6a200c41807f72200c41ff0071200c410776220b1b3a00002005210a200b210c200b0d000b2006210a2007450d022007410c6c210b4100210c034002402006200c6a220a41046a280200220d4102470d00200a410c6a210a0c040b200341086a200a280200200d200a41086a280200200341d0006a108e04024020032d00082204411a460d0020032f000920032d000b41107472210520032903102114200328020c2107200a410c6a210d200b200c6b41746a210a02400340200a450d01200a41746a210a200d280204210c200d410c6a210d200c4102470d000b0b02402008450d002006102e0b02402003280258450d002003280254102e0b200020053b0001200020043a0000200041036a20054110763a0000200041086a2014370000200041046a2007360000410021044101210d4101210c4101210b0c100b200b200c410c6a220c470d000b2002210a0c020b200d4101102c000b200b4101102c000b200a410020076b410c6c6a210c024003402006200c460d01200c410c6a210c200a280204210d200a410c6a210a200d4102470d000b0b02402008450d002006102e0b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d09200a4101742206200d200d2006491b22064100480d0902400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d08200c410174220a200d200d200a491b220a4100480d0802400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b41002104410121074101210c4101210d4101210b41012108410121090c190b20064101102c000b200a4101102c000b2001410c6a2802002109200141086a2802002113200141046a2802002106024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d09200a410174220d200c200c200d491b220d4100480d0902400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41043a0000200341d0006a410c6a4100360200200342013702542003200236025020062009410c6c6a2111410121044100210d4100210a2009210c03400240200a200d470d00200d41016a220b200d490d0a200d4101742205200b200b2005491b220b4100480d0a02400240200d0d00200b102921040c010b2004200d200b102a21040b2004450d032003200b36025820032004360254200b210d0b2003200a41016a220536025c2004200a6a200c41807f72200c41ff0071200c410776220b1b3a00002005210a200b210c200b0d000b2006210a2009450d032009410c6c21084100210d034002402006200d6a220c41046a28020022044102470d00200c410c6a210a0c050b200c2802002105200c41086a2802002107024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d0a200a4101742202200b200b2002491b22024100480d0a02400240200a0d0020021029210b0c010b2003280254200a2002102a210b0b200b450d04200320023602582003200b3602540b2003200a41016a36025c200b200a6a41f0003a0000200341086a200520042007200341d0006a108e04024020032d0008220b411a460d0020032f000920032d000b41107472210420032903102114200328020c2105200c410c6a210c2008200d6b41746a210a02400340200a450d01200a41746a210a200c280204210d200c410c6a210c200d4102470d000b0b02402013450d002006102e0b02402003280258450d002003280254102e0b200020043b00012000200b3a0000200041036a20044110763a0000200041086a2014370000200041046a20053600004100210b4101210d4101210c0c0f0b2008200d410c6a220d470d000b2011210a0c030b200d4101102c000b200b4101102c000b20024101102c000b200a410020096b410c6c6a210c024003402006200c460d01200c410c6a210c200a280204210d200a410c6a210a200d4102470d000b0b02402013450d002006102e0b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d08200a4101742206200d200d2006491b22064100480d0802400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d07200c410174220a200d200d200a491b220a4100480d0702400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b41002109410121074101210c4101210d4101210b410121080c170b20064101102c000b200a4101102c000b2001410c6a2802002106200141086a2802002109200141046a280200210802400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0a200a410174220d200c200c200d491b220d4100480d0a02400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41033a0000200820064102746a21074100210d4100210a41002105410121042006210c03400240200a2005470d00200d200a41016a220b200b200d491b22054100480d0b02400240200d0d002005102921040c010b2004200a2005102a21040b2004450d050b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200d41026a210d200a41016a210a200b210c200b0d000b02402006450d00200821060340200a410174210d2006280200210c03400240200a2005470d00200a41016a220b200a490d0d200d200b200b200d491b22054100480d0d02400240200a0d002005102921040c010b2004200a2005102a21040b2004450d080b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200d41026a210d200a41016a210a200b210c200b0d000b200641046a22062007470d000b0b02402009450d002008102e0b200241086a2106200241046a2107200a210d03400240024020072802002006280200220c460d002002280200210b0c010b200c41016a220b200c490d0b200c4101742208200b200b2008491b22084100480d0b02400240200c0d0020081029210b0c010b2002280200200c2008102a210b0b200b450d032002200b360200200720083602002006280200210c0b2006200c41016a360200200b200c6a200d41807f72200d41ff0071200d410776220c1b3a0000200c210d200c0d000b02400240200241046a280200220d200241086a280200220c6b200a490d002002280200210d0c010b200c200a6a220b200c490d0a200d410174220c200b200b200c491b220c4100480d0a02400240200d0d00200c1029210d0c010b2002280200200d200c102a210d0b200d450d032002200d360200200241046a200c360200200241086a280200210c0b200241086a200c200a6a360200200d200c6a2004200a10f6041a41002108410121072005450d052004102e0c050b200d4101102c000b20084101102c000b200c4101102c000b20054101102c000b20054101102c000b4101210c4101210d4101210b0c130b2001410c6a2802002106200141086a2802002111200141046a28020021130240024002400240024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d11200a410174220d200c200c200d491b220d4100480d1102400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41023a0000200341dc006a410036020020034201370254200320023602502013200641286c6a21054100210a4100210c2006210d034002400240200a200c460d002003280254210a0c010b200a41016a220b200a490d12200a4101742204200b200b2004491b220b4100480d1202400240200a0d00200b1029210a0c010b2003280254200a200b102a210a0b200a450d032003200b3602582003200a3602540b2003200c41016a36025c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280258210a200328025c210c200d210d0c010b0b2013210b2006450d0c2013210b0340200341086a41086a220d200b220a41086a2802003602002003200a290200370308200a41286a210b200a2d001822074104460d0d200a411b6a2d00002108200a41196a2f00002109200a41206a2900002114200a411c6a280000210c200a41146a2802002102200a41106a2802002104200a28020c2106200341206a41086a200d280200220a360200200320032903082218370320200341c0006a41086a200a36020020032018370340200341086a200341c0006a200341d0006a109004024020032d0008220a411a460d0020032f000920032d000b41107472210720032903102114200328020c21022004450d0d2006102e0c0d0b200320023602482003200436024420032006360240200341086a200341c0006a200341d0006a109004024020032d0008220a411a460d0020032f000920032d000b411074722107200328020c2102200329031021140c0d0b2014422088a7210a2014a7210d0240024002400240024020070e0400010203000b024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d16200a4101742204200d200d2004491b22044100480d1602400240200a0d0020041029210d0c010b2003280254200a2004102a210d0b200d450d08200320043602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a41003a00000340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d17200a4101742204200d200d2004491b22044100480d1702400240200a0d0020041029210d0c010b2003280254200a2004102a210d0b200d450d0a200320043602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000c040b0b024002402003280258200328025c2204460d00200328025421060c010b200441016a22062004490d1520044101742207200620062007491b22074100480d150240024020040d002007102921060c010b200328025420042007102a21060b2006450d092003200736025820032006360254200328025c21040b2003200441016a36025c200620046a41013a0000024002402003280258200328025c2204460d00200328025421060c010b200441016a22062004490d1520044101742207200620062007491b22074100480d150240024020040d002007102921060c010b200328025420042007102a21060b2006450d0a2003200736025820032006360254200328025c21040b2003200441016a36025c200620046a41f0003a0000200341086a200c200d200a200341d0006a108e0420032d0008220a411a460d0220032f000920032d000b4110747221070c0e0b024002402003280258200328025c2204460d00200328025421060c010b200441016a22062004490d1420044101742207200620062007491b22074100480d140240024020040d002007102921060c010b200328025420042007102a21060b2006450d0a2003200736025820032006360254200328025c21040b2003200441016a36025c200620046a41023a0000200341086a200c200d200a200341d0006a108e0420032d0008220a411a460d0120032f000920032d000b4110747221070c0d0b024002402003280258200328025c220a460d002003280254210c0c010b200a41016a220c200a490d13200a410174220d200c200c200d491b220d4100480d1302400240200a0d00200d1029210c0c010b2003280254200a200d102a210c0b200c450d0a2003200d3602582003200c360254200328025c210a0b2003200a41016a36025c200c200a6a41033a0000024002402003280258200328025c220a460d002003280254210c0c010b200a41016a220c200a490d13200a410174220d200c200c200d491b220d4100480d1302400240200a0d00200d1029210c0c010b2003280254200a200d102a210c0b200c450d0b2003200d3602582003200c360254200328025c210a0b2003200a41016a36025c200c200a6a2009200841107472220c417f73220a413f7141c00072200a200c411874411875417f4a1b3a0000024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d13200a4101742204200d200d2004491b22044100480d1302400240200a0d0020041029210d0c010b2003280254200a2004102a210d0b200d450d0c200320043602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c4180fe03714100473a00000b200b2005470d000c0e0b0b200d4101102c000b200b4101102c000b20044101102c000b20044101102c000b20074101102c000b20074101102c000b20074101102c000b200d4101102c000b200d4101102c000b20044101102c000b20032903102114200328020c21020b0240200b2005460d000340200b41186a2d00004104460d01200b41106a280200210c200b410c6a280200210d0240200b41046a280200450d00200b280200102e0b0240200c450d00200d102e0b200b41286a220b2005470d000b0b02402011450d002013102e0b02402003280258450d002003280254102e0b200020073b00012000200a3a0000200041036a20074110763a0000200041086a2014370000200041046a20023600004100210c4101210d0c080b200b2005460d000340200b41186a2d00004104460d01200b41106a280200210a200b410c6a280200210c0240200b41046a280200450d00200b280200102e0b0240200a450d00200c102e0b200b41286a220b2005470d000b0b02402011450d002013102e0b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d06200a4101742206200d200d2006491b22064100480d0602400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d05200c410174220a200d200d200a491b220a4100480d0502400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b4100210b410121074101210c4101210d0c130b20064101102c000b200a4101102c000b20082010460d0003402008410d6a2d00004105460d010240200841046a280200450d002008280200102e0b200841106a22082010470d000b0b0240200e450d00200f102e0b200241086a2106200241046a2107200c210d0240024003400240024020072802002006280200220a460d002002280200210b0c010b200a41016a220b200a490d04200a4101742208200b200b2008491b22084100480d0402400240200a0d0020081029210b0c010b2002280200200a2008102a210b0b200b450d022002200b360200200720083602002006280200210a0b2006200a41016a360200200b200a6a200d41807f72200d41ff0071200d410776220a1b3a0000200a210d200a0d000b02400240200241046a280200220d200241086a280200220a6b200c490d002002280200210d0c010b200a200c6a220b200a490d03200d410174220a200b200b200a491b220a4100480d0302400240200d0d00200a1029210d0c010b2002280200200d200a102a210d0b200d450d022002200d360200200241046a200a360200200241086a280200210a0b200241086a200a200c6a360200200d200a6a2004200c10f6041a4100210d410121072005450d032004102e0c030b20084101102c000b200a4101102c000b102d000b4101210c0c0c0b2000200c3b00012000200a3a0000200041036a200c4110763a0000200041086a2014370000200041046a2004360000410021134101210d4101210c4101210b410121044101210541012106410121074101210241012108410121090c090b4101210c200241086a200a41016a3602004100210d200b200a6a41003a00002003411c6a2004360200200341186a200536020020032006360214200320073602102003200836020c20032009360208200341d0006a200341086a2002109504200320032900513703402003200341d0006a41086a29000037004720032d0050220a411a460d092000200a3a000020002003290340370001200041086a20032900473700000b4101210b0b410121040b410121050b410121060b410121070b410121020b410121080b41012109410121130b20012d0000220a410e4b0d18200a0e0f0a0b0c0d0e0f1011121813141516170a0b4101210c410021074101210d0b4101210b0b410121080b410121090b410121040b410121050b410121130b410121060b410121020b41012111410121120c0f0b200141086a280200450d10200141046a280200102e0c100b200d450d0f0240200141086a280200450d00200141046a280200102e0b200141146a280200450d0f200141106a280200102e0c0f0b02402001410c6a280200220c450d00200141046a280200210a200c410474210c03400240200a41046a280200450d00200a280200102e0b200a41106a210a200c41706a220c0d000b0b200141086a280200450d0e2001280204102e0c0e0b200c450d0d02402001410c6a280200220c450d00200141046a280200210a200c41286c210c03400240200a41046a280200450d00200a280200102e0b0240200a41106a280200450d00200a410c6a280200102e0b200a41286a210a200c41586a220c0d000b0b200141086a280200450d0d2001280204102e0c0d0b200141086a280200450d0c200141046a280200102e0c0c0b200b450d0b200141086a280200450d0b200141046a280200102e0c0b0b2004450d0a200141086a280200450d0a200141046a280200102e0c0a0b2005450d0902402001410c6a280200220a450d00200141046a280200220d200a4104746a210b03400240200d280208220c450d00200d280200210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200d41106a210a0240200d41046a280200450d00200d280200102e0b200a210d200a200b470d000b0b200141086a280200450d092001280204102e0c090b2006450d0802402001410c6a280200220c450d00200141046a280200210a200c41146c210c03400240200a41046a280200450d00200a280200102e0b200a41146a210a200c416c6a220c0d000b0b200141086a280200450d082001280204102e0c080b2007450d0702402001410c6a280200220a450d00200141046a280200220d200a411c6c6a210b03400240200d410c6a280200220c450d00200d280204210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b0240200d41086a280200450d00200d280204102e0b200d411c6a210a0240200d41146a280200450d00200d280210102e0b200a210d200a200b470d000b0b200141086a280200450d072001280204102e0c070b2002450d0602402001410c6a280200220a450d00200141046a280200220d200a41186c6a210b03400240200d41046a280200450d00200d280200102e0b0240200d41146a280200220c450d00200d28020c210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200d41186a210a0240200d41106a280200450d00200d28020c102e0b200a210d200a200b470d000b0b200141086a280200450d062001280204102e0c060b2008450d0502402001410c6a280200220a450d00200141046a280200220d200a411c6c6a210b03400240200d410c6a280200220c450d00200d280204210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b0240200d41086a280200450d00200d280204102e0b200d411c6a210a0240200d41146a280200450d00200d280210102e0b200a210d200a200b470d000b0b200141086a280200450d052001280204102e0c050b2009450d040240200141046a2d0000220a41024b0d00024002400240200a0e03000102000b2001410c6a280200450d07200141086a280200102e0c070b0240200141146a280200220c450d002001410c6a280200210a200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b200141106a280200450d06200128020c102e0c060b0240200141146a280200220a450d002001410c6a2802002204200a4104746a210503402004220b41106a21040240200b280204220a450d000240200b410c6a280200220c450d00200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b200b41086a280200450d00200b280204102e0b20042005470d000b0b200141106a280200450d05200128020c102e0c050b2001410c6a280200450d04200141086a280200102e0c040b2013450d030240200141086a280200450d00200141046a280200102e0b0240200141146a280200220a450d00200141186a280200450d00200a102e0b200141246a280200450d03200141206a280200102e0c030b200110bf030c020b410121100b2000411a3a0000024020012d0000220a410e4b0d0002400240024002400240024002400240024002400240024002400240200a0e0f0001020304050607080e090a0b0c0d000b200c450d0e200141086a280200450d0e200141046a280200102e0c0e0b2007450d0d0240200141086a280200450d00200141046a280200102e0b200141146a280200450d0d200141106a280200102e0c0d0b200d450d0c02402001410c6a280200220c450d00200141046a280200210a200c410474210c03400240200a41046a280200450d00200a280200102e0b200a41106a210a200c41706a220c0d000b0b200141086a280200450d0c2001280204102e0c0c0b200b450d0b02402001410c6a280200220c450d00200141046a280200210a200c41286c210c03400240200a41046a280200450d00200a280200102e0b0240200a41106a280200450d00200a410c6a280200102e0b200a41286a210a200c41586a220c0d000b0b200141086a280200450d0b2001280204102e0c0b0b2008450d0a200141086a280200450d0a200141046a280200102e0c0a0b2009450d09200141086a280200450d09200141046a280200102e0c090b2004450d08200141086a280200450d08200141046a280200102e0c080b2005450d0702402001410c6a280200220a450d00200141046a280200220d200a4104746a210b03400240200d280208220c450d00200d280200210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200d41106a210a0240200d41046a280200450d00200d280200102e0b200a210d200a200b470d000b0b200141086a280200450d072001280204102e0c070b2013450d0602402001410c6a280200220c450d00200141046a280200210a200c41146c210c03400240200a41046a280200450d00200a280200102e0b200a41146a210a200c416c6a220c0d000b0b200141086a280200450d062001280204102e0c060b2006450d0502402001410c6a280200220a450d00200141046a280200220d200a411c6c6a210b03400240200d410c6a280200220c450d00200d280204210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b0240200d41086a280200450d00200d280204102e0b200d411c6a210a0240200d41146a280200450d00200d280210102e0b200a210d200a200b470d000b0b200141086a280200450d052001280204102e0c050b2002450d0402402001410c6a280200220a450d00200141046a280200220d200a41186c6a210b03400240200d41046a280200450d00200d280200102e0b0240200d41146a280200220c450d00200d28020c210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200d41186a210a0240200d41106a280200450d00200d28020c102e0b200a210d200a200b470d000b0b200141086a280200450d042001280204102e0c040b2011450d0302402001410c6a280200220a450d00200141046a280200220d200a411c6c6a210b03400240200d410c6a280200220c450d00200d280204210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b0240200d41086a280200450d00200d280204102e0b200d411c6a210a0240200d41146a280200450d00200d280210102e0b200a210d200a200b470d000b0b200141086a280200450d032001280204102e0c030b2012450d020240200141046a2d0000220a41024b0d00024002400240200a0e03000102000b2001410c6a280200450d05200141086a280200102e0c050b0240200141146a280200220c450d002001410c6a280200210a200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b200141106a280200450d04200128020c102e0c040b0240200141146a280200220a450d002001410c6a2802002204200a4104746a210503402004220b41106a21040240200b280204220a450d000240200b410c6a280200220c450d00200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b200b41086a280200450d00200b280204102e0b20042005470d000b0b200141106a280200450d03200128020c102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2010450d010240200141086a280200450d00200141046a280200102e0b0240200141146a280200220a450d00200141186a280200450d00200a102e0b200141246a280200450d01200141206a280200102e0c010b200110bf030b200341e0006a24000ba62207017f027e077f017e017f017e107f230041d0066b22032400200241d8006a2903002104200241d0006a290300210520022802002106200341c4006a200241046a41cc0010f6041a20034190016a200341c4006a41046a41c80010f6041a2001280200210720034190036a41186a2208200341c8016a29030037030020034190036a41106a2209200341c0016a29030037030020034190036a41086a220a200341b8016a290300370300200320032903b00137039003024002400240024041c80010292202450d002002420037030020022006360220200241186a4200370300200241106a4200370300200241086a42003703002002200341b0016a220b2902003702242002412c6a200b41086a290200370200200241346a200b41106a2902003702002002413c6a200b41186a290200370200200341286a41c28cc00041161070200341186a2003290330200341286a41106a290300427f420010fc04200341086a20052004200329031842002003280228220c1b220d4201200d420156200341186a41086a2903004200200c1b220d420052200d501b220c1b200d4200200c1b10fc04200341e0026a41086a200a290300370300200341e0026a41106a2009290300370300200341e0026a41186a200829030037030020032003290390033703e0022003290308210d0240024002400240200741046a28020020072802082208460d00200728020021090c010b200841016a22092008490d012008410174220a20092009200a491b220aad42d0007e2204422088a70d012004a7220c4100480d010240024020080d00200c102921090c010b2007280200200841d0006c200c102a21090b2009450d0220072009360200200741046a200a360200200728020821080b2009200841d0006c6a22084200370310200842003703082008200d37030020082002360220200820032903e00237022c200841186a4200370300200841246a428180808010370200200841346a200341e0026a41086a22022903003702002008413c6a200341e0026a41106a220a290300370200200841c4006a200341e0026a41186a22082903003702002007200728020841016a3602082001280208210c200341a0026a41186a200b41186a290000370300200341a0026a41106a200b41106a290000370300200341a0026a41086a200b41086a2900003703002003200b2900003703a002024002400240200c280200220141e08dc000460d00200c28020421090c010b4100210920034190036a410041e00210f5041a20034188036a220b410036020020034180036a2207420037030020084200370300200a420037030020024200370300200342003703e00241940310292201450d01200141003b010620014100360200200141086a20034190036a41e00210f6041a20014190036a200b28020036020020014188036a200729030037020020014180036a200341f8026a290300370200200141f8026a200341f0026a290300370200200141f0026a200341e0026a41086a290300370200200120032903e0023702e802200c4100360204200c20013602000b02400340200141086a2108200141066a210e20012f0106220a41057421024100210b0240024003402002450d01200341a0026a2008412010f8042207450d02200241606a2102200b41016a210b200841206a21082007417f4a0d000b200b417f6a210a0b2009450d022009417f6a21092001200a4102746a4194036a28020021010c010b0b2001200b4102746a41e8026a20063602000c060b200341d8016a41186a200341a0026a41186a2202290300220d370300200341d8016a41106a200341a0026a41106a22082903002204370300200341d8016a41086a200341a0026a41086a220b2903002205370300200320032903a002220f3703d801200c200c28020841016a3602082002200d37030020082004370300200b20053703002003200f3703a0020240024002400240200e2f01002209410b490d0020034190036a410041e00210f5041a20034188036a2202410036020020034180036a22084200370300200341e0026a41186a4200370300200341e0026a41106a4200370300200341e0026a41086a4200370300200342003703e00241940310292210450d03201041003b010620104100360200201041086a20034190036a41e00210f604210b20104190036a200228020036020020104188036a200829030037020020104180036a200341e0026a41186a290300370200201041f8026a200341e0026a41106a290300370200201041f0026a200341e0026a41086a290300370200201020032903e0023702e802200320012f00c8013b01dc022003200141ca016a2d00003a00de02200141cb016a2800002111200141cf016a2800002112200141d3016a2800002113200141d7016a28000021142003200141e0016a2900003700cd02200320012900db013703c8022001280280032115200b200141e8016a20012f010641796a220241057410f604210b201041e8026a20014184036a200241027410f6042107200141063b0106201020023b0106200320032f01dc023b01c402200320032d00de023a00c602200320032903c8023703e002200320032900cd023700e502200a4107490d01201041066a210e200b200a417a6a22094105746a200b200a41796a22084105746a220b200241ffff037120086b41057410f7041a200b41186a200341a0026a41186a290300370000200b41106a200341a0026a41106a290300370000200b41086a200341a0026a41086a290300370000200b20032903a002370000200720094102746a210b200720084102746a21020c020b200141086a2207200a41016a220c4105746a2007200a4105746a22072009200a6b41057410f7041a200741186a2002290300370000200741106a2008290300370000200741086a200b290300370000200720032903a002370000200141e8026a2202200c4102746a2002200a4102746a220220012f0106200a6b41027410f7041a20022006360200200120012f010641016a3b01060c080b200141086a2202200a41016a22084105746a2002200a4105746a2202200e2f0100200a6b41057410f7041a200241186a200341a0026a41186a290300370000200241106a200341a0026a41106a290300370000200241086a200341a0026a41086a290300370000200220032903a002370000200141e8026a220b200a4102746a2102200b20084102746a210b200a21080b200b2002200e2f010020086b41027410f7041a20022006360200200e200e2f010041016a3b0100200341c0026a41026a221620032d00c60222023a00002003418c026a41026a221720023a0000200320032900e50237009502200320032903e00237039002200320032f01c40222023b01c00220032003290095023700fd0120032003290390023703f801200320023b018c0220012802002209450d0520012f0104210e20034190036a41027221180340201620172d00003a0000200320032f018c023b01c002200320032903f8013703a002200320032900fd013700a502200e41ffff037121010240024002400240024020092f01062202410b490d002018410041be0310f5041a41c40310292207450d0320074100360200200741046a20034190036a41c00310f6041a200320092f00c8013b01dc022003200941ca016a2d00003a00de022003200941db016a2900003703c8022003200941e0016a2900003700cd02200941cb016a2800002119200941cf016a280000211a200941d3016a280000211b200941d7016a280000211c20094180036a280200211d200741086a200941e8016a20092f0106220841796a220241057410f604211e200741e8026a20094184036a200241027410f604211f20074194036a200941b0036a2008417a6a220a41027410f6042106200941063b0106200720023b01060240200a450d00410021022006210803402008280200220b20023b0104200b2007360200200841046a2108200a200241016a2202470d000b0b200320032d00de0222023a00c602200320032f01dc0222083b01c402200320032903c8023703e002200320032900cd023700e50220034190026a41026a220a20023a0000200320083b019002200320032903e00237039003200320032900e50237009503200e41ffff037122084107490d01201e2001417a6a220b4105746a201e200141796a22024105746a220820072f010620026b41057410f7041a200841186a20032900a5023700002008201436000f2008201336000b2008201236000720082011360003200841026a20162d00003a0000200820032f01c0023b0000200820032903a002370013201f200b41027422086a201f20024102746a220e20072f0106221120026b41027410f7041a200e20153602002007201141016a220e3b01062001410274221120066a416c6a200620086a2208200e41ffff03712201200b6b41027410f7041a200820103602002001200b490d02200720116a41fc026a210803402008280200220b200241016a22023b0104200b2007360200200841046a210820022001490d000c030b0b200941086a2208200141016a220b4105746a200820014105746a2208200220016b41057410f7041a200841186a20032900a5023700002008201436000f2008201336000b2008201236000720082011360003200841026a200341c0026a41026a2d00003a0000200820032f01c0023b0000200820032903a002370013200941e8026a2202200b41027422086a2002200141027422076a220220092f0106220a20016b41027410f7041a200220153602002009200a41016a22023b0106200720094194036a22016a41086a200120086a2208200241ffff03712207200b6b41027410f7041a20082010360200200e41ffff037120074f0d0b2009200b417f6a22024102746a4198036a210803402008280200220b200241016a22023b0104200b2009360200200841046a210820022007490d000c0c0b0b200941086a2202200141016a220e4105746a200220014105746a220220092f010620016b41057410f7041a200241186a20032900a5023700002002201436000f2002201336000b2002201236000720022011360003200241026a20162d00003a0000200220032f01c0023b0000200220032903a002370013200941e8026a220b200e41027422066a200b200141027422026a220b20092f0106221120016b41027410f7041a200b20153602002009201141016a220b3b0106200220094194036a22116a41086a201120066a2206200b41ffff0371220b200e6b41027410f7041a200620103602002008200b4f0d00200920026a4198036a2102034020022802002208200141016a22013b010420082009360200200241046a2102200b2001470d000b0b2017200a2d00003a0000200320032f0190023b018c0220032003290390033703f80120032003290095033700fd01200928020022020d0120192111201c2114201b2113201a211220072110201d21150c080b41c4034104102c000b20092f0104210e20192111201c2114201b2113201a211220022109201d2115200721100c000b0b4194034104102c000b4194034104102c000b102d000b200c4108102c000b41c8004108102c000b20034190036a410272410041be0310f5041a41c40310292202450d0120024100360200200241046a20034190036a41c00310f6041a2002200c280200220836029403200c2002360200200c200c28020441016a360204200841003b010420082002360200200220022f0106220b4105746a220841086a20032f018c023b00002008410a6a2003418c026a41026a2d00003a0000200841176a2014360000200841136a20133600002008410f6a20123600002008410b6a20113600002008411b6a20032903f801370000200841206a20032900fd0137000020024194036a200b41016a22084102746a20103602002002200b4102746a41e8026a2015360200200220083b0106201020083b0104201020023602000b200020034190016a41c80010f6041a200341d0066a24000f0b41c4034104102c000b130020004105360204200041bcaac3003602000b3400200041e0a1c30036020420004100360200200041146a4107360200200041106a4188bdc300360200200041086a42083702000b3701017f02404110102922020d0041104101102c000b2002420037000820024201370000200042908080808002370204200020023602000bc70101017f23004190016b22022400200241003a00782002428080848080023703682002420137035820024201370350200242af0137034820024287013703402002420137033820024201370330200242013703282002420137032020024201370318200242013703102002420137030820024280808080c00037036020024280808180800437037020024100360288012002420137038001200241086a20024180016a10fe01200041086a200228028801360200200020022903800137020020024190016a24000b130020004110360204200041e4c6c3003602000b3301017f02404108102922020d0041084101102c000b2000428880808080013702042000200236020020024280ade2043700000b3201017f02404104102922020d0041044101102c000b20004284808080c000370204200020023602002002418080013600000b3101017f02404104102922020d0041044101102c000b20004284808080c0003702042000200236020020024180083600000b3101017f02404108102922020d0041084101102c000b20004288808080800137020420002002360200200242e8073700000b3c01017f02404110102922020d0041104101102c000b2002420037000820024280a094a58d1d370000200042908080808002370204200020023602000b3b01017f02404110102922020d0041104101102c000b2002420037000820024280c8afa025370000200042908080808002370204200020023602000b3801017f02404110102922020d0041104101102c000b200242003700082002429601370000200042908080808002370204200020023602000b3801017f02404110102922020d0041104101102c000b20024200370008200242e807370000200042908080808002370204200020023602000b3701017f02404110102922020d0041104101102c000b2002420037000820024204370000200042908080808002370204200020023602000b3001017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241083600000b3701017f02404110102922020d0041104101102c000b2002420037000820024210370000200042908080808002370204200020023602000b3001017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241023600000b860a02057f027e20002802102102200041186a2802002203200110470240024002400240024002400240024002400240200141046a2802002204200141086a28020022056b2003490d00200128020021040c010b200520036a22062005490d0820044101742205200620062005491b22054100480d080240024020040d002005102921040c010b200128020020042005102a21040b2004450d0120012004360200200141046a2005360200200141086a28020021050b200141086a2206200520036a360200200420056a2002200310f6041a200028021c210402400240200141046a2802002205200628020022036b4104490d00200128020021050c010b200341046a22022003490d0820054101742203200220022003491b22034100480d080240024020050d002003102921050c010b200128020020052003102a21050b2005450d0220012005360200200141046a2003360200200141086a28020021030b200141086a2202200341046a360200200520036a20043600002000412c6a20011046200041086a29030021072000290300210802400240200141046a2802002205200228020022036b4110490d00200128020021050c010b200341106a22042003490d0820054101742203200420042003491b22034100480d080240024020050d002003102921050c010b200128020020052003102a21050b2005450d0320012005360200200141046a2003360200200141086a28020021030b200141086a2204200341106a360200200520036a22032007370008200320083700002000280220210202400240200141046a2802002205200428020022036b4104490d00200128020021050c010b200341046a22042003490d0820054101742203200420042003491b22034100480d080240024020050d002003102921050c010b200128020020052003102a21050b2005450d0420012005360200200141046a2003360200200141086a28020021030b200141086a2204200341046a360200200520036a2002360000024020002802244101460d0002400240200141046a28020020042802002200460d00200128020021030c010b200041016a22032000490d0920004101742205200320032005491b22054100480d090240024020000d002005102921030c010b200128020020002005102a21030b2003450d0620012003360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200320006a41003a00000f0b02400240200141046a28020020042802002203460d00200128020021050c010b200341016a22052003490d0820034101742204200520052004491b22044100480d080240024020030d002004102921050c010b200128020020032004102a21050b2005450d0620012005360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200520036a41013a00002000280228210502400240200141046a2802002203200428020022006b4104490d00200128020021030c010b200041046a22042000490d0820034101742200200420042000491b22004100480d080240024020030d002000102921030c010b200128020020032000102a21030b2003450d0720012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20053600000f0b20054101102c000b20034101102c000b20034101102c000b20034101102c000b20054101102c000b20044101102c000b20004101102c000b102d000bcd0101037f230041106b22022400200241003602082002420137030020002d00002103410110292104024002400240024020034101460d002004450d02200441003a0000200242818080801037020420022004360200200041086a200210d4030c010b2004450d02200441013a0000200242818080801037020420022004360200200041016a200210460b2002280204210420012802002001280204200228020022012002280208100402402004450d002001102e0b200241106a24000f0b41014101102c000b41014101102c000b8f0703037f047e067f23002202210320024180026b416071220224002001411c6a22042902002105200420022903b801370200200141146a22042902002106200420022903b0013702002001410c6a22042902002107200420022903a801370200200241003a00a00120012902042108200120022903a00137020420022005370358200220063703502002200737034820022008370340200141246a2d00002104200241a0016a41176a22092005370000200241a0016a41106a220a2002290051370300200241a0016a41086a220b2002290049370300200220022900413703a001024002402008a741ff01714101460d00200041003602200c010b200241106a41176a2009290000370000200241106a41106a200a290300370300200241106a41086a200b290300370300200220022903a001370310200220043a002f02400240411210292204450d00200441002900fee743370000200441106a41002f008ee8433b0000200441086a4100290086e84337000020024292808080a0023702a401200220043602a001200241106a200241a0016a104a20022802a401210a20022802a801210420022802a0012109200241a0016a41186a220b4200370300200241a0016a41106a220c4200370300200241a0016a41086a220d4200370300200242003703a00120092004200241a0016a1000200241c0006a41186a220e200b290300370300200241c0006a41106a220b200c290300370300200241c0006a41086a2204200d290300370300200220022903a001370340200241a0016a200241c0006a10ab0320022d00ac014102460d01200241c0006a200241a0016a41d00010f6041a200241306a41086a220c200428020036020020022002290340370330200241a0016a200241cc006a41c20010f6041a200141046a220141206a200241e1016a2d00003a0000200141186a200241d9016a290000370000200141106a200241d1016a290000370000200141086a200241c9016a290000370000200120022900c101370000200e200241106a41186a2903002205370300200b200241106a41106a29030022083703002004200241106a41086a2903002206370300200020022903102207370200200041086a2006370200200041106a2008370200200041186a200537020020022007370340200041206a2002290330370200200041286a200c280200360200200a450d022009102e200324000f0b41124101102c000b41ebdfc30041d700109b01000b200324000bdb0703037f047e087f230022022103200241e0026b416071220224002001411c6a22042902002105200420022903f801370200200141146a22042902002106200420022903f0013702002001410c6a22042902002107200420022903e801370200200241003a00e00120012902042108200120022903e00137020420022005370378200220063703702002200737036820022008370360200141246a2d00002104200241e0016a41176a22092005370000200241e0016a41106a220a2002290071370300200241e0016a41086a220b2002290069370300200220022900613703e001024002402008a741ff01714101460d00200041073a00400c010b200241186a41176a2009290000370000200241186a41106a200a290300370300200241186a41086a200b290300370300200220022903e001370318200220043a003702400240411510292204450d00200441002900bec8443700002004410d6a41002900cbc844370000200441086a41002900c6c84437000020024295808080d0023702e401200220043602e001200241186a200241e0016a104a20022802e401210c20022802e801210420022802e001210b200241e0016a41186a22094200370300200241e0016a41106a220a4200370300200241e0016a41086a220d4200370300200242003703e001200b2004200241e0016a1000200241e0006a41186a22042009290300370300200241e0006a41106a2209200a290300370300200241e0006a41086a220a200d290300370300200220022903e001370360200241e0016a200241e0006a10b20320022d0081024102460d01200241e0006a200241e0016a41e30010f6041a200241386a41206a220d200241e0006a41206a2d00003a0000200241386a41186a220e2004290300370300200241386a41106a220f2009290300370300200241386a41086a2210200a29030037030020022002290360370338200241e0016a20024181016a41c20010f6041a200141046a220141206a200241e0016a41c1006a2d00003a0000200141186a20024199026a290000370000200141106a20024191026a290000370000200141086a20024189026a29000037000020012002290081023700002004200241186a41186a2903003703002009200241186a41106a290300370300200a200241186a41086a2903003703002002200229031837036020024188016a201029030037030020024190016a200f29030037030020024198016a200e290300370300200241a0016a200d2d00003a000020022002290338370380012000200241e0006a41c10010f6041a200c450d02200b102e200324000f0b41154101102c000b41ebdfc30041d700109b01000b200324000bd00603037f047e057f230022022103200241e0016b416071220224002001411c6a220429020021052004200229039801370200200141146a2204290200210620042002290390013702002001410c6a220429020021072004200229038801370200200241003a00800120012902042108200120022903800137020420022005370338200220063703302002200737032820022008370320200141246a2d0000210420024180016a41176a2209200537000020024180016a41106a220a200229003137030020024180016a41086a220b20022900293703002002200229002137038001024002402008a741ff01714101460d00200042003703000c010b200241176a2009290000370000200241106a200a290300370300200241086a200b2903003703002002200229038001370300200220043a001f02400240411210292204450d0020044100290090e843370000200441106a41002f00a0e8433b0000200441086a4100290098e84337000020024292808080a002370284012002200436028001200220024180016a104a200228028401210a200228028801210b200228028001210920024180016a41186a220c420037030020024180016a41106a220d420037030020024180016a41086a2204420037030020024200370380012009200b20024180016a1000200241206a41186a200c290300370300200241206a41106a200d290300370300200241206a41086a2004290300370300200220022903800137032020024180016a200241206a10ad0320022d0098014102460d012004290300210520022802900121042002290380012108200241206a20024194016a41c60010f6041a20024180016a200241246a41c20010f6041a200141046a220141206a200241c1016a2d00003a0000200141186a200241b9016a290000370000200141106a200241b1016a290000370000200141086a200241a9016a290000370000200120022900a10137000020002002290300370008200041106a200241086a290300370000200041186a200241106a290300370000200041206a200241186a290300370000200041306a2005370300200041286a2008370300200041386a200436020020004201370300200a450d022009102e200324000f0b41124101102c000b41ebdfc30041d700109b01000b200324000bc30401047f230041f0006b22072400200741086a200242002003200410fb04200741c0006a41eea0c50041111081012007290348210320072802402108200741e0006a41086a220942003703002007420037036041eea0c5004111200741e0006a1003200741d0006a41086a220a2009290300370300200720072903603703502007200120027d2003420020081b7c370360200741d0006a4110200741e0006a41081004200741306a20002007290308200741086a41086a290300106d200741306a41086a290300210120072903302102200741186a41c28cc00041161070200520027d200220057d2002200558200120065820012006511b22001b2103200620017d2005200254ad7d200120067d2002200554ad7d20001b2106200741186a41106a2903004200200728021822081b21052007290320420020081b2102024002402000450d00200942003703002007420037036041c28cc0004116200741e0006a1003200a20092903003703002007200729036037035020074200200520067d2002200354ad7d2206200220037d2201200256200620055620062005511b22091b37036820074200200120091b370360200741e0006a21090c010b200942003703002007420037036041c28cc0004116200741e0006a1003200a2009290300370300200720072903603703502007427f200520067c200220037c22062002542209ad7c22022009200220055420022005511b22091b3703682007427f200620091b370360200741e0006a21090b200741d0006a4110200941101004200741f0006a24000ba32302117f057e230041f0036b22062400200641d0026a200010af01410221070240024020062d00d00222084102470d0041012108413421094102210a0c010b200641d0036a41086a220a200641e4026a290200370300200641d0036a41106a220b200641ec026a290200370300200641d0036a41186a220c200641f4026a290200370300200641a8036a41086a220d20064188036a290300370300200641a8036a41106a220e20064190036a290300370300200641a8036a41186a220f20064198036a290300370300200641a8036a41206a2210200641a0036a2903003703002006200641dc026a2902003703d003200620064180036a2903003703a803200641d0026a41086a2802002109024020080d00200641fc026a2802002107200641a8026a41186a200c290300370300200641a8026a41106a200b290300370300200641a8026a41086a200a29030037030020064180026a41086a200d29030037030020064180026a41106a200e29030037030020064180026a41186a200f29030037030020064180026a41206a2010290300370300200620062903d0033703a802200620062903a803370380020b4102210a024020074102470d0041012108413421090c010b200641a8036a41186a200641a8026a41186a290300370300200641a8036a41106a200641a8026a41106a290300370300200641a8036a41086a200641a8026a41086a290300370300200641d0026a41086a20064180026a41086a290300370300200641d0026a41106a20064180026a41106a290300370300200641d0026a41186a20064180026a41186a290300370300200641d0026a41206a20064180026a41206a290300370300200620062903a8023703a80320062006290380023703d002410021082007210a0b200641e0016a41086a220b200641a8036a41086a2207290300370300200641e0016a41106a220c200641a8036a41106a290300370300200641e0016a41186a220d200641a8036a41186a290300370300200641b8016a41086a220e200641d0026a41086a290300370300200641b8016a41106a220f200641d0026a41106a290300370300200641b8016a41186a2210200641d0026a41186a290300370300200641b8016a41206a2211200641d0026a41206a290300370300200620062903a8033703e001200620062903d0023703b8010240024020080d0020064190016a221220062903b801370300200641f4006a200b290300370200200641fc006a200c29030037020020064184016a200d29030037020020064198016a200e290300370300200641a0016a200f290300370300200641a8016a2010290300370300200641b0016a201129030037030020062009360268200620062903e00137026c2006200a36028c0120074200370300200642003703a80341b0f3c200410d200641a8036a1003200641d0036a41086a2007290300370300200620062903a8033703d003200641e0006a200641d0036a10ac032006280264410020062802601b210d4101210802400240200628028c014101470d002012280200200d460d010b200641d0026a200110af010240024020062d00d002220a4102470d00412e210a41cee2c300210b0c010b200641a8026a41026a20062d00d3023a0000200641a8036a41086a2208200641e4026a280200360200200620062f00d1023b01a8022006200641dc026a2902003703a803200641ec026a2802002107200641e8026a28020021090240200a0d0041012108412e210a41cee2c300210b024020070d000c020b2009102e0c010b200641d0026a41086a280200210a20062802d402210b200641e0016a41026a200641a8026a41026a2d00003a000020064180026a41086a2008280200360200200620062f01a8023b01e001200620062903a80337038002200641f0026a2d0000210c410021080b200641cc026a41026a200641e0016a41026a2d00003a0000200641d0036a41086a220e20064180026a41086a280200360200200620062f01e0013b01cc0220062006290380023703d00320080d00200641cb016a200e280200360000200620062f01cc023b01b8012006200a3600bf012006200b3600bb01200620062903d0033700c3012006200c3a00d701200620073600d301200620093600cf012006200641ce026a2d00003a00ba01200628028c0121132006280290012114200620052802002211200541086a28020022154105746a3602d403200620113602d0032006200641e8006a3602d803200641a8036a200641d0036a10270240024002400240024002400240024002400240024020062802a8030d0041002107200641003602b002200642043703a802410421094100210a0c010b200641d0026a41086a2208200641a8036a41086a290300370300200620062903a8033703d002411010292209450d01200920062903d002370200200941086a200829030037020020064180026a41086a200641d0036a41086a280200360200200620062903d00337038002200641a8036a20064180026a10270240024020062802a8030d00410121074101210a0c010b410121084101210a0340200641d0026a41086a220b200641a8036a41086a290300370300200620062903a8033703d00202400240200a2008460d00200841016a21070c010b200841016a22072008490d082008410174220a20072007200a491b220a41ffffffff0071200a470d08200a410474220c4100480d080240024020080d00200c102921090c010b20092008410474200c102a21090b2009450d050b200920084104746a220820062903d002370200200841086a200b290300370200200641a8036a20064180026a10272007210820062802a8030d000b0b200620073602b0022006200a3602ac02200620093602a8020b200641e8006a41186a28020021082006280278210b200641003602d002200b2008200641d0026a100a211020062802d002220f417f460d02200641a8036a41186a200241186a290000370300200641a8036a41106a200241106a290000370300200641a8036a41086a200241086a290000370300200620022900003703a803200641003602d803200642013703d0032010200f200641d0036a10b0010240024020062802d403220e20062802d803220c6b4120490d00200c41206a210b20062802d00321080c010b200c41206a220b200c490d05200e4101742208200b200b2008491b22124100480d0502400240200e0d002012102921080c010b20062802d003200e2012102a21080b2008450d04200620123602d403200620083602d0032012210e0b2006200b3602d8032008200c6a220c20062903a803370000200c41086a200641a8036a41086a290300370000200c41106a200641a8036a41106a290300370000200c41186a200641a8036a41186a290300370000200641d0026a41186a220c4200370300200641d0026a41106a22124200370300200641d0026a41086a22164200370300200642003703d0022008200b200641d0026a100020064180026a41186a200c29030037030020064180026a41106a201229030037030020064180026a41086a2016290300370300200620062903d002370380020240200e450d002008102e0b0240200f450d002010102e0b024020064180026a200641b8016a412010f8040d000240024020070d004100210b0c010b2007410474210c2009410c6a21084100210b03402008280200200b6a210b200841106a2108200c41706a220c0d000b0b2006200628028401200b6b36028401411710292208450d06200d201420151b210f4101201320151b2110200641e8006a41106a210b200841002900b0a5433700002008410f6a41002900bfa543370000200841086a41002900b8a54337000020064297808080f0023702d402200620083602d0022000200641d0026a104a20062802d402211220062802d802211620062802d002210e200641d0026a41186a22084200370300200641d0026a41106a220c4200370300200641d0026a41086a22154200370300200642003703d002200e2016200641d0026a1000200641a8036a41186a2008290300370300200641a8036a41106a200c290300370300200641a8036a41086a2015290300370300200620062903d0023703a803200641a8036a4120100602402012450d00200e102e0b200c20043703002008200b29030037030020064180036a200f360200200641fc026a2010360200200641f8026a200d360200200641f4026a20062802840136020020064184036a2002290000370200200641d0026a41206a200b41086a2802003602002006418c036a200241086a29000037020020064194036a200241106a2900003702002006419c036a200241186a290000370200200620033703d802200641003a00d0022001200641d0026a10f001411410292208450d07200841002900d88c40370000200841106a41002800e88c40360000200841086a41002900e08c4037000020064294808080c0023702d402200620083602d0022000200641d0026a104a20062802d402210b200641c8006a20062802d002220c20062802d802106e200641c8006a41106a290300210320062802482108200629035021040240200b450d00200c102e0b2003420020081b21172004420020081b2118200641d0026a200042004200106f20062903d0022119200641306a41c28cc00041161070200641306a41106a2903004200200628023022081b21032006290338420020081b2104200641d0026a41106a290300211a20062903d802211b0240024020194200520d00200641a8036a41086a22084200370300200642003703a80341c28cc0004116200641a8036a1003200641d0036a41086a2008290300370300200620062903a8033703d0032006427f2003201a7c2004201b7c221b2004542208ad7c22042008200420035420042003511b22081b3703b0032006427f201b20081b3703a803200641a8036a21080c010b200641a8036a41086a22084200370300200642003703a80341c28cc0004116200641a8036a1003200641d0036a41086a2008290300370300200620062903a8033703d003200642002003201a7d2004201b54ad7d22192004201b7d221b200456201920035620192003511b22081b3703b00320064200201b20081b3703a803200641a8036a21080b200641d0036a4110200841101004200641206a200120182017106d200641206a41086a29030021042006290320211b200641086a41c28cc00041161070200641086a41106a29030021032006290310211720062802082108200641a8036a41086a220b4200370300200642003703a80341c28cc0004116200641a8036a1003200641d0036a41086a200b290300370300200620062903a8033703d0032006427f20042003420020081b22037c201b2017420020081b22047c221b2004542208ad7c22042008200420035420042003511b22081b3703d8022006427f201b20081b3703d002200641d0036a4110200641d0026a4110100402402007450d0020074104742107200941046a210803400240200841046a280200450d002008280200102e0b200841106a2108200741706a22070d000b0b0240200a450d002009102e0b200541046a280200450d0c2011102e0c0c0b200920074104746a2111200921082007450d0720092108034002402008280200220b0d00200841106a21080c090b200841046a2802002107200841086a28020021002008410c6a280200210c20062802800121022006280278210d200641d0026a41186a220e4200370300200641d0026a41106a220f4200370300200641d0026a41086a22104200370300200642003703d002200b4120200641d0026a1000200641a8036a41186a200e290300370300200641a8036a41106a200f290300370300200641a8036a41086a2010290300370300200620062903d0023703a803200d2002200641a8036a41202007200c100b02402000450d002007102e0b200841106a22082011470d000c090b0b41104104102c000b200c4104102c000b41c0e6c5004138109b01000b20124101102c000b102d000b41174101102c000b41144101102c000b20082011460d0003402008280200450d010240200841086a280200450d00200841046a280200102e0b200841106a22082011470d000b0b200a450d002009102e0b200641fc006a280200450d002006280278102e0b200541046a280200450d002005280200102e0b200641f0036a24000bac0e010c7f230041c0036b220124000240024002400240024002400240411210292202450d0020024100290090e843370000200241106a41002f00a0e8433b0000200241086a4100290098e84337000020014292808080a0023702e402200120023602e0022000200141e0026a104a20012802e402210320012802e802210220012802e0022100200141e0026a41186a22044200370300200141e0026a41106a22054200370300200141e0026a41086a22064200370300200142003703e00220002002200141e0026a1000200141c0026a41186a2004290300370300200141c0026a41106a2005290300370300200141c0026a41086a2006290300370300200120012903e0023703c002200141e0026a200141c0026a10ad03024020012d00f80222024102460d00200141c0026a412010060b2001410a6a200141f9026a41c70010f6041a02402003450d002000102e0b200141d1006a2001410a6a41c70010f6041a20024102460d06200120023a00980120014198016a410172200141d1006a41c10010f6042106200141ba016a21050240024020012d00b9014101460d00410021000c010b411210292202450d0220024100290090e843370000200241106a41002f00a0e8433b0000200241086a4100290098e84337000020014292808080a0023702e402200120023602e0022005200141e0026a104a20012802e802210720012802e402210420012802e002210020012d00980121020b02400240200241ff01714101470d00411210292202450d0420024100290090e843370000200241106a41002f00a0e8433b0000200241086a4100290098e84337000020014292808080a0023702e402200120023602e0022006200141e0026a104a20012802e402210320012802e00222020d010b20012d00b9012102200141e0026a41186a22064200370300200141e0026a41106a22084200370300200141e0026a41086a22094200370300200142003703e00241f8e8c300411a200141e0026a1000200141c0026a41186a2006290300370300200141c0026a41106a2008290300370300200141c0026a41086a2009290300370300200120012903e0023703c002024020024101460d00200141c0026a412010060c060b200141203602e4022001200141c0026a3602e0022005200141e0026a109a020c050b20012802e8022108200141e0026a41186a22064200370300200141e0026a41106a22054200370300200141e0026a41086a22094200370300200142003703e00220022008200141e0026a1000200141c0026a41186a220a2006290300370300200141c0026a41106a2005290300370300200141c0026a41086a2009290300370300200120012903e0023703c002200141e0026a200141c0026a10ad0320012d00f8024102460d03200141e0016a200141e0026a41e00010f6041a20014199026a200141b9016a2205290000370000200141a1026a200541086a290000370000200141a9026a200541106a290000370000200141b1026a200541186a290000370000200141b9026a200541206a2d00003a000020064200370300200141e0026a41106a22054200370300200141e0026a41086a22094200370300200142003703e00220022008200141e0026a1000200a2006290300370300200141c0026a41106a2005290300370300200141c0026a41086a2009290300370300200120012903e0023703c002200141203602e4022001200141c0026a3602e002200141e0016a200141e0026a10dd0341012109024020030d00410021030c060b2002102e0c050b41124101102c000b41124101102c000b41124101102c000b418596c50041d300109b01000b41002102410021090b024002400240024020000d00410021050c010b200141e0026a41186a22054200370300200141e0026a41106a22064200370300200141e0026a41086a22084200370300200142003703e00220002007200141e0026a1000200141c0026a41186a220a2005290300370300200141c0026a41106a220b2006290300370300200141c0026a41086a220c2008290300370300200120012903e0023703c002200141e0026a200141c0026a10ad0320012d00f8024102460d01200141e0016a200141e0026a41e00010f6041a200141e0016a41206a20014198016a41086a29030037030020014188026a20014198016a41106a29030037030020014190026a20014198016a41186a29030037030020014198026a20014198016a41206a2d00003a000020012001290398013703f801200542003703002006420037030020084200370300200142003703e00220002007200141e0026a1000200a2005290300370300200b2006290300370300200c2008290300370300200120012903e0023703c002200141203602e4022001200141c0026a3602e002200141e0016a200141e0026a10dd03410121052004450d002000102e0b2003450d012009200245720d012002102e0c010b418596c50041d300109b01000b2004450d002000452005720d002000102e0b200141c0036a24000bd71003067f017e077f23004190036b220124000240024002400240024002400240411210292202450d00200241002900fee743370000200241106a41002f008ee8433b0000200241086a4100290086e84337000020014292808080a0023702c402200120023602c0022000200141c0026a104a20012802c402210320012802c802210220012802c0022100200141c0026a41186a22044200370300200141c0026a41106a22054200370300200141c0026a41086a22064200370300200142003703c00220002002200141c0026a1000200141a0026a41186a2004290300370300200141a0026a41106a2005290300370300200141a0026a41086a2006290300370300200120012903c0023703a002200141c0026a200141a0026a10ab03024020012d00cc0222024102460d00200141a0026a412010060b20012902c402210720012802c0022104200141026a200141cd026a41c30010f6041a02402003450d002000102e0b200141c5006a200141026a41c30010f6041a20024102460d06200120023a00880120014188016a410172200141c5006a41c10010f6042105200141aa016a21000240024020012d00a9014101460d00410021030c010b411210292202450d02200241002900fee743370000200241106a41002f008ee8433b0000200241086a4100290086e84337000020014292808080a0023702c402200120023602c0022000200141c0026a104a20012802c802210820012802c402210920012802c002210320012d00880121020b02400240200241ff01714101470d00411210292202450d04200241002900fee743370000200241106a41002f008ee8433b0000200241086a4100290086e84337000020014292808080a0023702c402200120023602c0022005200141c0026a104a20012802c402210620012802c00222050d010b20012d00a9012102200141c0026a41186a22054200370300200141c0026a41106a220a4200370300200141c0026a41086a220b4200370300200142003703c00241dee8c300411a200141c0026a1000200141a0026a41186a2005290300370300200141a0026a41106a200a290300370300200141a0026a41086a200b290300370300200120012903c0023703a002024020024101460d00200141a0026a412010060c060b200141203602c4022001200141a0026a3602c0022000200141c0026a109a020c050b20012802c802210a200141c0026a41186a22004200370300200141c0026a41106a22024200370300200141c0026a41086a220b4200370300200142003703c0022005200a200141c0026a1000200141a0026a41186a220c2000290300370300200141a0026a41106a2002290300370300200141a0026a41086a200b290300370300200120012903c0023703a002200141c0026a200141a0026a10ab0320012d00cc024102460d03200141d0016a200141c0026a41d00010f6041a200141fd016a200141a9016a220229000037000020014185026a200241086a2900003700002001418d026a200241106a29000037000020014195026a200241186a2900003700002001419d026a200241206a2d00003a000020004200370300200141c0026a41106a22024200370300200141c0026a41086a220b4200370300200142003703c0022005200a200141c0026a1000200c2000290300370300200141a0026a41106a2002290300370300200141a0026a41086a200b290300370300200120012903c0023703a002200141003602c802200142013703c00220012802d001210220012802d8012200200141c0026a1047200141dc016a210a02402000450d002000410574210003402002200141c0026a104a200241206a2102200041606a22000d000b0b200a200141c0026a10de0320012802c4022102200141a0026a412020012802c002220020012802c802100402402002450d002000102e0b024020012802d401450d0020012802d001102e0b4101210b024020060d00410021060c060b2005102e0c050b41124101102c000b41124101102c000b41124101102c000b418596c50041d300109b01000b410021054100210b0b024002400240024020030d00410021020c010b200141c0026a41186a22024200370300200141c0026a41106a22004200370300200141c0026a41086a220a4200370300200142003703c00220032008200141c0026a1000200141a0026a41186a220c2002290300370300200141a0026a41106a220d2000290300370300200141a0026a41086a220e200a290300370300200120012903c0023703a002200141c0026a200141a0026a10ab0320012d00cc024102460d01200141d0016a200141c0026a41d00010f6041a200141e4016a20014188016a41086a290300370200200141ec016a20014188016a41106a290300370200200141f4016a20014188016a41186a290300370200200141fc016a20014188016a41206a2d00003a000020012001290388013702dc012002420037030020004200370300200a4200370300200142003703c00220032008200141c0026a1000200c2002290300370300200d2000290300370300200e200a290300370300200120012903c0023703a002200141003602c802200142013703c00220012802d001210220012802d8012200200141c0026a1047200141dc016a210a02402000450d002000410574210003402002200141c0026a104a200241206a2102200041606a22000d000b0b200a200141c0026a10de0320012802c4022102200141a0026a412020012802c002220020012802c802100402402002450d002000102e0b024020012802d401450d0020012802d001102e0b410121022009450d002003102e0b2006450d01200b200545720d012005102e0c010b418596c50041d300109b01000b02402009450d002003452002720d002003102e0b2004450d002007a7450d002004102e0b20014190036a24000bf40501047f230041106b220224002002410036020820024201370300200041106a200210662002200036020c2002410c6a2002106b024002400240024002400240024020002d00184101460d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d0720034101742205200420042005491b22054100480d070240024020030d002005102921040c010b200228020020032005102a21040b2004450d0320022005360204200220043602000b2002200341016a360208200420036a41003a00000c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d0620034101742205200420042005491b22054100480d060240024020030d002005102921040c010b200228020020032005102a21040b2004450d0320022005360204200220043602000b2002200341016a360208200420036a41013a0000200041196a2002104a0b02400240200041396a2d00004101460d0002400240200228020420022802082200460d00200228020021030c010b200041016a22032000490d0720004101742204200320032004491b22044100480d070240024020000d002004102921030c010b200228020020002004102a21030b2003450d052002200436020420022003360200200228020821000b2002200041016a360208200320006a41003a00000c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d0620034101742205200420042005491b22054100480d060240024020030d002005102921040c010b200228020020032005102a21040b2004450d052002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a00002000413a6a2002104a0b2002280204210020012802002001280204200228020022012002280208100402402000450d002001102e0b200241106a24000f0b20054101102c000b20054101102c000b20044101102c000b20054101102c000b102d000bd50501037f024002400240024002400240024020002d00004101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0720024101742204200320032004491b22044100480d070240024020020d002004102921030c010b200128020020022004102a21030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41003a00000c010b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0620024101742204200320032004491b22044100480d060240024020020d002004102921030c010b200128020020022004102a21030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041016a2001104a0b024020002d00214101460d0002400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d0620004101742203200220022003491b22034100480d060240024020000d002003102921020c010b200128020020002003102a21020b2002450d0420012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41003a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0520024101742204200320032004491b22044100480d050240024020020d002004102921030c010b200128020020022004102a21030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041226a2001104a0f0b20044101102c000b20044101102c000b20034101102c000b20044101102c000b102d000b13002000410e360204200041a8e9c3003602000b3400200041c196c40036020420004100360200200041146a4115360200200041106a41c896c400360200200041086a42073702000b6b01027f230041106b22022400200241003602082002420137030002404104102922030d0041044101102c000b2003410036000020024284808080c00037020420022003360200410020021047200041086a200228020836020020002002290300370200200241106a24000b3001017f02404108102922020d0041084101102c000b20004288808080800137020420002002360200200242003700000b890201037f230041c0006b22022400200241186a4200370300200241106a22034200370300200241086a4200370300200241286a22044100360200200242003703002002420837032020024100360238200242013703302002200236023c2002413c6a200241306a106b2002200336023c2002413c6a200241306a106b2002280220210320042802002204200241306a104702402004450d00200441306c21040340200341106a200241306a104a2002200336023c200341306a21032002413c6a200241306a106b200441506a22040d000b0b20002002290330370200200041086a200241306a41086a28020036020002402002280224450d002002280220102e0b200241c0006a24000b7001017f230041306b220224002002420037031020024200370308200241033602182002410036022820024201370320200241186a200241206a10662002200241086a36022c2002412c6a200241206a106b200041086a200228022836020020002002290320370200200241306a24000b0b00200041c0843d10ab010b3001017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241043600000b13002000410236020420004190bac4003602000b3101017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241a0053600000b840a04087f047e067f057e230041a0026b2202240002400240024002400240410f10292203450d00200341002900a2e843370000200341076a41002900a9e8433700002002428f808080f0013702fc01200220033602f8012001200241f8016a104a20022802fc012104200228028002210320022802f8012105200241f0006a41186a22014200370300200241f0006a41106a22064200370300200241f0006a41086a220742003703002002420037037020052003200241f0006a1000200241d0006a41186a2001290300370300200241d0006a41106a2006290300370300200241d0006a41086a200729030037030020022002290370370350200241003602f801200241d0006a4120200241f8016a100821080240024020022802f8012209417f460d0020022009360294012002200836029001200241386a20024190016a10652002290338a70d06200241386a41106a290300210a2002290340210b200241206a20024190016a10652002290320a70d06200241306a290300210c2002290328210d200241186a20024190016a103120022802180d06200228029401220641306e220e41306c2203417f4c0d03200228021c210f0240024020030d00410821100c010b200310292210450d050b0240200f450d00410021070340200241003a009802200741016a2111410021030240024002400240034020062003460d01200241f8016a20036a20022802900122012d00003a00002002200141016a360290012002200341016a22013a0098022001210320014120470d000b200241f0006a41086a2203200241f8016a41086a290300370300200241f0006a41106a2212200241f8016a41106a290300370300200241f0006a41186a2213200241f8016a41186a290300370300200220022903f8013703702002200620016b36029401200220024190016a10652002290300a70d01200241106a290300211420022903082115200241b8016a41086a20032903002216370300200241b8016a41106a20122903002217370300200241b8016a41186a2013290300221837030020024198016a41086a2201201637030020024198016a41106a2206201737030020024198016a41186a221220183703002002200229037022163703b8012002201637039801200e2007470d03024020074101742203201120112003491b220ead42307e2216422088a70d002016a7220341004e0d030b102d000b2002410036029401200341ff0171450d00200241003a0098020b200241b8016a41086a200241d8016a41086a290300370300200e450d0a2010102e0c0a0b0240024020070d002003102921100c010b2010200741306c2003102a21100b2010450d080b2010200741306c6a22032014370308200320153703002003200229039801370310200341186a2001290300370300200341206a2006290300370300200341286a20122903003703002011200f460d012002280294012106201121070c000b0b2010450d06200fad422086200ead84211402402009450d002008102e0b2000200d3703102000200b37030020002010360220200041186a200c3703002000200a370308200041246a20143702000c010b200041186a4200370300200041106a4200370300200041086a420037030020004200370300200041286a4100360200200042083703200b02402004450d002005102e0b200241a0026a24000f0b410f4101102c000b1032000b20034108102c000b20034108102c000b41eff0c2004133200241f8016a4184f4c2001053000b860d021e7f037e230041f0026b220424000240024002400240410d10292205450d0041002106200541002900bfe843370000200541056a41002900c4e8433700002004428d808080d0013702a402200420053602a0022001200441a0026a104a20042802a402210720042802a802210820042802a0022105200441a0026a41186a22094200370300200441a0026a41106a220a4200370300200441a0026a41086a220b4200370300200442003703a00220052008200441a0026a1000200441e0016a41186a2009290300370300200441e0016a41106a200a290300370300200441e0016a41086a200b290300370300200420042903a0023703e001200441003602a002200441e0016a4120200441a0026a10082108024020042802a0022209417f460d002009450d0220082d0000220641034f0d022008102e0b02402007450d002005102e0b02400240024020060e03000201000b200441f8006a200110820220042d00784101470d04200441a0016a41186a220520044191016a290000370300200441a0016a41106a220620044189016a290000370300200441a0016a41086a220820044181016a290000370300200420042900793703a001200441a0026a200441a0016a108302200441c0016a41186a22072005290300370300200441c0016a41106a220b2006290300370300200441c0016a41086a220c2008290300370300200420042903a0013703c00120042802c002220d450d04200441e0016a41186a220e2007290300370300200441e0016a41106a220f200b290300370300200441e0016a41086a2210200c290300370300200441e0016a41286a2205200441a0026a41086a2206290300370300200441e0016a41306a2208200441a0026a41106a2207290300370300200441e0016a41386a2209200441a0026a41186a220a290300370300200441086a41286a2211200441ec026a2212280200360200200441086a41206a2213200441e4026a2214290200370300200441086a41186a2215200441dc026a2216290200370300200441086a41106a2217200441d4026a2218290200370300200441086a41086a2219200441cc026a221a290200370300200420042903c0013703e001200420042903a00237038002200420042902c402370308200441386a41386a221b2009290300370300200441386a41306a221c2008290300370300200441386a41286a221d2005290300370300200441386a41206a221e200429038002370300200441386a41186a221f200e290300370300200441386a41106a2220200f290300370300200441386a41086a22212010290300370300200420042903e0013703382009201b2903003703002008201c2903003703002005201d290300370300200441e0016a41206a221b201e290300370300200e201f290300370300200f202029030037030020102021290300370300200420042903383703e001200441f8006a41186a201f290300370300200441f8006a41106a2020290300370300200441f8006a41086a202129030037030020042004290338370378200a200929030037030020072008290300370300200620052903003703002004200d3602c0022004201b2903003703a002200441c4026a22052004290308370200201a201929030037020020182017290300370200201620152903003702002014201329030037020020122011280200360200200a290300212220072007290300222320027c2224370300200a202220037c2024202354ad7c37030020062903002122200420042903a002222320027c22243703a0022006202220037c2024202354ad7c370300200441c0016a200120022003108e0120043502c0012102200b2903002122200c2903002103200441f8006a200441a0026a10ec0302402005280200450d0020042802c002102e0b200242018521020c050b200441a0026a200110820220042d00a0024101470d03200441f8016a200441b9026a290000370300200441e0016a41106a200441b1026a290000370300200441e0016a41086a200441a9026a290000370300200420042900a1023703e001200441386a200441e0016a20022003108e0120043502384201852102200441386a41106a2903002122200441386a41086a29030021030c040b200441a0026a200120022003108e0120043502a0024201852102200441b0026a2903002122200441a8026a29030021030c030b410d4101102c000b41eff0c2004133200441a0026a4184f4c2001053000b420021020b2000200337030820002002370300200041106a2022370300200441f0026a24000b0900200042003702000bc30201067f230041d0006b22022400200242f3e885db96cddbb320370308200241086a2001412c6a2001290300200141086a290300417f410e1091010240410e10292203450d00200341002900b1e843370000200341066a41002900b7e8433700002002428e808080e001370234200220033602302000200241306a104a200228023421002002280238210420022802302103200241306a41186a22054200370300200241306a41106a22064200370300200241306a41086a220742003703002002420037033020032004200241306a1000200241106a41186a2005290300370300200241106a41106a2006290300370300200241106a41086a200729030037030020022002290330370310200241203602342002200241106a3602302001200241306a10ef0302402000450d002003102e0b200241d0006a24000f0b410e4101102c000b02000bd70302027f077e23004180016b22032400200341c0006a200110d80302400240024020032903404201520d00200241016a2104200341c0006a41086a21020340200341086a41306a200241306a2903002205370300200341086a41286a200241286a2903002206370300200341086a41206a200241206a2903002207370300200341086a41186a200241186a2903002208370300200341086a41106a200241106a2903002209370300200341086a41086a200241086a290300220a37030020032002290300220b370308200341c0006a41306a2005370300200341c0006a41286a2006370300200341c0006a41206a2007370300200341c0006a41186a2008370300200341c0006a41106a20093703002002200a3703002003200b3703402004417f6a2204450d02200341c0006a200110d80320032903404201510d000b0b200042003703000c010b2000200329034037030820004201370300200041386a200341c0006a41306a290300370300200041306a200341c0006a41286a290300370300200041286a200341c0006a41206a290300370300200041206a200341c0006a41186a290300370300200041186a200341c0006a41106a290300370300200041106a200341c8006a2903003703000b20034180016a24000bc80101027f230041106b2202240020024100360208200242013703002000412c6a2002104a2002200036020c2002410c6a2002106b2002200041106a36020c2002410c6a2002106b20002802202103200041286a28020022002002104702402000450d002003200041186c6a210003402002200336020c2002410c6a2002106b200341106a200210662000200341186a2203470d000b0b2002280204210320012802002001280204200228020022002002280208100402402003450d002000102e0b200241106a24000bf10801047f230041e0026b22052400200541f598c5004119107d0240024002402005280204410020052802001b2206417f6a220720064d0d00200541033a0098010c010b200541086a200710810320052d0098014103460d00200541a0016a200541086a41980110f6041a20052802a8022107200541a0016a102f200720014d0d0020004187cac40036020420004101360200200041086a41c7003602002002102f0c010b200541a0016a41086a22074200370300200542003703a00141f598c5004119200541a0016a1003200541086a41086a2007290300370300200520052903a0013703082005200641016a3602a001200541086a4110200541a0016a41041004200541a0016a200241880110f6041a200520033a00b002200520043602ac02200520013602a802024002400240024002400240411a10292201450d00200141186a41002f00ebc8443b0000200141106a41002900e3c844370000200141086a41002900dbc844370000200141002900d3c8443700002001411a4134102a2202450d012002200636001a200541086a41186a22014200370300200541086a41106a22044200370300200541086a41086a22074200370300200542003703082002411e200541086a1000200541b8026a41186a2001290300370300200541b8026a41106a2004290300370300200541b8026a41086a2007290300370300200520052903083703b802200541003602102005420137030820052802a8022104410410292201450d022005410436020c20052005280210220741046a36021020052001360208200120076a2004360000200541a0016a200541086a10bc01024020052d00b002220141024b0d00024002400240024020010e03000102000b410021040c020b410121040c010b410221040b200520043a00df0202400240200528020c20052802102201460d00200528020821070c010b200141016a22072001490d0720014101742208200720072008491b22084100480d070240024020010d002008102921070c010b200528020820012008102a21070b2007450d052005200836020c20052007360208200528021021010b2005200141016a360210200720016a20043a00000b20052802ac02210702400240200528020c2204200528021022016b4104490d00200528020821040c010b200141046a22082001490d0620044101742201200820082001491b22014100480d060240024020040d002001102921040c010b200528020820042001102a21040b2004450d052005200136020c20052004360208200528021021010b2005200141046a360210200420016a2007360000200528020c2101200541b8026a4120200528020822042005280210100402402001450d002004102e0b2002102e200541a0016a102f200541ac016a2006360200200541a9016a20033a0000200541a8016a41033a0000200541053a00a00141c8ecc5004100200541a0016a107220004100360200200020063602040c060b411a4101102c000b41344101102c000b41044101102c000b20084101102c000b20014101102c000b102d000b200541e0026a24000bbd0201047f230041c0006b2202240002400240411310292203450d002003410f6a41002800fcc844360000200341086a41002900f5c844370000200341002900edc844370000200341134126102a2203450d0120032001360013200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034117200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a200529030037030020022002290320370300200241206a200210af030240024020022802300d00200041003602100c010b20002002290320370300200041186a2001290300370300200041106a2004290300370300200041086a200241206a41086a2903003703000b2003102e200241c0006a24000f0b41134101102c000b41264101102c000b130020004111360204200041cccbc4003602000b3400200041f9eac40036020420004100360200200041146a410f360200200041106a4184ebc400360200200041086a42093702000b4f01027f230041106b2202240002404101102922030d0041014101102c000b200341003a0000200041086a4101360200200241013602042002200336020020002002290300370200200241106a24000b5d01027f23004190016b22022400200241033a0088010240410110292203450d00200341003a0000200042818080801037020420002003360200024020022d0088014103460d002002102f0b20024190016a24000f0b41014101102c000bfc0201057f230041c0006b22022400200241206a4200370300200241186a4200370300200241086a41086a4200370300200241003a0028200242003703082002410036023820024201370330200241086a200241306a104a02400240024020022d0028220341064b0d000240024002400240024002400240024020030e0700010203040506000b410021040c060b410121040c050b410221040c040b410321040c030b410421040c020b410521040c010b410621040b200220043a003f02400240200228023420022802382203460d00200228023021050c010b200341016a22052003490d0320034101742206200520052006491b22064100480d030240024020030d002006102921050c010b200228023020032006102a21050b2005450d022002200636023420022005360230200228023821030b2002200341016a360238200520036a20043a00000b20002002290330370200200041086a200241306a41086a280200360200200241c0006a24000f0b20064101102c000b102d000b3f01017f230041106b220224002002410036020820024201370300410020021047200041086a200228020836020020002002290300370200200241106a24000b130020004106360204200041ac87c5003602000b3201017f02404104102922020d0041044101102c000b20004284808080c0003702042000200236020020024180ce183600000b3201017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241c0d1023600000b3e01017f02404110102922020d0041104101102c000b20024200370008200242808084fea6dee111370000200042908080808002370204200020023602000b3201017f02404104102922020d0041044101102c000b20004284808080c0003702042000200236020020024180af1a3600000ba11a03037f027e017f23004190026b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e13000102030405060708090a0b0c0d0e0f101112000b20024188016a200141086a109a03200041003a0000200041106a20024188016a41086a290300370300200041086a2002290388013703000c120b200041013a00002000410220012d0001220141004720014102461b3a00010c110b200041023a0000200041086a200141086a2903003703000c100b20024188016a200141046a1039200041033a00002000410c6a20024190016a280200360200200041046a2002290388013702000c0f0b109b03000b0240024002400240200141086a280200417f6a220341014b0d0020030e020102010b41f8b3c0001058000b41012103024002402001410c6a2d00004101460d00200241026a2001410f6a2d00003a000020024190016a2001411c6a29020037030020024188016a41106a200141246a290200370300200241a0016a2001412c6a2d00003a000020022001410d6a2f00003b01002002200141146a29020037038801200141106a2802002104410021030c010b200141106a28020021040b200241246a41026a200241026a2d00003a0000200241286a41086a20024188016a41086a290300370300200241286a41106a20024188016a41106a290300370300200241286a41186a20024188016a41186a280200360200200220022f01003b01242002200229038801370328200141386a29030021052001290330210641012107200241106a21010c010b41012103024002402001410c6a2d00004101460d002002418e026a2001410f6a2d00003a000020024190016a2001411c6a29020037030020024188016a41106a200141246a290200370300200241a0016a2001412c6a2d00003a000020022001410d6a2f00003b018c022002200141146a29020037038801200141106a2802002104410021030c010b200141106a28020021040b41022107200241246a41026a2002418c026a41026a2d00003a0000200241286a41086a20024188016a41086a290300370300200241286a41106a20024188016a41106a290300370300200241286a41186a20024188016a41186a280200360200200220022f018c023b01242002200229038801370328200220012903303703102002200141386a290300370318200141c8006a290300210520012903402106200221010b20012006370300200120053703082000410c6a20033a0000200041086a20073602002000410d6a20022f01243b00002000410f6a200241266a2d00003a0000200041106a2004360200200041146a20022903283702002000411c6a200241286a41086a290300370200200041246a200241286a41106a2903003702002000412c6a200241c0006a280200360200200041386a200241106a41086a290300370300200041306a2002290310370300200041c0006a2002290300370300200041c8006a200241086a290300370300200041053a00000c0d0b20024188016a200141086a109c03200041063a0000200041386a20024188016a41306a290300370300200041306a20024188016a41286a290300370300200041286a20024188016a41206a290300370300200041206a20024188016a41186a290300370300200041186a20024188016a41106a290300370300200041106a20024188016a41086a290300370300200041086a2002290388013703000c0c0b20024188016a41186a200141286a29000037030020024188016a41106a200141206a29000037030020024190016a200141186a29000037030020024188016a41286a200141386a29000037030020024188016a41306a200141c0006a29000037030020024188016a41386a200141c8006a29000037030020024188016a41c8006a200141d8006a29000037030020024188016a41d0006a200141e0006a29000037030020024188016a41d8006a200141e8006a2900003703002002200141106a290000370388012002200141306a2900003703a8012002200141d0006a2900003703c8012001410c6a2802002203417f4c0d0c0240024020030d00410121010c010b200141046a2802002104200310292201450d0e20012004200310f6041a0b200241286a20024188016a41e00010f6041a2000410c6a2003360200200041086a2003360200200041046a2001360200200041106a200241286a41e00010f6041a200041073a00000c0b0b20024188016a200141086a109d03200041083a0000200041306a20024188016a41286a290300370300200041286a20024188016a41206a290300370300200041206a20024188016a41186a290300370300200041186a20024188016a41106a290300370300200041106a20024188016a41086a290300370300200041086a2002290388013703000c0a0b20024188016a200141046a109e03200041093a0000200041246a200241a8016a2903003702002000411c6a200241a0016a290300370200200041146a20024198016a2903003702002000410c6a20024190016a290300370200200041046a2002290388013702000c090b20024188016a200141046a109e032000410a3a0000200041246a200241a8016a2903003702002000411c6a200241a0016a290300370200200041146a20024198016a2903003702002000410c6a20024190016a290300370200200041046a2002290388013702000c080b20024188016a200141086a10d8012000410b3a0000200041c0006a20024188016a41386a290300370300200041386a20024188016a41306a290300370300200041306a20024188016a41286a290300370300200041286a20024188016a41206a290300370300200041206a20024188016a41186a290300370300200041186a20024188016a41106a290300370300200041106a20024188016a41086a290300370300200041086a2002290388013703000c070b20024188016a200141046a108b03200041046a20024188016a41c40010f6041a2000410c3a00000c060b2000410d3a0000200041046a200141046a2802003602000c050b2001410c6a2802002203417f4c0d050240024020030d00410121010c010b200141046a2802002104200310292201450d0820012004200310f6041a0b2000410e3a00002000410c6a2003360200200041086a2003360200200041046a20013602000c040b024002400240024002400240200141086a280200417f6a220341024b0d0020030e03010203010b4184dbc0001058000b200141386a2903002105200141306a290300210641012103024002402001410c6a2d00004101460d0020024190016a2001411c6a29020037030020024188016a41106a200141246a290200370300200241a0016a2001412c6a2d00003a00002002200141146a290200370388012001410d6a2f00002001410f6a2d0000411074722104200141106a2802002101410021030c010b200141106a28020021010b200241286a41186a20024188016a41186a280200360200200241286a41106a20024188016a41106a290300370300200241286a41086a20024188016a41086a2903003703002002200229038801370328410121070c030b2001410c6a28020022034108762104410221070c010b2001410c6a28020022034108762104410321070b0b2000410f3a0000200041386a2005370300200041306a2006370300200041106a2001360200200041086a2007360200200041146a20022903283702002000410c6a2004410874200341ff0171723602002000411c6a200241286a41086a290300370200200041246a200241286a41106a2903003702002000412c6a200241c0006a2802003602000c030b20024188016a200141086a109f03200041086a20024188016a41800110f6041a200041103a00000c020b0240024002400240200141046a280200417f6a220341014b0d0020030e020102010b41a8c2c2001058000b41880110292203450d072003200141086a280200109903410121010c010b4101210302400240200141086a2d00004101460d0020024188016a41086a200141186a29020037030020024188016a41106a200141206a29020037030020024188016a41186a200141286a2d00003a00002002200141106a29020037038801200141096a2f00002001410b6a2d00004110747221072001410c6a2802002104410021030c010b2001410c6a28020021040b200241286a41186a20024188016a41186a280200360200200241286a41106a20024188016a41106a290300370300200241286a41086a20024188016a41086a290300370300200220022903880137032820032007410874722103410221010b200041113a00002000410c6a2004360200200041086a2003360200200041046a2001360200200041106a2002290328370200200041186a200241286a41086a290300370200200041206a200241286a41106a290300370200200041286a200241286a41186a2802003602000c010b20024188016a200141046a108002200041046a20024188016a41e40010f6041a200041123a00000b20024190026a24000f0b1032000b20034101102c000b20034101102c000b4188014108102c000ba10301047f230041c0006b22022400024002400240411310292203450d002003410f6a41002800fcc844360000200341086a41002900f5c844370000200341002900edc844370000200341134126102a2204450d0120042000360013200241206a41186a22034200370300200241206a41106a22004200370300200241206a41086a220542003703002002420037032020044117200241206a1000200241186a2003290300370300200241106a2000290300370300200241086a200529030037030020022002290320370300411010292203450d02200320012903003700002003200141086a2903003700082002429080808080023702242002200336022020012802102105200141186a2802002203200241206a104702402003450d00200341057421002005210303402003200241206a104a200341206a2103200041606a22000d000b0b2002280224210320024120200228022022002002280228100402402003450d002000102e0b2004102e0240200141146a280200450d002005102e0b200241c0006a24000f0b41134101102c000b41264101102c000b41104101102c000be70201067f230041d0006b220224000240410f10292203450d00200341002900bd9445370000200341076a41002900c494453700002002428f808080f00137020c200220033602082001200241086a104a200228020c21042002280210210520022802082103200241086a41186a22014200370300200241086a41106a22064200370300200241086a41086a220742003703002002420037030820032005200241086a1000200241306a41186a2001290300370300200241306a41106a2006290300370300200241306a41086a200729030037030020022002290308370330200241086a200241306a412010dc010240024020022d00084101460d00200041003a00000c010b20002002290308370000200041206a200241086a41206a2d00003a0000200041186a2001290300370000200041106a2006290300370000200041086a20072903003700000b02402004450d002003102e0b200241d0006a24000f0b410f4101102c000b800e01097f23004180016b2204240002400240024002400240024002400240024002400240411a10292205450d00200541186a41002f00ebc8443b0000200541106a41002900e3c844370000200541086a41002900dbc844370000200541002900d3c8443700002005411a4134102a2205450d012005200136001a200441e0006a41186a22064200370300200441e0006a41106a22074200370300200441e0006a41086a22084200370300200442003703602005411e200441e0006a1000200441c0006a41186a2006290300370300200441c0006a41106a2007290300370300200441c0006a41086a200829030037030020042004290360370340200441c0006a412041c8ecc50041004100100521062005102e024002402006417f470d0041a997c50021060c010b200441146a200041086a2900003702002004411c6a200041106a290000370200200441246a200041186a290000370200200420013602082004200029000037020c411010292205450d03200541002900aec844370000200541086a41002900b6c84437000020044290808080800237026420042005360260200541104120102a2205450d0420042004280268220641046a3602682004200536026020044120360264200520066a2001360000200441086a410472200441e0006a104a200428026421062004280268210720042802602105200441e0006a41186a22084200370300200441e0006a41106a22094200370300200441e0006a41086a220a42003703002004420037036020052007200441e0006a1000200441c0006a41186a2008290300370300200441c0006a41106a2009290300370300200441c0006a41086a200a29030037030020042004290360370340200441c0006a412041c8ecc500410041001005210702402006450d002005102e0b02402007417f470d00200441306a2001108203200441086a41186a200041186a290000370300200441086a41106a200041106a290000370300200441086a41086a200041086a29000037030020042000290000370308024002402004280234220820042802382205460d00200428023021070c010b200541016a22062005490d0820054101742207200620062007491b220841ffffff3f712008470d08200841057422064100480d080240024020050d002006102921070c010b200428023020054105742006102a21070b2007450d0720042008360234200420073602300b200720054105746a22062004290308370000200641186a200441086a41186a290300370000200641106a200441086a41106a290300370000200641086a200441086a41086a2903003700002004200541016a220a360238411310292206450d082006410f6a41002800a6c944360000200641086a410029009fc94437000020064100290097c944370000200641134126102a2209450d0920092001360013200441e0006a41186a22064200370300200441e0006a41106a220b4200370300200441e0006a41086a220c42003703002004420037036020094117200441e0006a1000200441c0006a41186a2006290300370300200441c0006a41106a200b290300370300200441c0006a41086a200c290300370300200420042903603703402004410036021020044201370308200a200441086a10470240200a450d00200541057441206a21062007210503402005200441086a104a200541206a2105200641606a22060d000b0b200428020c2105200441c0006a4120200428020822062004280210100402402005450d002006102e0b2009102e2008450d002007102e0b200441146a200041086a2900003702002004411c6a200041106a290000370200200441246a200041186a290000370200200420013602082004200029000037020c411010292205450d09200541002900aec844370000200541086a41002900b6c84437000020044290808080800237026420042005360260200541104120102a2205450d0a2004412036026420042004280268220641046a36026820042005360260200520066a2001360000200441086a410472200441e0006a104a200428026421012004280268210520042802602100200441e0006a41186a22064200370300200441e0006a41106a22074200370300200441e0006a41086a220842003703002004420037036020002005200441e0006a1000200441c0006a41186a2006290300370300200441c0006a41106a2007290300370300200441c0006a41086a200829030037030020042004290360370340410110292205450d0b41002106200541807f410020021b2003723a0000200441c0006a41202005410110042005102e2001450d002000102e0b20044180016a240020060f0b411a4101102c000b41344101102c000b41104101102c000b41204101102c000b20064101102c000b102d000b41134101102c000b41264101102c000b41104101102c000b41204101102c000b41014101102c000bc00302067f017e230041d0006b220224000240411310292203450d002003410f6a41002800ef9345360000200341086a41002900e89345370000200341002900e0934537000020024293808080b00237022c200220033602282001200241286a1046200228022c21042002280230210320022802282101200241286a41186a22054200370300200241286a41106a22064200370300200241286a41086a220742003703002002420037032820012003200241286a1000200241086a41186a2005290300370300200241086a41106a2006290300370300200241086a41086a20072903003703002002200229032837030820024100360228200241086a4120200241286a1008210302400240024020022802282205417f460d002003450d00200220033602482002200536024c024020054104490d0020022005417c6a36024c2002200341046a36024820032800002106200241286a200241c8006a1030200228022822050d020b41eff0c2004133200241286a4184f4c2001053000b410021050c010b200229022c21082003102e20002008370208200020063602000b2000200536020402402004450d002001102e0b200241d0006a24000f0b41134101102c000bb204030e7f017e017f230041c0006b22032400200128020022042001280208220541047422066a210720012802042108200421010240024002402005450d00200341306a41017221094100210a200341306a41026a210b200341206a410172220c41076a210d0340200b2004200a6a220141036a2d00003a00002003200141016a2f00003b0130024020012d0000220e41ac01470d00200141106a21010c020b2003410c6a41026a200b2d0000220f3a0000200320032f013022103b010c200141046a29020021112001410c6a2802002112200920103b0000200941026a200f3a00002003200e3a00302003201236023c20032011370234200341206a200341306a20021083042003200c2900003703102003200d290000370017024020032d0020220e411a470d002006200a41106a220a470d010c030b0b2000200e3a000020002003290310370001200041086a20032900173700000240200541047441706a200a460d00200141186a2101034002400240200141786a220a2d0000220b4109460d00200b41ac01470d010c030b200128020041ffffffff0371450d00200a41046a280200102e0b200141106a2101200a41106a2007470d000b0b2008450d022004102e0c020b20012007460d0003400240024020012d0000220a4109460d00200a41ac01470d010c030b200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a22012007470d000b0b02402008450d002004102e0b2000411a3a00000b200341c0006a24000bf6d60202097f017e230041106b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41003a00000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41013a00000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008102921050c010b200628020020042008102a21050b2005450dad0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41023a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008102921050c010b200628020020042008102a21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008102921050c010b200628020020042008102a21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41033a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008102921050c010b200628020020042008102a21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008102921050c010b200628020020042008102a21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41043a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008102921050c010b200628020020042008102a21050b2005450db00120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41053a00000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410b3a00000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490df00120044101742207200620062007491b22074100480df0010240024020040d002007102921060c010b200928020020042007102a21060b2006450db00120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410c3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df1012004410174220a20062006200a491b220a4100480df1010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db201200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490def0120044101742207200620062007491b22074100480def010240024020040d002007102921060c010b200928020020042007102a21060b2006450db10120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410d3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df0012004410174220a20062006200a491b220a4100480df0010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db301200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca4010b0b200241046a210a2001410c6a2802002104200141086a2802002109200141046a280200210b02400240200241086a2802002002410c6a2802002201460d00200a28020021050c010b200141016a22052001490dee0120014101742206200520052006491b22064100480dee010240024020010d002006102921050c010b200a28020020012006102a21050b2005450db20120022005360204200241086a20063602002002410c6a28020021010b2002410c6a2206200141016a360200200520016a410e3a000020032009200b200b20094102746a200210840420032d0000411a470d9303200241086a2107034002400240200728020020062802002201460d00200a28020021050c010b200141016a22052001490def0120014101742208200520052008491b22084100480def010240024020010d002008102921050c010b200a28020020012008102a21050b2005450db4012002200536020420072008360200200628020021010b2006200141016a360200200520016a200441807f72200441ff0071200441077622011b3a00002001210420010d000b0240200941ffffffff0371450d00200b102e0b2000411a3a00000c95030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490ded0120044101742206200520052006491b22064100480ded010240024020040d002006102921050c010b200228020420042006102a21050b2005450db30120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410f3a00000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490dec0120044101742207200620062007491b22074100480dec010240024020040d002007102921060c010b200928020020042007102a21060b2006450db30120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41103a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490ded012004410174220a20062006200a491b220a4100480ded010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db501200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490deb0120044101742207200620062007491b22074100480deb010240024020040d002007102921060c010b200928020020042007102a21060b2006450db40120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41113a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490dec012004410174220a20062006200a491b220a4100480dec010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db601200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b02400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490deb0120044101742206200520052006491b22064100480deb010240024020040d002006102921050c010b200928020020042006102a21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a200b3a00000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dea0120044101742206200520052006491b22064100480dea010240024020040d002006102921050c010b200228020420042006102a21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411a3a00000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490de90120044101742206200520052006491b22064100480de9010240024020040d002006102921050c010b200228020420042006102a21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411b3a00000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de80120044101742207200620062007491b22074100480de8010240024020040d002007102921060c010b200928020020042007102a21060b2006450db60120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41203a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de9012004410174220a20062006200a491b220a4100480de9010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db801200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de70120044101742207200620062007491b22074100480de7010240024020040d002007102921060c010b200928020020042007102a21060b2006450db70120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41213a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de8012004410174220a20062006200a491b220a4100480de8010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db901200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de60120044101742207200620062007491b22074100480de6010240024020040d002007102921060c010b200928020020042007102a21060b2006450db80120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41223a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de7012004410174220a20062006200a491b220a4100480de7010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450dba01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de50120044101742207200620062007491b22074100480de5010240024020040d002007102921060c010b200928020020042007102a21060b2006450db90120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41233a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de6012004410174220a20062006200a491b220a4100480de6010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450dbb01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de40120044101742207200620062007491b22074100480de4010240024020040d002007102921060c010b200928020020042007102a21060b2006450dba0120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41243a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de5012004410174220a20062006200a491b220a4100480de5010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450dbc01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c99010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de30120044101742208200720072008491b22084100480de3010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dbb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41283a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de4012004410174220b20072007200b491b220b4100480de4010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dbd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de40120044101742209200620062009491b22094100480de4010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dbe012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de20120044101742208200720072008491b22084100480de2010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dbd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41293a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de3012004410174220b20072007200b491b220b4100480de3010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dbf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de30120044101742209200620062009491b22094100480de3010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de10120044101742208200720072008491b22084100480de1010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dbf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de2012004410174220b20072007200b491b220b4100480de2010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de20120044101742209200620062009491b22094100480de2010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c96010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de00120044101742208200720072008491b22084100480de0010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de1012004410174220b20072007200b491b220b4100480de1010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de10120044101742209200620062009491b22094100480de1010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddf0120044101742208200720072008491b22084100480ddf010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de0012004410174220b20072007200b491b220b4100480de0010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de00120044101742209200620062009491b22094100480de0010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dde0120044101742208200720072008491b22084100480dde010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddf012004410174220b20072007200b491b220b4100480ddf010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc701200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddf0120044101742209200620062009491b22094100480ddf010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc8012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddd0120044101742208200720072008491b22084100480ddd010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc70120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dde012004410174220b20072007200b491b220b4100480dde010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc901200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dde0120044101742209200620062009491b22094100480dde010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dca012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddc0120044101742208200720072008491b22084100480ddc010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc90120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412f3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddd012004410174220b20072007200b491b220b4100480ddd010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dcb01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddd0120044101742209200620062009491b22094100480ddd010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dcc012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c91010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddb0120044101742208200720072008491b22084100480ddb010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dcb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41303a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddc012004410174220b20072007200b491b220b4100480ddc010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dcd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddc0120044101742209200620062009491b22094100480ddc010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dce012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dda0120044101742208200720072008491b22084100480dda010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dcd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41313a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddb012004410174220b20072007200b491b220b4100480ddb010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dcf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddb0120044101742209200620062009491b22094100480ddb010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd90120044101742208200720072008491b22084100480dd9010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dcf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41323a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dda012004410174220b20072007200b491b220b4100480dda010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dda0120044101742209200620062009491b22094100480dda010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd80120044101742208200720072008491b22084100480dd8010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41333a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd9012004410174220b20072007200b491b220b4100480dd9010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd90120044101742209200620062009491b22094100480dd9010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8d010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd70120044101742208200720072008491b22084100480dd7010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41343a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd8012004410174220b20072007200b491b220b4100480dd8010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd80120044101742209200620062009491b22094100480dd8010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd60120044101742208200720072008491b22084100480dd6010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41353a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da3022004410174220b20072007200b491b220b4100480da3020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da30220044101742209200620062009491b22094100480da3020240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8b010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da10220044101742208200720072008491b22084100480da1020240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41363a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da2022004410174220b20072007200b491b220b4100480da2020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dda01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da20220044101742209200620062009491b22094100480da2020240024020040d002009102921060c010b200a28020020042009102a21060b2006450ddb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da00220044101742208200720072008491b22084100480da0020240024020040d002008102921070c010b200a28020020042008102a21070b2007450dda0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41373a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da1022004410174220b20072007200b491b220b4100480da1020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450ddc01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da10220044101742209200620062009491b22094100480da1020240024020040d002009102921060c010b200a28020020042009102a21060b2006450ddd012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c89010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9f0220044101742208200720072008491b22084100480d9f020240024020040d002008102921070c010b200a28020020042008102a21070b2007450ddc0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41383a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da0022004410174220b20072007200b491b220b4100480da0020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dde01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da00220044101742209200620062009491b22094100480da0020240024020040d002009102921060c010b200a28020020042009102a21060b2006450ddf012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9e0220044101742208200720072008491b22084100480d9e020240024020040d002008102921070c010b200a28020020042008102a21070b2007450dde0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41393a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9f022004410174220b20072007200b491b220b4100480d9f020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de001200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9f0220044101742209200620062009491b22094100480d9f020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de1012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9d0220044101742208200720072008491b22084100480d9d020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de00120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9e022004410174220b20072007200b491b220b4100480d9e020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de201200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9e0220044101742209200620062009491b22094100480d9e020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de3012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9c0220044101742208200720072008491b22084100480d9c020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de20120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9d022004410174220b20072007200b491b220b4100480d9d020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de401200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9d0220044101742209200620062009491b22094100480d9d020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de5012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c85010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9b0220044101742208200720072008491b22084100480d9b020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de40120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9c022004410174220b20072007200b491b220b4100480d9c020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de601200220073602042009200b360200200828020021040b2008200441016a360200200720046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021050c010b200441016a22052004490d9c0220044101742209200520052009491b22094100480d9c020240024020040d002009102921050c010b200a28020020042009102a21050b2005450de7012002200536020420082009360200200728020021040b2007200441016a360200200520046a200641807f72200641ff0071200641077622041b3a00002004210620040d000c84010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9a0220044101742208200720072008491b22084100480d9a020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de60120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9b022004410174220b20072007200b491b220b4100480d9b020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9b0220044101742209200620062009491b22094100480d9b020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c83010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d990220044101742208200720072008491b22084100480d99020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9a022004410174220b20072007200b491b220b4100480d9a020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dea01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9a0220044101742209200620062009491b22094100480d9a020240024020040d002009102921060c010b200a28020020042009102a21060b2006450deb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008102921050c010b200628020020042008102a21050b2005450dea0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a413f3a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008102921050c010b200628020020042008102a21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008102921050c010b200628020020042008102a21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c0003a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008102921050c010b200628020020042008102a21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742207200520052007491b22074100480d96020240024020040d002007102921050c010b200228020420042007102a21050b2005450dec0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c1003a00002003200620021085042003210220032d0000411a470df0020c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006102921050c010b200228020420042006102a21050b2005450dec0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c2003a00002003200c20021086042003210220032d0000411a470def020c7d0b200241046a2106200141046a280200210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d940220044101742208200520052008491b22084100480d94020240024020040d002008102921050c010b200628020020042008102a21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c3003a000002400240200241086a2802002205200828020022046b4104490d00200628020021050c010b200441046a22082004490d940220054101742204200820082004491b22044100480d94020240024020050d002004102921050c010b200628020020052004102a21050b2005450ded0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441046a360200200520046a20073600000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d930220044101742207200520052007491b22074100480d93020240024020040d002007102921050c010b200628020020042007102a21050b2005450ded0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a41c4003a000002400240200241086a2802002205200728020022046b4108490d00200628020021050c010b200441086a22072004490d930220054101742204200720072004491b22044100480d93020240024020050d002004102921050c010b200628020020052004102a21050b2005450dee0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441086a360200200520046a200c3700000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c5003a00000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c6003a00000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c7003a00000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c8003a00000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c9003a00000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ca003a00000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cb003a00000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cc003a00000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cd003a00000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ce003a00000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cf003a00000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d0003a00000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d1003a00000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d2003a00000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d3003a00000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d4003a00000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d5003a00000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d6003a00000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d7003a00000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d8003a00000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d9003a00000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41da003a00000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41db003a00000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dc003a00000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dd003a00000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41de003a00000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41df003a00000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e0003a00000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e1003a00000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e2003a00000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e3003a00000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e4003a00000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e5003a00000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e6003a00000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e7003a00000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490def0120044101742206200520052006491b22064100480def010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e8003a00000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dba0220044101742206200520052006491b22064100480dba020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e9003a00000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db90220044101742206200520052006491b22064100480db9020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ea003a00000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db80220044101742206200520052006491b22064100480db8020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41eb003a00000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db70220044101742206200520052006491b22064100480db7020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ec003a00000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db60220044101742206200520052006491b22064100480db6020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ed003a00000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db50220044101742206200520052006491b22064100480db5020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ee003a00000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db40220044101742206200520052006491b22064100480db4020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ef003a00000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db30220044101742206200520052006491b22064100480db3020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f0003a00000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db20220044101742206200520052006491b22064100480db2020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f1003a00000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db10220044101742206200520052006491b22064100480db1020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f2003a00000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db00220044101742206200520052006491b22064100480db0020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f3003a00000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daf0220044101742206200520052006491b22064100480daf020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f4003a00000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dae0220044101742206200520052006491b22064100480dae020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f5003a00000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad0220044101742206200520052006491b22064100480dad020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f6003a00000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac0220044101742206200520052006491b22064100480dac020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f7003a00000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dab0220044101742206200520052006491b22064100480dab020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f8003a00000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daa0220044101742206200520052006491b22064100480daa020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f9003a00000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da90220044101742206200520052006491b22064100480da9020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fa003a00000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da80220044101742206200520052006491b22064100480da8020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fb003a00000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da70220044101742206200520052006491b22064100480da7020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fc003a00000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da60220044101742206200520052006491b22064100480da6020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fd003a00000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da50220044101742206200520052006491b22064100480da5020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fe003a00000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da40220044101742206200520052006491b22064100480da4020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ff003a00000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da30220044101742206200520052006491b22064100480da3020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4180013a00000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da20220044101742206200520052006491b22064100480da2020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4181013a00000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da10220044101742206200520052006491b22064100480da1020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4182013a00000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da00220044101742206200520052006491b22064100480da0020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4183013a00000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f0220044101742206200520052006491b22064100480d9f020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4184013a00000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9e0220044101742206200520052006491b22064100480d9e020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4185013a00000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9d0220044101742206200520052006491b22064100480d9d020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4186013a00000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9c0220044101742206200520052006491b22064100480d9c020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4187013a00000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9b0220044101742206200520052006491b22064100480d9b020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4188013a00000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9a0220044101742206200520052006491b22064100480d9a020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4189013a00000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d990220044101742206200520052006491b22064100480d99020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418a013a00000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d980220044101742206200520052006491b22064100480d98020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418b013a00000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d970220044101742206200520052006491b22064100480d97020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418c013a00000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742206200520052006491b22064100480d96020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418d013a00000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418e013a00000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d940220044101742206200520052006491b22064100480d94020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418f013a00000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d930220044101742206200520052006491b22064100480d93020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4190013a00000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4191013a00000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4192013a00000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4193013a00000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4194013a00000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4195013a00000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4196013a00000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4197013a00000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4198013a00000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4199013a00000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419a013a00000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419b013a00000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419c013a00000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419d013a00000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419e013a00000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419f013a00000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a0013a00000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a1013a00000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a2013a00000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a3013a00000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a4013a00000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a5013a00000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a6013a00000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a7013a00000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a8013a00000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a9013a00000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41aa013a00000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ab013a00000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ac013a00000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ad013a00000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ae013a00000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41af013a00000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b0013a00000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b1013a00000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b2013a00000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b3013a00000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b4013a00000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b5013a00000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b6013a00000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b7013a00000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b8013a00000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b9013a00000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ba013a00000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bb013a00000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bc013a00000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bd013a00000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41be013a00000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bf013a00000b2000411a3a000020012d00004109470df201200141086a28020041ffffffff0371450df201200141046a280200102e0cf2010b20064101102c000b20064101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20064101102c000b20064101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20064101102c000b20084101102c000b20064101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20064101102c000b20064101102c000b20064101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b102d000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20074101102c000b20064101102c000b20084101102c000b20044101102c000b20074101102c000b20044101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b20002003290300370200200041086a200341086a290300370200200941ffffffff0371450d01200b102e0c010b20002002290200370200200041086a200241086a29020037020020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200341106a24000bb60301057f2004410c6a2105200441086a2106024002400240034002400240200628020020052802002207460d00200428020421080c010b200741016a22082007490d0420074101742209200820082009491b22094100480d040240024020070d002009102921080c010b200428020420072009102a21080b2008450d022004200836020420062009360200200528020021070b2005200741016a360200200820076a200141807f72200141ff0071200141077622071b3a00002007210120070d000b024020022003460d002004410c6a2105200441086a2106034020022802002101034002400240200628020020052802002207460d00200428020421080c010b200741016a22082007490d0620074101742209200820082009491b22094100480d060240024020070d002009102921080c010b200428020420072009102a21080b2008450d052004200836020420062009360200200528020021070b2005200741016a360200200820076a200141807f72200141ff0071200141077622071b3a00002007210120070d000b200241046a22022003470d000b0b2000411a3a00000f0b20094101102c000b20094101102c000b102d000bc30301067f200141c000712103200141ff0071210402400240024002400240200141077522050d002003450d010b2002410c6a2106200241086a2107034002402005417f470d00200341ff01710d020b02400240200728020020062802002208460d00200228020421030c010b200841016a22032008490d0520084101742204200320032004491b22044100480d050240024020080d002004102921030c010b200228020420082004102a21030b2003450d032002200336020420072004360200200628020021080b2006200841016a360200200320086a200141807f723a0000200541c000712103200541ff007121042005210120054107752208210520080d002008210520030d000b0b02400240200241086a2802002002410c6a2802002205460d00200228020421080c010b200541016a22082005490d0320054101742203200820082003491b22034100480d030240024020050d002003102921080c010b200228020420052003102a21080b2008450d0220022008360204200241086a20033602002002410c6a28020021050b2002410c6a200541016a360200200820056a20043a00002000411a3a00000f0b20044101102c000b20034101102c000b102d000bc30301067f2001a7220341c000712104200341ff0071210502400240024002400240200142078722014200520d002004450d010b2002410c6a2106200241086a2107034002402001427f520d00200441ff01710d020b02400240200728020020062802002204460d00200228020421050c010b200441016a22052004490d0520044101742208200520052008491b22084100480d050240024020040d002008102921050c010b200228020420042008102a21050b2005450d032002200536020420072008360200200628020021040b2006200441016a360200200520046a200341807f723a00002001a7220341c000712104200341ff00712105200142078722014200520d0020040d000b0b02400240200241086a2802002002410c6a2802002204460d00200228020421030c010b200441016a22032004490d0320044101742206200320032006491b22064100480d030240024020040d002006102921030c010b200228020420042006102a21030b2003450d0220022003360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200320046a20053a00002000411a3a00000f0b20084101102c000b20064101102c000b102d000bcf03010a7f230041306b22022400200241216a220341076a210441002105410021064100210741002108410821090240024002400340200241186a2001108804024020022802184101470d002000200229021c370204200041013602002000410c6a200241186a410c6a29020037020002402007450d00200921070340024020072d00004109470d00200741086a28020041ffffffff0371450d00200741046a280200102e0b200741106a2107200641706a22060d000b0b2008450d042009102e0c040b200220032900003703082002200429000037000f20022d0020210a2002200229000f37001f200220022903083703180240024020072008470d00200741016a220b2007490d032005200b200b2005491b220841ffffffff00712008470d032008410474220b4100480d030240024020070d00200b102921090c010b20092006200b102a21090b2009450d010b200920066a220b200a3a0000200b41016a2002290318370000200b41086a200229001f370000200541026a2105200641106a2106200741016a2107200a41ff01714106460d030c010b0b200b4108102c000b102d000b20002009360204200041003602002000410c6a2007360200200041086a20083602000b200241306a24000b99b601020a7f017e230041f0006b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490d02200320054f0d0120052003105e000b200241013a0048200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a108a04200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c610b2001280200220620046a2d000021072001410c6a2208200536020002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200741bf014b0d0020070ec001b702b702010203b70200000000000405060708090a00000000000000000b0c000000000d0e0f101100000012131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901b7020b2000410b3a000420004101360200200041056a20073a00000cb9020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da102200620056a2c00002101200820093602004100210a0240200141004e0d00411821090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410221070cbd020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a108a04200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbc020b4102210a410221070cb8020b4103210a410221070cb7020b4101210a0b410221070cb5020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da102200620056a2c00002101200820093602004100210a0240200141004e0d00411821090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410321070cbc020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a108a04200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbb020b4102210a410321070cb7020b4103210a410321070cb6020b4101210a0b410321070cb4020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da102200620056a2c00002101200820093602004100210a0240200141004e0d00411821090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410421070cbb020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a108a04200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cba020b4102210a410421070cb6020b4103210a410421070cb5020b4101210a0b410421070cb3020b410621070cb2020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb5020b410721070cb1020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb4020b410821070cb0020b200241d8006a2001108b0441042109200228025822064101460da201200241e0006a280200210b200228025c210302400240200241e4006a28020022040d00410021074100210a0c010b0240024020044102742205410275220741ffffffff03712007470d0020054100480d002005102922090d0120054104102c000b102d000b200441027421042005417c6a210a410021050340200920056a200320056a2802003602002004200541046a2205470d000b200a41027641016a210a0b0240200b450d002003102e0b20022d005c4105470dae022006450dae0220022802640da3010cae020b410a21070cae020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddb012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb1020b410b21070cad020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddb012003200541016a22044f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210720082004360200200741ff00712001411f71742009722109200141076a2101200421052007418001710d000b20014120490d01410d210120074110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb0020b0240024020032004460d00200441016a22012004490dd901200320014f0d0120012003105e000b200241013a0048200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a108a04200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000cb0020b200620046a2d0000210520082001360200024020050d00410c21074100210a0cad020b200041163a000420004101360200200041056a20053a00000caf020b410d21070cab020b410e21070caa020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cad020b410f21070ca9020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cac020b411021070ca8020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cab020b411121070ca7020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000caa020b411221070ca6020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000ca9020b411321070ca5020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddb01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca8020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9c010b20032001460d9a012001417f460dd7012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9b010b200aad210c411421070ca4020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddc01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca7020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9d010b20032001460d9b012001417f460dd8012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9c010b200aad210c411521070ca3020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddd01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca6020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9e010b20032001460d9c012001417f460dd9012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9d010b200aad210c411621070ca2020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dde01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca5020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9f010b20032001460d9d012001417f460dda012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9e010b200aad210c411721070ca1020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddf01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca4020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca0010b20032001460d9e012001417f460ddb012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9f010b200aad210c411821070ca0020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de001200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca3020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca1010b20032001460d9f012001417f460ddc012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da0010b200aad210c411921070c9f020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de101200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca2020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca2010b20032001460da0012001417f460ddd012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da1010b200aad210c411a21070c9e020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de201200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca1020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca3010b20032001460da1012001417f460dde012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da2010b200aad210c411b21070c9d020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de301200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca0020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca4010b20032001460da2012001417f460ddf012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da3010b200aad210c411c21070c9c020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de401200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9f020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca5010b20032001460da3012001417f460de0012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da4010b200aad210c411d21070c9b020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de501200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9e020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca6010b20032001460da4012001417f460de1012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da5010b200aad210c411e21070c9a020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de601200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9d020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca7010b20032001460da5012001417f460de2012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da6010b200aad210c411f21070c99020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de701200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca8010b20032001460da6012001417f460de3012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b41202107024020054120490d00410d21012004410f4b0da7010b200aad210c0c98020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de801200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9b020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca9010b20032001460da7012001417f460de4012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da8010b200aad210c412121070c97020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de901200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9a020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010caa010b20032001460da8012001417f460de5012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da9010b200aad210c412221070c96020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dea01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c99020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cab010b20032001460da9012001417f460de6012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0daa010b200aad210c412321070c95020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450deb01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c98020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cac010b20032001460daa012001417f460de7012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dab010b200aad210c412421070c94020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dec01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c97020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cad010b20032001460dab012001417f460de8012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dac010b200aad210c412521070c93020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ded01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c96020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cae010b20032001460dac012001417f460de9012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dad010b200aad210c412621070c92020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dee01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c95020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010caf010b20032001460dad012001417f460dea012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dae010b200aad210c412721070c91020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450def01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c94020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb0010b20032001460dae012001417f460deb012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0daf010b200aad210c412821070c90020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df001200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c93020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb1010b20032001460daf012001417f460dec012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0db0010b200aad210c412921070c8f020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df101200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c92020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb2010b20032001460db0012001417f460ded012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0db1010b200aad210c412a21070c8e020b0240024020032005460d00200441026a21012005417f460dee01200320014f0d0120012003105e000b200241013a0048200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a108a04200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c91020b200620056a2d0000210920082001360200024020090d00412b21074100210a0c8e020b200041153a000420004101360200200041056a20093a00000c90020b0240024020032005460d00200441026a21012005417f460dee01200320014f0d0120012003105e000b200241013a0048200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a108a04200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c90020b200620056a2d0000210920082001360200024020090d00412c21074100210a0c8d020b200041153a000420004101360200200041056a20093a00000c8f020b41002101410021090240024002400340410d210a2001411f4b0d010240024020032005460d002005417f460df2012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a044105210a0c020b200620056a2c0000210420082007360200200441ff00712001411f71742009722109200141076a21012007210520044100480d000b200441c00071210502402001411f4b0d0020050d020b0240024020014120490d0020050d010b200441ff01714108490d0320014120490d032005450d010c030b20044180017241ff017141f7014b0d020b2000200a36020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c90020b2009417f2001411f71747221090b412d21070c8b020b4200210c4100210102400240024002400340410e21072001413f4b0d010240024020032005460d002005417f460df3012003200541016a22094f0d01200541016a2003105e000b200241013a0008200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241086a360238200241286a200241d8006a108a042002290328210c20022802302101410521070c030b200620056a2d0000210420082009360200200441ff0071220aad2001413f71ad86200c84210c200141076a210120092105200441187441187522094100480d000b200941c00071210502402001413f4b0d0020050d030b02400240200141c000490d0020050d010b200141c000490d0420090d010c040b200a41ff00460d030b0b200020073a0004200020022f00183b000520004101360200200041106a2001360200200041086a200c370200200041076a2002411a6a2d00003a00000c8f020b200c427f2001413f71ad8684210c0b412e21070c8a020b02400240200320056b4104490d00200441056a21012005417b4b0dee01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420004281808080d000370300200041086a2002290228370200200041106a200241286a41086a2802003602000c8d020b200620056a280000210920082001360200412f21070c89020b02400240200320056b4108490d00200441096a2101200541774b0dee01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a042002290328210c200041106a2002280230360200200041086a200c37020020004281808080d0003703000c8c020b200620056a290000210c20082001360200413021070c88020b413121070c87020b413221070c86020b413321070c85020b413421070c84020b413521070c83020b413621070c82020b413721070c81020b413821070c80020b413921070cff010b413a21070cfe010b413b21070cfd010b413c21070cfc010b413d21070cfb010b413e21070cfa010b413f21070cf9010b41c00021070cf8010b41c10021070cf7010b41c20021070cf6010b41c30021070cf5010b41c40021070cf4010b41c50021070cf3010b41c60021070cf2010b41c70021070cf1010b41c80021070cf0010b41c90021070cef010b41ca0021070cee010b41cb0021070ced010b41cc0021070cec010b41cd0021070ceb010b41ce0021070cea010b41cf0021070ce9010b41d00021070ce8010b41d10021070ce7010b41d20021070ce6010b41d30021070ce5010b41d40021070ce4010b41d50021070ce3010b41d60021070ce2010b41d70021070ce1010b41d80021070ce0010b41d90021070cdf010b41da0021070cde010b41db0021070cdd010b41dc0021070cdc010b41dd0021070cdb010b41de0021070cda010b41df0021070cd9010b41e00021070cd8010b41e10021070cd7010b41e20021070cd6010b41e30021070cd5010b41e40021070cd4010b41e50021070cd3010b41e60021070cd2010b41e70021070cd1010b41e80021070cd0010b41e90021070ccf010b41ea0021070cce010b41eb0021070ccd010b41ec0021070ccc010b41ed0021070ccb010b41ee0021070cca010b41ef0021070cc9010b41f00021070cc8010b41f10021070cc7010b41f20021070cc6010b41f30021070cc5010b41f40021070cc4010b41f50021070cc3010b41f60021070cc2010b41f70021070cc1010b41f80021070cc0010b41f90021070cbf010b41fa0021070cbe010b41fb0021070cbd010b41fc0021070cbc010b41fd0021070cbb010b41fe0021070cba010b41ff0021070cb9010b41800121070cb8010b41810121070cb7010b41820121070cb6010b41830121070cb5010b41840121070cb4010b41850121070cb3010b41860121070cb2010b41870121070cb1010b41880121070cb0010b41890121070caf010b418a0121070cae010b418b0121070cad010b418c0121070cac010b418d0121070cab010b418e0121070caa010b418f0121070ca9010b41900121070ca8010b41910121070ca7010b41920121070ca6010b41930121070ca5010b41940121070ca4010b41950121070ca3010b41960121070ca2010b41970121070ca1010b41980121070ca0010b41990121070c9f010b419a0121070c9e010b419b0121070c9d010b419c0121070c9c010b419d0121070c9b010b419e0121070c9a010b419f0121070c99010b41a00121070c98010b41a10121070c97010b41a20121070c96010b41a30121070c95010b41a40121070c94010b41a50121070c93010b41a60121070c92010b41a70121070c91010b41a80121070c90010b41a90121070c8f010b41aa0121070c8e010b41ab0121070c8d010b200041013602002000200241d8006a41047222012902003702042000410c6a200141086a2902003702000c8f010b2002280260102e0c8a010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8c010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8a010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c88010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c86010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c84010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c82010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c80010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7e0b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7c0b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7a0b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c780b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c760b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c740b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c720b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c700b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6e0b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6c0b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6a0b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c680b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c660b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c640b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c620b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c600b417f20051035000b417f20091035000b417f20091035000b417f20091035000b417f200541016a1035000b417f200541016a1035000b417f200541016a1035000b417f200541016a1035000b417f20011035000b417f200541016a1035000b417f200541016a1035000b417f200541016a1035000b417f200541016a1035000b417f200541016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f20011035000b417f200541016a1035000b417f200541016a1035000b200520011035000b200520011035000b20092003105e000b20092003105e000b20092003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b0240024002400240024002402007200a470d002007210a0c010b2007200a490d010240200a0d004100210a024020070d00410421090c020b2009102e410421090c010b20092007410274200a4102742205102a2209450d020b4100210541002107034002402005411f4d0d00410f21010c080b20012802082206200128020c2203460d06200341016a22042003490d0320062004490d04200128020020036a2d0000210320082004360200200341ff00712005411f71742007722107200541076a21052003418001710d000b024020054120490d00410d21012003410f4b0d070b2007ad422086200aad84210c410921070c040b41809cc5001058000b20054104102c000b417f20041035000b20042006105e000b20004100360200200041106a200c3703002000410c6a2009360200200041096a200a3a0000200041086a20073a00000c020b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a280200360200200a41ffffffff0371450d002009102e0b200241f0006a24000bd30101017f230041106b22022400024002400240024020002d00000e03010200010b2002200128021841c4d4c500410b2001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c020b2002200128021841cfd4c500410c2001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c010b2002200128021841dbd4c500410d2001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040b200241106a240020000b890301067f230041306b2202240020012802002103024002402001280204220441037422050d00410021060c010b200341046a2107410021060340200728020020066a2106200741086a2107200541786a22050d000b0b024002400240024002400240200141146a2802000d00200621070c010b02402004450d00024002402006410f4b0d002003280204450d010b200620066a220720064f0d020b4101210541002107200241086a21060c020b41fce8c500410041001038000b2007417f4c0d01200241086a2106024020070d0041012105410021070c010b200710292205450d020b200241003602102002200736020c200220053602082002200241086a360214200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318200241146a418ce9c500200241186a10b5040d0220002006290200370200200041086a200641086a280200360200200241306a24000f0b1032000b20074101102c000b41a4e9c5004133200241186a41d8e9c5001053000bf30603067f017e067f230041c0006b2202240041002103410021040240024002400240024002400240034002402003411f4d0d00410f21030c020b0240024020012802082205200128020c2206460d00200641016a22072006490d05200520074f0d0120072005105e000b200241013a000f2002413c6a41013602002002420137022c200241e8d4c500360228200241213602142002200241106a36023820022002410f6a360210200241186a200241286a108a04410521030c020b200128020020066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b20034120490d01410d210320064110490d010b200241086a200241186a41086a280200220136020020022002290218220837030020002003360204200041086a2008370200200041106a2001360200200041013602000c050b410421090240024020040d004100210a0c010b4100210a4100210b0340200b220c41016a210b4100210341002105024002400240034002402003411f4d0d00410f21010c020b024002402001280208220d200128020c2206460d00200641016a22072006490d09200d20074f0d012007200d105e000b200241013a00002002413c6a41013602002002420137022c200241e8d4c500360228200241213602142002200241106a36023820022002360210200241186a200241286a108a0420022802182103200228021c2106200228022021074100210e410521010c030b200128020020066a2d000021062001200736020c200641ff00712003411f71742005722105200341076a21032006418001710d000b20034120490d0220064110490d02410d21010b0b20004101360200200041106a20073602002000410c6a2006360200200041086a20033602002000200e410874200172360204200a450d072009102e0c070b0240200a200c470d00200a4101742203200a41016a220620062003491b220341ffffffff03712003470d06200341027422064100480d0602400240200a0d002006102921090c010b2009200a4102742006102a21090b2009450d052003210a0b2005410876210e2009200c4102746a2005360200200b2004470d000b0b20002009360204200041003602002000410c6a2004360200200041086a200a3602000c040b417f20071035000b417f20071035000b20064104102c000b102d000b200241c0006a24000bf6d60202097f017e230041106b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41003a00000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41013a00000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008102921050c010b200628020020042008102a21050b2005450dad0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41023a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008102921050c010b200628020020042008102a21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008102921050c010b200628020020042008102a21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41033a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008102921050c010b200628020020042008102a21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008102921050c010b200628020020042008102a21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41043a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008102921050c010b200628020020042008102a21050b2005450db00120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41053a00000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410b3a00000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490df00120044101742207200620062007491b22074100480df0010240024020040d002007102921060c010b200928020020042007102a21060b2006450db00120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410c3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df1012004410174220a20062006200a491b220a4100480df1010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db201200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490def0120044101742207200620062007491b22074100480def010240024020040d002007102921060c010b200928020020042007102a21060b2006450db10120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410d3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df0012004410174220a20062006200a491b220a4100480df0010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db301200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca4010b0b200241046a210a2001410c6a2802002104200141086a2802002109200141046a280200210b02400240200241086a2802002002410c6a2802002201460d00200a28020021050c010b200141016a22052001490dee0120014101742206200520052006491b22064100480dee010240024020010d002006102921050c010b200a28020020012006102a21050b2005450db20120022005360204200241086a20063602002002410c6a28020021010b2002410c6a2206200141016a360200200520016a410e3a000020032009200b200b20094102746a200210840420032d0000411a470d9303200241086a2107034002400240200728020020062802002201460d00200a28020021050c010b200141016a22052001490def0120014101742208200520052008491b22084100480def010240024020010d002008102921050c010b200a28020020012008102a21050b2005450db4012002200536020420072008360200200628020021010b2006200141016a360200200520016a200441807f72200441ff0071200441077622011b3a00002001210420010d000b0240200941ffffffff0371450d00200b102e0b2000411a3a00000c95030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490ded0120044101742206200520052006491b22064100480ded010240024020040d002006102921050c010b200228020420042006102a21050b2005450db30120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410f3a00000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490dec0120044101742207200620062007491b22074100480dec010240024020040d002007102921060c010b200928020020042007102a21060b2006450db30120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41103a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490ded012004410174220a20062006200a491b220a4100480ded010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db501200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490deb0120044101742207200620062007491b22074100480deb010240024020040d002007102921060c010b200928020020042007102a21060b2006450db40120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41113a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490dec012004410174220a20062006200a491b220a4100480dec010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db601200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b02400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490deb0120044101742206200520052006491b22064100480deb010240024020040d002006102921050c010b200928020020042006102a21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a200b3a00000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dea0120044101742206200520052006491b22064100480dea010240024020040d002006102921050c010b200228020420042006102a21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411a3a00000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490de90120044101742206200520052006491b22064100480de9010240024020040d002006102921050c010b200228020420042006102a21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411b3a00000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de80120044101742207200620062007491b22074100480de8010240024020040d002007102921060c010b200928020020042007102a21060b2006450db60120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41203a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de9012004410174220a20062006200a491b220a4100480de9010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db801200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de70120044101742207200620062007491b22074100480de7010240024020040d002007102921060c010b200928020020042007102a21060b2006450db70120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41213a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de8012004410174220a20062006200a491b220a4100480de8010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db901200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de60120044101742207200620062007491b22074100480de6010240024020040d002007102921060c010b200928020020042007102a21060b2006450db80120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41223a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de7012004410174220a20062006200a491b220a4100480de7010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450dba01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de50120044101742207200620062007491b22074100480de5010240024020040d002007102921060c010b200928020020042007102a21060b2006450db90120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41233a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de6012004410174220a20062006200a491b220a4100480de6010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450dbb01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de40120044101742207200620062007491b22074100480de4010240024020040d002007102921060c010b200928020020042007102a21060b2006450dba0120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41243a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de5012004410174220a20062006200a491b220a4100480de5010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450dbc01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c99010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de30120044101742208200720072008491b22084100480de3010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dbb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41283a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de4012004410174220b20072007200b491b220b4100480de4010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dbd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de40120044101742209200620062009491b22094100480de4010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dbe012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de20120044101742208200720072008491b22084100480de2010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dbd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41293a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de3012004410174220b20072007200b491b220b4100480de3010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dbf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de30120044101742209200620062009491b22094100480de3010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de10120044101742208200720072008491b22084100480de1010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dbf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de2012004410174220b20072007200b491b220b4100480de2010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de20120044101742209200620062009491b22094100480de2010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c96010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de00120044101742208200720072008491b22084100480de0010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de1012004410174220b20072007200b491b220b4100480de1010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de10120044101742209200620062009491b22094100480de1010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddf0120044101742208200720072008491b22084100480ddf010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de0012004410174220b20072007200b491b220b4100480de0010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de00120044101742209200620062009491b22094100480de0010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dde0120044101742208200720072008491b22084100480dde010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddf012004410174220b20072007200b491b220b4100480ddf010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc701200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddf0120044101742209200620062009491b22094100480ddf010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc8012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddd0120044101742208200720072008491b22084100480ddd010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc70120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dde012004410174220b20072007200b491b220b4100480dde010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc901200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dde0120044101742209200620062009491b22094100480dde010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dca012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddc0120044101742208200720072008491b22084100480ddc010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc90120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412f3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddd012004410174220b20072007200b491b220b4100480ddd010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dcb01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddd0120044101742209200620062009491b22094100480ddd010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dcc012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c91010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddb0120044101742208200720072008491b22084100480ddb010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dcb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41303a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddc012004410174220b20072007200b491b220b4100480ddc010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dcd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddc0120044101742209200620062009491b22094100480ddc010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dce012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dda0120044101742208200720072008491b22084100480dda010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dcd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41313a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddb012004410174220b20072007200b491b220b4100480ddb010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dcf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddb0120044101742209200620062009491b22094100480ddb010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd90120044101742208200720072008491b22084100480dd9010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dcf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41323a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dda012004410174220b20072007200b491b220b4100480dda010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dda0120044101742209200620062009491b22094100480dda010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd80120044101742208200720072008491b22084100480dd8010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41333a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd9012004410174220b20072007200b491b220b4100480dd9010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd90120044101742209200620062009491b22094100480dd9010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8d010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd70120044101742208200720072008491b22084100480dd7010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41343a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd8012004410174220b20072007200b491b220b4100480dd8010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd80120044101742209200620062009491b22094100480dd8010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd60120044101742208200720072008491b22084100480dd6010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41353a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da3022004410174220b20072007200b491b220b4100480da3020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da30220044101742209200620062009491b22094100480da3020240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8b010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da10220044101742208200720072008491b22084100480da1020240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41363a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da2022004410174220b20072007200b491b220b4100480da2020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dda01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da20220044101742209200620062009491b22094100480da2020240024020040d002009102921060c010b200a28020020042009102a21060b2006450ddb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da00220044101742208200720072008491b22084100480da0020240024020040d002008102921070c010b200a28020020042008102a21070b2007450dda0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41373a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da1022004410174220b20072007200b491b220b4100480da1020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450ddc01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da10220044101742209200620062009491b22094100480da1020240024020040d002009102921060c010b200a28020020042009102a21060b2006450ddd012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c89010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9f0220044101742208200720072008491b22084100480d9f020240024020040d002008102921070c010b200a28020020042008102a21070b2007450ddc0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41383a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da0022004410174220b20072007200b491b220b4100480da0020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dde01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da00220044101742209200620062009491b22094100480da0020240024020040d002009102921060c010b200a28020020042009102a21060b2006450ddf012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9e0220044101742208200720072008491b22084100480d9e020240024020040d002008102921070c010b200a28020020042008102a21070b2007450dde0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41393a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9f022004410174220b20072007200b491b220b4100480d9f020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de001200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9f0220044101742209200620062009491b22094100480d9f020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de1012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9d0220044101742208200720072008491b22084100480d9d020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de00120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9e022004410174220b20072007200b491b220b4100480d9e020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de201200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9e0220044101742209200620062009491b22094100480d9e020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de3012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9c0220044101742208200720072008491b22084100480d9c020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de20120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9d022004410174220b20072007200b491b220b4100480d9d020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de401200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9d0220044101742209200620062009491b22094100480d9d020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de5012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c85010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9b0220044101742208200720072008491b22084100480d9b020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de40120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9c022004410174220b20072007200b491b220b4100480d9c020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de601200220073602042009200b360200200828020021040b2008200441016a360200200720046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021050c010b200441016a22052004490d9c0220044101742209200520052009491b22094100480d9c020240024020040d002009102921050c010b200a28020020042009102a21050b2005450de7012002200536020420082009360200200728020021040b2007200441016a360200200520046a200641807f72200641ff0071200641077622041b3a00002004210620040d000c84010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9a0220044101742208200720072008491b22084100480d9a020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de60120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9b022004410174220b20072007200b491b220b4100480d9b020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9b0220044101742209200620062009491b22094100480d9b020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c83010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d990220044101742208200720072008491b22084100480d99020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9a022004410174220b20072007200b491b220b4100480d9a020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dea01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9a0220044101742209200620062009491b22094100480d9a020240024020040d002009102921060c010b200a28020020042009102a21060b2006450deb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008102921050c010b200628020020042008102a21050b2005450dea0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a413f3a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008102921050c010b200628020020042008102a21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008102921050c010b200628020020042008102a21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c0003a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008102921050c010b200628020020042008102a21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742207200520052007491b22074100480d96020240024020040d002007102921050c010b200228020420042007102a21050b2005450dec0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c1003a00002003200620021085042003210220032d0000411a470df0020c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006102921050c010b200228020420042006102a21050b2005450dec0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c2003a00002003200c20021086042003210220032d0000411a470def020c7d0b200241046a2106200141046a280200210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d940220044101742208200520052008491b22084100480d94020240024020040d002008102921050c010b200628020020042008102a21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c3003a000002400240200241086a2802002205200828020022046b4104490d00200628020021050c010b200441046a22082004490d940220054101742204200820082004491b22044100480d94020240024020050d002004102921050c010b200628020020052004102a21050b2005450ded0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441046a360200200520046a20073600000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d930220044101742207200520052007491b22074100480d93020240024020040d002007102921050c010b200628020020042007102a21050b2005450ded0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a41c4003a000002400240200241086a2802002205200728020022046b4108490d00200628020021050c010b200441086a22072004490d930220054101742204200720072004491b22044100480d93020240024020050d002004102921050c010b200628020020052004102a21050b2005450dee0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441086a360200200520046a200c3700000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c5003a00000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c6003a00000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c7003a00000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c8003a00000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c9003a00000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ca003a00000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cb003a00000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cc003a00000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cd003a00000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ce003a00000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cf003a00000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d0003a00000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d1003a00000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d2003a00000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d3003a00000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d4003a00000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d5003a00000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d6003a00000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d7003a00000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d8003a00000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d9003a00000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41da003a00000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41db003a00000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dc003a00000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dd003a00000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41de003a00000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41df003a00000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e0003a00000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e1003a00000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e2003a00000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e3003a00000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e4003a00000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e5003a00000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e6003a00000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e7003a00000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490def0120044101742206200520052006491b22064100480def010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e8003a00000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dba0220044101742206200520052006491b22064100480dba020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e9003a00000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db90220044101742206200520052006491b22064100480db9020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ea003a00000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db80220044101742206200520052006491b22064100480db8020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41eb003a00000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db70220044101742206200520052006491b22064100480db7020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ec003a00000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db60220044101742206200520052006491b22064100480db6020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ed003a00000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db50220044101742206200520052006491b22064100480db5020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ee003a00000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db40220044101742206200520052006491b22064100480db4020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ef003a00000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db30220044101742206200520052006491b22064100480db3020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f0003a00000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db20220044101742206200520052006491b22064100480db2020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f1003a00000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db10220044101742206200520052006491b22064100480db1020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f2003a00000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db00220044101742206200520052006491b22064100480db0020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f3003a00000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daf0220044101742206200520052006491b22064100480daf020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f4003a00000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dae0220044101742206200520052006491b22064100480dae020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f5003a00000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad0220044101742206200520052006491b22064100480dad020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f6003a00000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac0220044101742206200520052006491b22064100480dac020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f7003a00000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dab0220044101742206200520052006491b22064100480dab020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f8003a00000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daa0220044101742206200520052006491b22064100480daa020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f9003a00000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da90220044101742206200520052006491b22064100480da9020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fa003a00000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da80220044101742206200520052006491b22064100480da8020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fb003a00000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da70220044101742206200520052006491b22064100480da7020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fc003a00000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da60220044101742206200520052006491b22064100480da6020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fd003a00000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da50220044101742206200520052006491b22064100480da5020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fe003a00000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da40220044101742206200520052006491b22064100480da4020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ff003a00000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da30220044101742206200520052006491b22064100480da3020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4180013a00000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da20220044101742206200520052006491b22064100480da2020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4181013a00000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da10220044101742206200520052006491b22064100480da1020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4182013a00000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da00220044101742206200520052006491b22064100480da0020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4183013a00000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f0220044101742206200520052006491b22064100480d9f020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4184013a00000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9e0220044101742206200520052006491b22064100480d9e020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4185013a00000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9d0220044101742206200520052006491b22064100480d9d020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4186013a00000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9c0220044101742206200520052006491b22064100480d9c020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4187013a00000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9b0220044101742206200520052006491b22064100480d9b020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4188013a00000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9a0220044101742206200520052006491b22064100480d9a020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4189013a00000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d990220044101742206200520052006491b22064100480d99020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418a013a00000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d980220044101742206200520052006491b22064100480d98020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418b013a00000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d970220044101742206200520052006491b22064100480d97020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418c013a00000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742206200520052006491b22064100480d96020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418d013a00000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418e013a00000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d940220044101742206200520052006491b22064100480d94020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418f013a00000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d930220044101742206200520052006491b22064100480d93020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4190013a00000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4191013a00000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4192013a00000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4193013a00000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4194013a00000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4195013a00000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4196013a00000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4197013a00000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4198013a00000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4199013a00000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419a013a00000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419b013a00000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419c013a00000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419d013a00000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419e013a00000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419f013a00000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a0013a00000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a1013a00000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a2013a00000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a3013a00000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a4013a00000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a5013a00000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a6013a00000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a7013a00000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a8013a00000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a9013a00000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41aa013a00000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ab013a00000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ac013a00000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ad013a00000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ae013a00000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41af013a00000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b0013a00000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b1013a00000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b2013a00000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b3013a00000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b4013a00000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b5013a00000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b6013a00000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b7013a00000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b8013a00000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b9013a00000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ba013a00000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bb013a00000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bc013a00000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bd013a00000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41be013a00000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bf013a00000b2000411a3a000020012d00004109470df201200141086a28020041ffffffff0371450df201200141046a280200102e0cf2010b20064101102c000b20064101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20064101102c000b20064101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20064101102c000b20084101102c000b20064101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20064101102c000b20064101102c000b20064101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b102d000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20074101102c000b20064101102c000b20084101102c000b20044101102c000b20074101102c000b20044101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b20002003290300370200200041086a200341086a290300370200200941ffffffff0371450d01200b102e0c010b20002002290200370200200041086a200241086a29020037020020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200341106a24000bfb07030e7f017e017f200241086a2103200241046a210420012802002205210602400240024002400240034002400240200428020020032802002207460d00200228020021080c010b200741016a22082007490d0220074101742209200820082009491b22094100480d020240024020070d002009102921080c010b200228020020072009102a21080b2008450d032002200836020020042009360200200328020021070b2003200741016a360200200820076a200641807f72200641ff0071200641077622071b3a00002007210620070d000b2001280204220a2001410c6a2802002206410c6c6a210b200141086a280200210c200a21072006450d03200a21072005450d03200b41746a210d200241086a210841002107200a210e02400340200e2103024003402003280200220f0d01200741016a2107200b2003410c6a2203470d000c080b0b2003410c6a210e200741016a21102005417f6a2105200341046a290200211102400240034002400240200241046a220428020020082802002206460d00200228020021090c010b200641016a22092006490d0620064101742201200920092001491b22014100480d060240024020060d002001102921090c010b200228020020062001102a21090b2009450d022002200936020020042001360200200828020021060b2008200641016a360200200920066a200741807f72200741ff0071200741077622061b3a0000200621072006450d020c000b0b20014101102c000b2011422088a7221221060240034002400240200428020020082802002207460d00200228020021090c010b200741016a22092007490d0520074101742201200920092001491b22014100480d050240024020070d002001102921090c010b200228020020072001102a21090b2009450d022002200936020020042001360200200828020021070b2008200741016a360200200920076a200641807f72200641ff0071200641077622071b3a00002007210620070d000b0240024020042802002206200828020022076b2012490d00200228020021060c010b200720126a22092007490d0420064101742207200920092007491b22074100480d040240024020060d002007102921060c010b200228020020062007102a21060b2006450d032002200636020020042007360200200828020021070b2008200720126a360200200620076a200f201210f6041a02402011a7450d00200f102e0b200d2003460d052010210720050d010c050b0b20014101102c000b20074101102c000b102d000b20094101102c000b2003410c6a21070b2007200b460d000340024020072802002206450d00200741046a280200450d002006102e0b2007410c6a2207200b470d000b0b0240200c450d00200a102e0b2000411a3a00000bcb0401067f200441046a2105024002400240024002400240200441086a2802002004410c6a2802002206460d00200528020021070c010b200641016a22072006490d0420064101742208200720072008491b22084100480d040240024020060d002008102921070c010b200528020020062008102a21070b2007450d0120042007360204200441086a20083602002004410c6a28020021060b2004410c6a2208200641016a360200200720066a20024101463a0000200441086a2109034002400240200928020020082802002206460d00200528020021070c010b200641016a22072006490d052006410174220a20072007200a491b220a4100480d050240024020060d00200a102921070c010b20052802002006200a102a21070b2007450d03200420073602042009200a360200200828020021060b2008200641016a360200200720066a200141807f72200141ff0071200141077622061b3a00002006210120060d000b024020024101470d002004410c6a2107200441086a2108034002400240200828020020072802002206460d00200528020021010c010b200641016a22012006490d0620064101742209200120012009491b22094100480d060240024020060d002009102921010c010b200528020020062009102a21010b2001450d052004200136020420082009360200200728020021060b2007200641016a360200200120066a200341807f72200341ff0071200341077622061b3a00002006210320060d000b0b2000411a3a00000f0b20084101102c000b200a4101102c000b20094101102c000b102d000bc30701097f230041d0006b2202240002400240024002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490d0420032005490d072001280200220620046a2d000021072001200536020c0240200741014d0d00410c21040c020b4100210820070e020302030b200241013a001f200241cc006a41013602002002420137023c200241e8d4c500360238200241213602342002200241306a36024820022002411f6a360230200241206a200241386a108a042002411a6a200241286a28020036010020022002290320370112200220022901103703002002200241166a290100370106410521040b200020073a0005200020043a000420002002290300370106200041013602002000410c6a20022901063701000c060b410121080b410120036b2109200441026a2104410021074100210a02400240034002402007411f4d0d00410f21070c020b02400240200920046a4102460d002004450d06200320044f0d0120042003105e000b200241013a0000200241cc006a41013602002002420137023c200241e8d4c500360238200241213602342002200241306a36024820022002360230200241106a200241386a108a04410521070c020b200620046a417f6a2d000021052001200436020c200541ff00712007411f7174200a72210a200441016a2104200741076a21072005418001710d000b20074120490d01410d210720054110490d010b2000200736020420004101360200200041086a2002290210370200200041106a200241106a41086a2802003602000c050b0240024020080d00410021040c010b2004417f6a2104410021074100210802400240034002402007411f4d0d00410f21040c020b0240024020032004460d002004417f460d082003200441016a22094f0d01200441016a2003105e000b200241013a0000200241cc006a41013602002002420137023c200241e8d4c500360238200241213602342002200241306a36024820022002360230200241106a200241386a108a04410521040c020b200620046a2d000021052001200936020c200541ff00712007411f71742008722108200741076a2107200921042005418001710d000b20074120490d01410d210420054110490d010b2000200436020420004101360200200041086a2002290210370200200041106a200241106a41086a2802003602000c060b410121040b2000200a360204200041003602002000410c6a2008360200200041086a20043602000c040b417f20051035000b417f20041035000b417f200441016a1035000b20052003105e000b200241d0006a24000ba60301077f2002410c6a2103200141086a28020022042105024002400240034002400240200241086a220628020020032802002207460d00200228020421080c010b200741016a22082007490d0420074101742209200820082009491b22094100480d040240024020070d002009102921080c010b200228020420072009102a21080b2008450d022002200836020420062009360200200328020021070b2003200741016a360200200820076a200541807f72200541ff0071200541077622071b3a00002007210520070d000b200128020421032001280200210802400240200241086a28020022052002410c6a28020022076b2004490d00200228020421050c010b200720046a22062007490d0320054101742207200620062007491b22074100480d030240024020050d002007102921050c010b200228020420052007102a21050b2005450d0220022005360204200241086a20073602002002410c6a28020021070b2002410c6a200720046a360200200520076a2008200410f6041a02402003450d002008102e0b2000411a3a00000f0b20094101102c000b20074101102c000b102d000b8b07010b7f230041d0086b22022400410021034100210402400240024002400240034002402003411f4d0d00410f21030c020b0240024020012802082205200128020c2206460d00200641016a22072006490d05200520074f0d0120072005105e000b200241013a0089082002411c6a41013602002002420137020c200241e8d4c5003602082002412136029c08200220024198086a360218200220024189086a36029808200241b8086a200241086a108a04410521030c020b2001280200220820066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b20034120490d01410d210320064110490d010b2000200336020420004101360200200041086a20022902b808370200200041106a200241b8086a41086a2802003602000c030b024020040d002000428080808010370200200041086a42003702000c030b200241086a410041800810f5041a410121094100210a410021064100210b03400240024002400240200520076b2004200b6b22034180082003418008491b2203490d00200720036a220c2007490d022005200c4f0d01200c2005105e000b200241013a00a708200241cc086a4101360200200242013702bc08200241e8d4c5003602b8082002412136029c08200220024198086a3602c8082002200241a7086a36029808200241a8086a200241b8086a108a0420024194086a200241b0086a280200360000200220022903a80837008c08200041053a000420002002290089083700052000410c6a20024190086a29000037000020004101360200200a450d062009102e0c060b200241086a200820076a200310f6041a2001200c36020c0240200a20066b2003490d00200320066a210c0c020b0240200620036a220c2006490d00200a4101742207200c200c2007491b22074100480d0002400240200a0d002007102921090c010b2009200a2007102a21090b02402009450d002007210a0c030b20074101102c000b102d000b2007200c1035000b200920066a200241086a200310f6041a20042003200b6a220b4d0d02200128020c21072001280208210520012802002108200c21060c000b0b417f20071035000b200241086a2009200c10cd02024020022802084101470d000240200a450d002009102e0b200041083a0004200041013602000c010b200020093602042000410c6a200c360200200041086a200a360200200041003602000b200241d0086a24000b160020012000280200220028020020002802081093040b8307010c7f200028021021030240024002400240200028020822044101460d0020030d012000280218200120022000411c6a28020028020c11040021030c030b2003450d010b0240024020020d00410021020c010b200120026a2105200041146a28020041016a21064100210720012103200121080340200341016a210902400240024020032c0000220a417f4a0d000240024020092005470d004100210b200521030c010b20032d0001413f71210b200341026a220921030b200a411f71210c0240200a41ff0171220a41df014b0d00200b200c41067472210a0c020b0240024020032005470d004100210d2005210e0c010b20032d0000413f71210d200341016a2209210e0b200d200b41067472210b0240200a41f0014f0d00200b200c410c7472210a0c020b02400240200e2005470d004100210a200921030c010b200e41016a2103200e2d0000413f71210a0b200b410674200c411274418080f0007172200a72220a418080c400470d020c040b200a41ff0171210a0b200921030b02402006417f6a2206450d00200720086b20036a21072003210820052003470d010c020b0b200a418080c400460d00024002402007450d0020072002460d0041002103200720024f0d01200120076a2c00004140480d010b200121030b2007200220031b21022003200120031b21010b20040d002000280218200120022000411c6a28020028020c1104000f0b4100210902402002450d002002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b0240200220096b200028020c2206490d002000280218200120022000411c6a28020028020c1104000f0b410021074100210902402002450d00410021092002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b200920026b20066a210a024002400240410020002d0030220320034103461b0e0402000100020b200a21074100210a0c010b200a4101762107200a41016a410176210a0b200741016a2103024003402003417f6a2203450d0120002802182000280204200028021c280210110200450d000b41010f0b2000280204210941012103200028021820012002200028021c28020c1104000d00200a41016a2103200028021c210a20002802182100034002402003417f6a22030d0041000f0b20002009200a280210110200450d000b41010f0b20030bef0201067f230041c0006b2202240041002103410021040240024003400240024002402003411f4b0d002001280204220520012802082206460d01200641016a22072006490d04200520074f0d0220072005105e000b200041013602002000410f3a00040c040b200241013a000f200241346a410136020020024201370224200241e8d4c5003602202002412136023c2002200241386a36023020022002410f6a360238200241106a200241206a108a042002410b6a200241186a28020036000020022002290310370003200041053a0004200020022900003700052000410c6a200241076a290000370000200041013602000c030b200128020020066a2d0000210620012007360208200641ff00712003411f71742004722104200341076a21032006418001710d000b0240024020034120490d002006410f4b0d010b20004100360200200020043602040c020b200041013602002000410d3a00040c010b417f20071035000b200241c0006a24000bdb06010a7f20012802042103200128020021044100210541012106410021072001280208220821090240024002400240024002400340024020072005470d002005410174220a200541016a220b200b200a491b220a4100480d070240024020050d00200a102921060c010b20062005200a102a21060b2006450d02200a21050b200620076a200941807f72200941ff00712009410776220a1b3a0000200741016a2107200a2109200a0d000b200520076b20084f0d02200720086a22092007490d052005410174220a20092009200a491b220941004e0d010c050b200a4101102c000b0240024020050d002009102921060c010b200620052009102a21060b2006450d01200921050b200620076a2004200810f6041a02402003450d002004102e0b200128020c210c0240200520086b20076b200141146a2802002209490d00200820096a20076a21030c020b200820076a220a20096a2203200a490d022005410174220a20032003200a491b220a4100480d020240024020050d00200a102921060c010b20062005200a102a21060b02402006450d00200a21050c020b200a4101102c000b20094101102c000b200620086a20076a200c200910f6041a200241086a210b200241046a210820032109024002400340024002402008280200200b2802002207460d002002280200210a0c010b200741016a220a2007490d0420074101742204200a200a2004491b22044100480d040240024020070d0020041029210a0c010b200228020020072004102a210a0b200a450d022002200a36020020082004360200200b28020021070b200b200741016a360200200a20076a200941807f72200941ff0071200941077622071b3a00002007210920070d000b02400240200241046a2802002209200241086a28020022076b2003490d00200228020021090c010b200720036a220a2007490d0320094101742207200a200a2007491b22074100480d030240024020090d002007102921090c010b200228020020092007102a21090b2009450d0220022009360200200241046a2007360200200241086a28020021070b200241086a200720036a360200200920076a2006200310f6041a02402005450d002006102e0b2000411a3a00000240200141106a280200450d00200c102e0b0f0b20044101102c000b20074101102c000b102d000be5bc0106077f017e047f017e197f027e230041f080046b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280204220320012802082204460d00200441016a22052004490d02200320054f0d0120052003105e000b200241013a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022802d88004210420022802dc8004210120004101360200200041003a00042001450d1d2004102e0c1d0b200128020020046a2d00002104200120053602082004410b4b0d02024020040e0c00100f0e0d0c0b0a02060504000b200241c0006a20011094044101210620022802442107024020022802404101470d0020074108762108200241d0006a2802002101200241c0006a41086a29030021090c1c0b4100210a200241c0006a41004180800110f5041a4100210b410021032007450d10410121064100210b410021054100210c034002400240024002402001280204220d200128020822036b2007200c6b220441808001200441808001491b2204490d00200320046a22082003490d02200d20084f0d012008200d105e000b200241013a00c88004200241ec80046a4101360200200242013702dc8004200241e8d4c5003602d88004200241213602242002200241206a3602e880042002200241c880046a360220200241286a200241d880046a108a042002290328210920022802302101410521070240200b450d002006102e0b0c1f0b200241c0006a200128020020036a200410f6041a200120083602080240200b20056b2004490d00200420056a21030c020b200520046a22032005490d14200b4101742208200320032008491b22084100480d1402400240200b0d002008102921060c010b2006200b2008102a21060b02402006450d002008210b0c020b20084101102c000b200320081035000b200620056a200241c0006a200410f6041a2003210520072004200c6a220c4b0d000c110b0b417f20051035000b200241c0006a2001109704024020022802404101470d00200041013602002000200241c0006a41047222012902003702042000410c6a200141086a2902003702000c1b0b200241d4006a2802002108200241d0006a2802002101200241cc006a2802002105200241c8006a280200210b2002280244210c410021044100210302400240034002402004411f4d0d00410f21010c0a0b20052001460d082001417f460d012005200141016a2206490d02200c20016a2d0000220a41ff00712004411f71742003722103200441076a210420062101200a418001710d000b20044120490d06410d2101200a410f4b0d080c060b417f200141016a1035000b200141016a2005105e000b200041123a000420004101360200200041056a20043a00000c190b200241c0006a20011097040240024020022802404101470d00200228024422014108762106200241c0006a41086a2903002209422088210e200241d0006a280200210a0c010b200241386a200241d4006a280200360200200241306a200241cc006a29020037030020022002290244370328410021064100210141002105024002400240024002400240024002400240034002402001411f4d0d00410f21070c070b2002280230220a20022802342204460d08200441016a22032004490d02200a2003490d01200228022820046a2d0000210420022003360234200441ff00712001411f71742005722105200141076a21012004418001710d000b024020014120490d002004410f4d0d0041002106410d21070c060b02400240024020050d004100210d410421030c010b410421034100210d4100210703402007220f41016a2107410021014100210c02400240024002400240024003404100210602402001411f4d0d00410f21070c0f0b2002280230220b20022802342204460d01200441016a220a2004490d02200b200a490d04200228022820046a2d000021042002200a360234200441ff00712001411f7174200c72210c200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d21070c0e0b200241c0006a200241286a108704024020022802404101470d002002280244220741087621062002280250210a200228024c210b200228024821080c0e0b200228024c21102002280248211120022802442112410021044100210b034002402004411f4d0d00410f21070c0e0b200228023022062002280234220a460d0c200a41016a2201200a490d0320062001490d0520022802282208200a6a2d0000210a20022001360234200a41ff00712004411f7174200b72210b200441076a2104200a418001710d000b20044120490d05200a410f4d0d05410d21070c0c0b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210b20022802e08004210a2009a72108410521070c0c0b417f200a1035000b417f20011035000b200a200b105e000b20012006105e000b41002113200241c0006a41004180800410f5041a02400240200b0d0041012114410021150c010b41002113410121144100210a4100211603400240024002400240200620016b200b20166b220441808004200441808004491b2204490d00200120046a22152001490d02200620154f0d0120152006105e000b200241013a00c78004200241013602ec8004200242013702dc8004200241e8d4c5003602d88004200241213602242002200241206a3602e880042002200241c780046a360220200241c880046a200241d880046a108a0420022802c88004210820022802cc8004210b20022802d08004210a410521072013450d0b2014102e0c0b0b200241c0006a200820016a200410f6041a2002201536023402402013200a6b2004490d002004200a6a21150c020b200a20046a2215200a490d1e20134101742201201520152001491b22014100480d1e0240024020130d002001102921140c010b201420132001102a21140b02402014450d00200121130c020b20014101102c000b200120151035000b2014200a6a200241c0006a200410f6041a200b200420166a22164d0d012002280234210120022802302106200228022821082015210a0c000b0b0240200d200f470d00200d4101742201200d41016a220420042001491b2201ad421c7e2209422088a70d1b2009a722044100480d1b02400240200d0d002004102921030c010b2003200d411c6c2004102a21030b2003450d032001210d0b2003200f411c6c6a2201200c41087622043b000120012014360210200120123602042001200c3a0000200141036a20044110763a0000200141186a2015360200200141146a20133602002001410c6a2010360200200141086a201136020020072005470d000b0b200228023420022802384621010240200228022c450d002002280228102e0b2001450d072005ad422086200dad842109410c21040c1c0b20044104102c000b2003200a105e000b417f20031035000b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210b20022802e08004210a2009a72108410521070b02402010450d0020104104742104201221010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b410021062011450d002012102e0b0240200f450d002003200f411c6c6a210c20032105034002402005410c6a2802002204450d0020052802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21010240200541146a280200450d002005280210102e0b200121052001200c470d000b0b200d450d032003102e0c030b4100210b410021080c020b20024103410220011b3a00c88004200241c0006a41146a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d88004210920022802e08004210a02402005450d0020032005411c6c6a210620032105034002402005410c6a2802002204450d0020052802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21010240200541146a280200450d002005280210102e0b2001210520012006470d000b0b2009422088210e4105210141002106200d450d022003102e0c020b200241013a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210b20022802e08004210a2009a7210841052107410021060b2006410874200741ff0171722101200bad220e4220862008ad842109200228022c450d002002280228102e0b20004101360200200041106a200a360200200041086a200e422086200942ffffffff0f838437020020002006410874200141ff0171723602040c180b200241c0006a20011097040240024020022802404101470d002002280244220b4108762101200241c0006a41086a2903002209422088210e200241d0006a28020021080c010b200241d4006a2802002114200241d0006a2802002101200241cc006a280200210a200241c8006a28020021132002280244210c410021044100210602400240024002400240024002400240024002400240024002400240034002402004411f4d0d00410f210b0c020b02400240200a2001460d002001417f460d06200a200141016a22054f0d01200141016a200a105e000b200241013a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d88004210920022802e0800421084105210b0c030b200c20016a2d0000220341ff00712004411f71742006722106200441076a2104200521012003418001710d000b20044120490d0220034110490d02410d210b0b0b2009422088a7210d2009a721160c0b0b024002400240024002400240024002400240024002400240024020060d0041002117410421030c010b200241c9006a211841042103410021174100211903402019221a41016a2119410021014100210b034002402001411f4d0d00410f210b0c170b200a2005460d142005417f460d0d200a200541016a2204490d06200c20056a2d0000220741ff00712001411f7174200b72210b200141076a2101200421052007418001710d000b024020014120490d002007410f4d0d00410d210b0c160b4100210f200241c0006a41004180800110f5041a02400240200b0d00410121102004210541002111410021070c010b41002111410121104100211541002112034002400240200a20046b200b20126b220141808001200141808001491b2201490d00200420016a22052004490d0f200a20054f0d012005200a105e000b200241013a00c78004200241013602ec8004200242013702dc8004200241e8d4c5003602d88004200241213602242002200241206a3602e880042002200241c780046a360220200241c880046a200241d880046a108a0420022903c880042209422088a7210d20022802d0800421082009a721164105210b2011450d182010102e0c180b200241c0006a200c20046a200110f6041a02400240201120156b2001490d00200120156a21070c010b201520016a22072015490d2820114101742204200720072004491b22044100480d280240024020110d002004102921100c010b201020112004102a21100b2010450d0d200421110b201020156a200241c0006a200110f6041a2005210420072115200b200120126a22124b0d000b0b20024100360234200220103602282002200736023820022007ad4220862011ad8437022c4100210141002112034002402001411f4d0d00410f210b0c140b2007200f460d12200f417f460d0a2007200f41016a220b490d052010200f6a2d000021042002200b360234200441ff00712001411f71742012722112200141076a2101200b210f2004418001710d000b024020014120490d002004410f4d0d00410d210b0c130b4100211b0240024020120d004104211c410021110c010b410021114104211c4100211d0340201d221e41016a211d4100210141002115024002400240034002402001411f4d0d00410f211520162101200d211f0c020b024002402002280230220f20022802342204460d00200441016a220b2004490d10200f200b4f0d01200b200f105e000b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d880042209422088a7211f20022802e0800421082009a72101410521150c020b2002280228221020046a2d000021072002200b360234200741ff00712001411f71742015722115200141076a21012007418001710d000b20014120490d0120074110490d0120162101200d211f410d21150b200141087621204101210741002104200821214100210b20012116201f210d0c010b0240024002400240200f200b460d00200441026a2101200b417f460d0e200f20014f0d012001200f105e000b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022802d88004212220022802dc8004212320022802e080042124410521150c010b2010200b6a2c00002104200220013602340240200441004e0d00411821150c010b0240200441c000710d00410621150c010b200441807f72220141ff017141fb014b0d0141062115200121040b20224108762120410121074100210b2023211f20242121202221010c010b20154180807c71210b201541087621042001417f732101410021070b200b200441ff017141087472201541ff017172210b02402007450d002020410874200141ff01717221162011450d15201c102e0c150b02402011201e470d0020114101742204201141016a220720072004491b220441ffffffff01712004470d28200441037422074100480d280240024020110d0020071029211c0c010b201c20114103742007102a211c0b201c450d09200421110b201c201e4103746a220420013a00042004200b360200201d2012470d000b0b4101210b41082110410021014100210741002115034020012104200241c0006a200241286a108804024020022802404101470d0020022802502121200228024c211f200228024821162002280244210b0c120b200241d880046a41026a2201201841026a2d00003a0000200220182f00003b01d88004200228024c211e2002280250211d200228025421250240024020022d0048220f4106470d00200b417f6a210b0c010b200f417e6a41034f0d00200b41016a2226200b4f21272026210b20270d004115211f41eb9bc50021164104210b200f4109470d11201d41ffffffff03710d100c110b200241c0006a41026a222620012d00003a0000200220022f01d880043b0140024020072015470d00200741016a22012007490d27201b20012001201b491b221541ffffffff00712015470d27201541047422014100480d270240024020070d002001102921100c010b201020042001102a21100b2010450d040b201020046a2201200f3a00002001410c6a2025360200200141086a201d360200200141046a201e360200200141016a20022f01403b0000200141036a20262d00003a0000201b41026a211b200441106a2101200741016a2107200b0d000b200228023420022802384621010240200228022c450d002002280228102e0b2001450d1402402017201a470d0020174101742201201741016a220420042001491b2201ad42187e2209422088a70d262009a722044100480d260240024020170d002004102921030c010b2003201741186c2004102a21030b2003450d04200121170b2003201a41186c6a2201201036020c20012012360208200120113602042001201c360200200141146a2007360200200141106a201536020020192006470d000b0b2005201446210102402013450d00200c102e0b2001450d142006ad4220862017ad842109410b21040c270b20014108102c000b20044104102c000b200f41016a2007105e000b200541016a200a105e000b20074104102c000b417f20011035000b417f200b1035000b417f200f41016a1035000b20044101102c000b200420051035000b417f200541016a1035000b417f200141016a1035000b201e102e0b0b02402007450d00201021010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b02402015450d002010102e0b2011450d01201c102e0c010b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d880042209422088a7211f20022802e0800421212009a721164105210b0b0240200228022c450d002002280228102e0b201f210d202121080c020b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210d20022802e0800421082009a721164105210b0c010b20024103410220011b3a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022802d88004211620022802dc8004210d20022802e08004210802402007450d00200441106a21054100210103400240201020016a22042d00004109470d00200441086a28020041ffffffff0371450d00200441046a280200102e0b2005200141106a2201470d000b0b02402015450d002010102e0b4105210b2011450d00201c102e0b0240201a450d002003201a41186c6a210a2003210503400240200541046a280200450d002005280200102e0b0240200541146a2802002204450d00200528020c2101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b200541186a21010240200541106a280200450d00200528020c102e0b200121052001200a470d000b0b2017450d012003102e0c010b20024103410220011b3a0028200241c0006a41146a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d88004210920022802e08004210802402006450d002003200641186c6a210a2003210503400240200541046a280200450d002005280200102e0b0240200541146a2802002204450d00200528020c2101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b200541186a21010240200541106a280200450d00200528020c102e0b200121052001200a470d000b0b2009422088210e4105210b410021012017450d012003102e0c010b200b4108762101200dad220e4220862016ad8421092013450d00200c102e0b20004101360200200041106a2008360200200041086a200e422086200942ffffffff0f838437020020002001410874200b41ff0171723602040c170b200241c0006a20011097040240024020022802404101470d00200228024422014108762106200241c0006a41086a2903002209422088210e200241d0006a280200210a0c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200370300200220022902443703d880044100210641002101410021050240024002400240024002400240024002400240034002402001411f4d0d00410f210b0c080b20022802e08004220a20022802e480042204460d09200441016a22032004490d01200a2003490d0420022802d8800420046a2d00002104200220033602e48004200441ff00712001411f71742005722105200141076a21012004418001710d000b024020014120490d002004410f4d0d0041002106410d210b0c070b0240024020050d004100210d410421030c010b410421034100210d4100210803402008221641016a2108410021014100210c0240024002400240024003404100210602402001411f4d0d00410f210b0c030b20022802e08004220b20022802e480042204460d01200441016a220a2004490d09200b200a490d0c20022802d8800420046a2d000021042002200a3602e48004200441ff00712001411f7174200c72210c200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d210b0c020b200241c0006a200241d880046a108704024020022802404101470d002002280244220b41087621062002280250210a200228024c2108200228024821070c020b200228024c21132002280248210f20022802442115200241c0006a200241d880046a108b04024020022802404101470d002002280244210b2002280250210a200228024c21082002280248210702402013450d0020134104742104201521010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b200b4108762106200f450d022015102e0c020b200228024821142002280244210702400240200228024c22010d00410021064104210b4100210a0c010b2001410274220a410275220641ffffffff03712006470d1e200a4100480d1e200a1029220b450d0d200a417c6a2110200b210120072104034020012004280200360200200141046a2101200441046a2104200a417c6a220a0d000b201041027641016a210a0b02402014450d002007102e0b200d2016470d04200d4101742201200d41016a220420042001491b2201ad421c7e2209422088a70d1d2009a722044100480d1d200d0d022004102921030c030b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088a721082002280230210a2009a721074105210b0b02402016450d0020032016411c6c6a210c20032105034002402005410c6a2802002204450d0020052802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21010240200541146a280200450d002005280210102e0b200121052001200c470d000b0b200d450d0e2003102e0c0e0b2003200d411c6c2004102a21030b2003450d052001210d0b20032016411c6c6a2201200c41087622043b00012001200b360210200120153602042001200c3a0000200141036a20044110763a0000200141186a200a360200200141146a20063602002001410c6a2013360200200141086a200f36020020082005470d000b0b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d88004102e0b2001450d072005ad422086200dad842109410a21040c1a0b417f20031035000b417f200a1035000b20044104102c000b2003200a105e000b200a200b105e000b200a4104102c000b41002108410021070c020b20024103410220011b3a00c88004200241c0006a41146a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a04200229032821092002280230210a02402005450d0020032005411c6c6a210620032105034002402005410c6a2802002204450d0020052802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21010240200541146a280200450d002005280210102e0b2001210520012006470d000b0b2009422088210e4105210141002106200d450d022003102e0c020b200241013a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088a721082002280230210a2009a721074105210b410021060b2006410874200b41ff01717221012008ad220e4220862007ad84210920022802dc8004450d0020022802d88004102e0b20004101360200200041106a200a360200200041086a200e422086200942ffffffff0f838437020020002006410874200141ff0171723602040c160b200820064621010240200b450d00200c102e0b02402001450d00410921040c0f0b20024103410220011b3a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a04200241e380046a200241306a280200360000200220022903283700db8004200041053a0004200020022900d880043700052000410c6a200241df80046a290000370000200041013602000c150b200241013a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a04410521010b2000200136020420004101360200200041086a20022902d88004370200200041106a200241d880046a41086a280200360200200b450d13200c102e0c130b200241c0006a20011097040240024020022802404101470d00200228024422044108762101200241c0006a41086a2903002209422088210e200241d0006a28020021060c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200370300200220022902443703d880044100210c4100210141002105024002400240024002400240024002400240024002400240024002400240024002400240034002402001411f4d0d00410f2104410021050c130b20022802e08004220a20022802e480042204460d11200441016a22032004490d01200a2003490d0820022802d8800420046a2d00002104200220033602e48004200441ff00712001411f71742005722105200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d2104410021050c120b0240024020050d0041002116410421030c010b410421034100210a41002116410021130340200241c0006a200241d880046a109104024020022802404101470d002002200229024c22093703c8800420022802482105200228024421042009a7210c0c110b200228024821152002280244210f0240024020022802e08004220420022802e480042206460d00200641016a22012006490d05200420014f0d0120012004105e000b200241013a00c780042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c780046a360220200241286a200241c0006a108a040c0e0b200228024c211420022802d88004220c20066a2d0000210d200220013602e480040240200d41034d0d00410a21010c100b02400240024002400240200d0e0400010203000b4100210d4100210b4100210603400240200b411f4d0d00410f21010c150b20042001460d132001417f460d092004200141016a2207490d0f200c20016a2d00002108200220073602e48004200841ff0071200b411f71742006722106200b41076a210b200721012008418001710d000b4100210d200b4120490d032008410f4d0d03410d21010c130b4100210b410021060340200b411f4b0d100240024020042001460d002001417f460d0b2004200141016a22074f0d01200141016a2004105e000b200241013a00c780042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c780046a360220200241286a200241c0006a108a040c120b200c20016a2d00002108200220073602e48004200841ff0071200b411f71742006722106200b41076a210b200721012008418001710d000b4101210d200b4120490d022008410f4d0d020c0e0b4100210b410021060340200b411f4b0d0f0240024020042001460d002001417f460d0b2004200141016a22074f0d01200141016a2004105e000b200241013a00c780042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c780046a360220200241286a200241c0006a108a040c110b200c20016a2d00002108200220073602e48004200841ff0071200b411f71742006722106200b41076a210b200721012008418001710d000b4102210d200b4120490d012008410f4b0d0d0c010b4100210b410021060340200b411f4b0d0e0240024020042001460d002001417f460d0b2004200141016a22074f0d01200141016a2004105e000b200241013a00c780042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c780046a360220200241286a200241c0006a108a040c100b200c20016a2d00002108200220073602e48004200841ff0071200b411f71742006722106200b41076a210b200721012008418001710d000b4103210d200b4120490d002008410f4b0d0c0b200220063602d080042002200d3602cc800420022902cc80042109024020162013470d0020164101742201201641016a220420042001491b2201ad42147e220e422088a70d1d200ea722044100480d1d0240024020160d002004102921030c010b2003201641146c2004102a21030b2003450d09200121160b2003201341146c6a2201200937020c20012014360208200120153602042001200f360200200a41146a210a201341016a2201211320012005470d000b0b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d88004102e0b2001450d0f2005ad4220862016ad842109410821040c1e0b417f20031035000b417f20011035000b417f200141016a1035000b417f200141016a1035000b417f200141016a1035000b417f200141016a1035000b20044104102c000b2003200a105e000b200141016a2004105e000b410d21014100210d0c030b410f21014100210d0c020b20022802282105200229022c2109410521014100210d0c010b200241013a00c780042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c780046a360220200241286a200241c0006a108a0420022802282105200229022c2109410521010b200d4108742001722104200220093703c880042009a7210c2015450d00200f102e0b20022802cc8004210602402013450d002003210103400240200141046a280200450d002001280200102e0b200141146a2101200a416c6a220a0d000b0b2016450d022003102e0c020b20024103410220011b3a00c88004200241c0006a41146a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a04200229032821092002280230210602402005450d00200541146c21042003210103400240200141046a280200450d002001280200102e0b200141146a21012004416c6a22040d000b0b2009422088210e41052104410021012016450d022003102e0c020b200241013a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088a7210c200228023021062009a72105410521040b20044108762101200cad220e4220862005ad84210920022802dc8004450d0020022802d88004102e0b20004101360200200041106a2006360200200041086a200e422086200942ffffffff0f838437020020002001410874200441ff0171723602040c120b200241c0006a20011097040240024020022802404101470d00200228024422054108762101200241c0006a41086a2903002209422088210e200241d0006a280200210a0c010b200241386a200241d4006a280200360200200241306a200241cc006a290200370300200220022902443703284100210b410021014100210602400240024002400240024002400240034002402001411f4d0d00410f21054100210c0c090b2002280230220a20022802342204460d07200441016a22052004490d01200a2005490d052002280228220c20046a2d0000210420022005360234200441ff00712001411f71742006722106200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d21054100210c0c080b024020060d00410421034100210d0c060b2006417f6a21144100211641002107410021084100210d4104210f410421030340024002400240024002400240024002400240200a2005460d00200541016a22042005490d0b200a20044f0d012004200a105e000b200241013a00c78004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c780046a360220200241c880046a200241c0006a108a0420022802c88004210c20022802cc8004210b20022802d08004210a410521130c010b200c20056a2c000021012002200436023402400240200141004e0d00411821130c010b41062113200141c00071450d00200141807f72220141ff017141fb014b0d020b0b200241e880046a200a360200200241e480046a200b360200200241e080046a200c360200200220013a00dd8004200220133a00dc80040c010b024002400240200a2004460d00200541026a21052004417f460d0b200a20054f0d012005200a105e000b200241013a00c78004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c780046a360220200241c880046a200241c0006a108a0420022802c88004210c20022802cc8004210b20022802d08004210a410521010c010b200c20046a2d00002104200220053602340240200441014b0d004100210a20040e020403040b410c21010b200241e880046a200a360200200241e480046a200b360200200241e080046a200c360200200220043a00dd8004200220013a00dc80040b200241013a00d8800420022802dc800421050c020b418002210a0b200241c0006a200241286a108704200228024c210b2002280248210c2002280244210520022802404101470d01200241d0006a280200210a0b02402008450d00200320076a21060340024020032802082204450d0020032802002101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b200341106a21010240200341046a280200450d002003280200102e0b2001210320062001470d000b0b200d450d09200f102e0c090b200841016a211302402008200d470d002016201320132016491b220d41ffffffff0071200d470d11200d41047422044100480d110240024020080d0020041029210f0c010b200f20072004102a210f0b200f450d05200f21030b200320076a220420053602002004410c6a20154180807c712001417f7341ff017172200a722215360200200441086a200b360200200441046a200c36020020142008460d06201641026a2116200741106a2107200228023421052002280230210a2002280228210c201321080c000b0b417f20051035000b417f20041035000b417f20051035000b20044104102c000b2005200a105e000b200228023420022802384621010240200228022c450d002002280228102e0b02402001450d002006ad422086200dad842109410721040c0e0b20024103410220011b3a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d88004210920022802e08004210a02402006450d00200320064104746a2106200321050340024020052802082204450d0020052802002101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b200541106a21010240200541046a280200450d002005280200102e0b2001210520012006470d000b0b2009422088210e4105210541002101200d450d022003102e0c020b200241013a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210b20022802e08004210a2009a7210c410521050b20054108762101200bad220e422086200cad842109200228022c450d002002280228102e0b20004101360200200041106a200a360200200041086a200e422086200942ffffffff0f838437020020002001410874200541ff0171723602040c110b200241c0006a20011097040240024020022802404101470d00200228024422044108762105200241c0006a41086a2903002209422088210e200241d0006a28020021010c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200220937030020022002290244220e3703d88004200ea7210c2009a721034100210420022802e4800421014100210502400240024002400240024002400240024003402004411f4b0d0120032001460d032001417f460d042003200141016a220a490d06200c20016a2d0000220641ff00712004411f71742005722105200441076a2104200a21012006418001710d000b2002200a3602e4800420044120490d012006410f4d0d0141002104410d210c0c060b200220013602e4800441002104410f210c0c050b0240024020050d00410421034100210d0c010b4100210741002106410021014100210d410421030340200241c0006a200241d880046a108f0420022f004520022d0047411074722104200228024c210b2002280248210820022d0044210c024020022802404101470d00200241d0006a2802002101200d450d082003102e0c080b200141016a210a02402001200d470d002007200a200a2007491b220dad420c7e2209422088a70d102009a722164100480d100240024020010d002016102921030c010b200320062016102a21030b2003450d050b200320066a2201200c3a0000200141036a20044110763a0000200141016a20043b0000200141086a200b360200200141046a2008360200200741026a21072006410c6a2106200a21012005200a470d000b0b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d88004102e0b2001450d062005ad422086200dad842109410621040c110b200220033602e48004200241013a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088a7210b200228023021012009a721084105210c410021040c040b417f200141016a1035000b20164104102c000b200141016a2003105e000b4100210b410021080b200441ffffff07712205410874200c41ff0171722104200bad220e4220862008ad84210920022802dc8004450d0120022802d88004102e0c010b20024103410220011b3a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088210e200228023021014105210441002105200d450d002003102e0b20004101360200200041106a2001360200200041086a200e422086200942ffffffff0f838437020020002005410874200441ff0171723602040c100b200241c0006a20011097040240024020022802404101470d00200228024422044108762105200241c0006a41086a2903002209422088210e200241d0006a28020021010c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200220937030020022002290244220e3703d88004200ea7210c2009a721054100210420022802e480042101410021060240024002400240024002400240024002400240024003402004411f4b0d0120052001460d032001417f460d042005200141016a220a490d07200c20016a2d0000220341ff00712004411f71742006722106200441076a2104200a21012003418001710d000b2002200a3602e4800420044120490d012003410f4d0d0141002104410d210a0c080b200220013602e4800441002104410f210a0c070b024020060d004100210b410421030c060b2006417f6a2116410421034108210d4100210841002107034002400240024002402005200a460d00200a41016a2201200a490d07200520014f0d0120012005105e000b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a042002280228210b200228022c210c200228023021014105210a0c010b200c200a6a2c00002104200220013602e480040240200441004e0d004118210a0c010b4107210a0240200441c000710d000c010b200441807f7222044170470d00200241c0006a200241d880046a108f0420022f004520022d004741107472210420022d0044210a20022802404101470d0120044180feff0771410876210520022802502101200228024c210c2002280248210b0b2005410874200441ff01717221042008450d092003102e0c090b200228024c21052002280248210c0240024020072008460d002008210b0c010b20084101742201200841016a220b200b2001491b220bad420c7e2209422088a70d102009a722014100480d100240024020080d002001102921030c010b20032008410c6c2001102a21030b2003450d050b2003200d6a22012005360200200141796a220520043b00002001417c6a200c360200200141786a200a3a0000200541026a20044110763a000020162007460d06200741016a2107200d410c6a210d20022802e48004210a20022802e08004210520022802d88004210c200b21080c000b0b200220053602e48004200241013a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088a7210c200228023021012009a7210b4105210a410021040c060b417f200141016a1035000b417f20011035000b20014104102c000b200141016a2005105e000b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d88004102e0b2001450d022006ad422086200bad842109410521040c0c0b4100210c4100210b0b200441ffffff07712205410874200a41ff0171722104200cad220e422086200bad84210920022802dc8004450d0120022802d88004102e0c010b20024103410220011b3a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088210e200228023021014105210441002105200b450d002003102e0b20004101360200200041106a2001360200200041086a200e422086200942ffffffff0f838437020020002005410874200441ff0171723602040c0f0b200241c0006a20011097040240024020022802404101470d00200228024422044108762105200241c0006a41086a2903002209422088210e200241d0006a28020021010c010b200241d4006a280200210d200241d0006a2802002101200241cc006a2802002105200241c8006a28020021072002280244210c4100210b41002104410021060240024002400240024002400240034002402004411f4d0d00410f2104410021050c030b20052001460d012001417f460d032005200141016a220a490d06200c20016a2d0000220341ff00712004411f71742006722106200441076a2104200a21012003418001710d000b024020044120490d002003410f4d0d00410d2104410021050c020b410421030240024020060d00410021130c010b410021164100211303402016221541016a2116200a2101410021044100210b024002400240034002402004411f4d0d00410f21040c020b0240024020052001460d002001417f460d0b2005200141016a220a4f0d01200141016a2005105e000b200241013a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022802d88004210520022802dc8004210b20022802e080042101410521040c030b200c20016a2d0000220841ff00712004411f7174200b72210b200441076a2104200a21012008418001710d000b20044120490d0220084110490d02410d21040b0b2013450d042003102e0c040b024020132015470d0020154101742201201620162001491b221341ffffffff03712013470d0e201341027422014100480d0e0240024020150d002001102921030c010b200320154102742001102a21030b2003450d070b200320154102746a200b36020020162006470d000b0b200a200d46210102402007450d00200c102e0b2001450d062006ad4220862013ad842109410421040c0f0b200241013a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210b20022802e0800421012009a72105410521040b200bad220e4220862005ad842109410021052007450d05200c102e0c050b417f200141016a1035000b417f200141016a1035000b20014104102c000b200141016a2005105e000b20024103410220011b3a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d880042209422088210e20022802e08004210141052104410021052013450d002003102e0b20004101360200200041106a2001360200200041086a200e422086200942ffffffff0f838437020020002005410874200441ff0171723602040c0e0b200241c0006a20011097040240024020022802404101470d00200228024422044108762101200241c0006a41086a2903002209422088210e200241d0006a28020021060c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200370300200220022902443703d880044100210c41002101410021050240024002400240024002400240024002400240034002402001411f4d0d00410f2104410021050c0b0b20022802e08004220a20022802e480042204460d09200441016a22032004490d02200a2003490d0120022802d8800420046a2d00002104200220033602e48004200441ff00712001411f71742005722105200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d2104410021050c0a0b02400240024020050d0041002116410421030c010b410421034100210a41002116410021130340200241c0006a200241d880046a109104200228024c210c2002280248210f20022802442110024020022802404101470d0020022802502106200f2105201021040c0a0b200241c0006a200241d880046a109104200228024c21112002280248211420022802442112024020022802404101470d0020022802502106201421052011210c201221040c090b024002400240024002400240024002400240024002400240024002400240024020022802e08004220620022802e48004220b460d00200b41016a2201200b490d02200620014f0d0120012006105e000b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022802282105200229022c210e4105210741002115410021060c160b20022802d88004220d200b6a2d00002104200220013602e48004410021150240200441034d0d0041092107410021060c160b024002400240024020040e0400010203000b410021154100210441002107034002402004411f4d0d00410f21070c180b0240024020062001460d002001417f460d072006200141016a22084f0d01200141016a2006105e000b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022802282105200229022c210e41052107410021150c190b200d20016a2d0000210b200220083602e48004200b41ff00712004411f71742007722107200441076a210420082101200b418001710d000b4100211520044120490d0f200b410f4d0d0f410d21070c160b0240024020062001460d00200b41026a21042001417f460d0620062004490d07200d20016a2c00002101200220043602e4800402402001417f4a0d00411821050c0e0b200141c000710d010c0c0b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a042002290328210920022802302104410521050c0c0b200141807f7222014170470d0a200241c0006a200241d880046a108f042002290348210920022802442107024020022802404101470d00200228025021040c0d0b410121150c0f0b200241c0006a200241d880046a108f042002290348210920022802442107024020022802404101460d00410221150c0f0b200220022802503602482007418080807871211520074180807c712106200741087621040c0c0b0240024020062001460d00200b41026a21082001417f460d0620062008490d08200d20016a2c00002104200220083602e480040240200441004e0d0041182107410021060c180b200441c000710d010c090b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0441052107200229022c210e20022802282105410021060c160b200441807f72220441ff017141fc01490d070240024020062008460d00200b41036a21012008417f460d07200620014f0d0120012006105e000b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022802282105200229022c210e41052107410021060c160b200d20086a2d0000210b200220013602e48004410021060240200b41014d0d00410c210741002115200b21040c160b2004417f732104410321150240200b0e020e000e0b410121060c0d0b417f20011035000b417f200141016a1035000b417f20041035000b20042006105e000b417f20081035000b417f20011035000b20082006105e000b41062107410021060c0d0b410721050b200141ff017141087420057221070b200220043602482007418080807871211520074180807c712106200741087621040b200220093703402002290244210e2009a721050c090b0b024020162013470d0020164101742201201641016a220b200b2001491b2201ad42287e220e422088a70d11200ea7220b4100480d110240024020160d00200b102921030c010b2003201641286c200b102a21030b2003450d03200121160b2003201341286c6a2201201236020c2001200c3602082001200f36020420012010360200200141206a20093702002001411c6a20073602002001411a6a20063a0000200141196a20043a0000200141186a20153a0000200141146a2011360200200141106a2014360200200a41286a210a201341016a2201211320012005470d000b0b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d88004102e0b2001450d082005ad4220862016ad842109410321040c120b200b4104102c000b2003200a105e000b417f20031035000b0b41002106410021040b200741ff0171200441ff0171410874722006418080fc0771722015722104200e422088a72106200ea7210c2014450d002012102e0b200f450d002010102e0b02402013450d002003210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200a41586a220a0d000b0b2016450d022003102e0c020b20024103410220011b3a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a04200229032821092002280230210602402005450d00200541286c21042003210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200441586a22040d000b0b2009422088210e41052104410021012016450d022003102e0c020b200241013a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088a7210c200228023021062009a72105410521040b20044108762101200cad220e4220862005ad84210920022802dc8004450d0020022802d88004102e0b20004101360200200041106a2006360200200041086a200e422086200942ffffffff0f838437020020002001410874200441ff0171723602040c0d0b200241c0006a20011097040240024020022802404101470d00200228024422014108762105200241c0006a41086a2903002209422088210e200241d0006a28020021040c010b200241d4006a2802002113200241d0006a2802002101200241cc006a2802002105200241c8006a28020021072002280244210c41002108410021044100210a024002400240024002400240024002400240034002402004411f4d0d00410f21014100210a0c0a0b20052001460d082001417f460d022005200141016a2206490d01200c20016a2d0000220341ff00712004411f7174200a72210a200441076a2104200621012003418001710d000b024020044120490d002003410f4d0d00410d21014100210a0c090b024002400240200a0d0041002112410421030c010b410120056b210d4100210b4104210341002112410021110340024002400240024002400240024002400240024020052006460d00200641016a22012006490d0120052001490d050240200c20066a2d0000221641e000460d004117210f0c130b201141016a211a200641026a2101410021164100210441002108034002402004411f4d0d00410f210f0c0a0b200d20016a4102460d082001450d0320052001490d07200c20016a417f6a2d0000220641ff00712004411f71742008722108200141016a2101200441076a21042006418001710d000b024020044120490d002006410f4d0d00410d210f0c090b2001417f6a210441002115410121100240024020080d00410021170c010b4100211441002106410021170340024002400240024020052004460d00200120066a2216450d09200520164f0d0120162005105e000b200241013a00282002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022802d88004210a20022802dc8004210820022802e0800421014105210f0c010b02400240200c20046a2c0000221641004e0d004118210f0c010b4106210f201641c00071450d00201641807f72221641ff017141fb014b0d020b0b2017450d0b2010102e0c0b0b200641016a210f024020062017470d002014200f200f2014491b22174100480d1b0240024020060d002017102921100c010b201020062017102a21100b20100d0020174101102c000b200441016a2104201020066a2016417f733a0000201441026a2114200f21062008200f470d000b0b2010411076411074221f201041087641ff0171410874221872201041ff017122107221144100210103404100211602402015411f4d0d00410f210f0c130b0240024020052004460d002004417f460d072005200441016a22064f0d01200441016a2005105e000b200241013a00282002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022802d88004210a20022802dc8004210820022d00e08004210120022d00e18004210520022f01e2800421044105210f0c130b200c20046a2d0000220f41ff00712015411f71742001722101201541076a211520062104200f418001710d000b20154120490d09200f410f4d0d09410d210f0c110b200241013a00282002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022802d88004210a20022802dc8004210820022d00e08004210120022d00e18004210520022f01e2800421044105210f0c110b417f20011035000b417f20011035000b417f20161035000b417f200441016a1035000b20012005105e000b20012005105e000b200241013a00282002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210820022802e0800421012009a7210a4105210f0b20014110762104200141087621050c090b0240200141014d0d004104210f41aea1c500210a412421080c070b02400240024020010e020001000b410421040c010b20052006460d06024002400240200641016a22012006490d0020052001490d010240200c20066a2c0000221641004e0d004118210f0c0c0b4106210f201641c00071450d02201641807f72221641ff017141fb014d0d022016417f732104200121060c030b417f200641016a1035000b200641016a2005105e000b0c080b024020122011470d0020124101742201201241016a221620162001491b220141ffffffff00712001470d0f200141047422164100480d0f0240024020120d002016102921030c010b200320124104742016102a21030b2003450d03200121120b200320114104746a220120194180807c71200441ff01714108747241e00072221936020c200120083602082001201736020420012018201072201f72360200200b41106a210b201a2111201a200a470d000b0b2006201346210102402007450d00200c102e0b2001450d07200aad4220862012ad842109410221040c100b20164104102c000b200141016a2005105e000b417f200141016a1035000b200241013a00282002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022802d88004210a20022802dc8004210820022d00e08004210120022d00e18004210520022f01e2800421044105210f0b0b2017450d002014102e0b200541ff0171410874200141ff017172210520044110742104201641ff0171410874210602402011450d002003210103400240200141046a280200450d002001280200102e0b200141106a2101200b41706a220b0d000b0b200520047221042006200f7221012012450d022003102e0c020b20024103410220011b3a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d88004210920022802e0800421040240200a450d00200a41047421052003210103400240200141046a280200450d002001280200102e0b200141106a2101200541706a22050d000b0b2009422088210e41052101410021052012450d022003102e0c020b200241013a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210820022802e0800421042009a7210a410521010b200141087621052008ad220e422086200aad8421092007450d00200c102e0b20004101360200200041106a2004360200200041086a200e422086200942ffffffff0f838437020020002005410874200141ff0171723602040c0c0b410021014100210402400340410021080240200a4105470d00410f21070c0b0b2003200a460d032003200a4d0d012006200a6a2d0000220541ff00712001411f71742004722104200141076a2101200a41016a220c210a2005418001710d000b024020014120490d002005410f4d0d00410d21070c0a0b024020040d0041002105410121134100210a4100210d0c050b200241c0006a410041800810f5041a410121134100210d4100210541002107034002400240024002402003200c6b200420076b22014180082001418008491b2201490d00200c20016a2216200c490d02200320164f0d0120162003105e000b200241013a00c88004200241ec80046a4101360200200242013702dc8004200241e8d4c5003602d88004200241213602242002200241206a3602e880042002200241c880046a360220200241286a200241d880046a108a0420022903282209422088a7210a200228023021012009a72104410521070240200d0d002004210d0c0f0b2013102e2004210d0c0e0b200241c0006a2006200c6a200110f6041a0240200d20056b2001490d00200120056a210a0c020b200520016a220a2005490d04200d410174220c200a200a200c491b220c4100480d0402400240200d0d00200c102921130c010b2013200d200c102a21130b02402013450d00200c210d0c020b200c4101102c000b200c20161035000b201320056a200241c0006a200110f6041a2016210c200a21052004200120076a22074d0d040c000b0b200a41016a2003105e000b102d000b200241013a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210a20022802e0800421012009a7210d410521070c070b200241c0006a2013200a10cd02024020022802404101470d00410821070240200d0d000c080b2013102e0c070b201341087621052016210c0b2003200c490d012003200c6b2204417f4c0d020240024020040d00410121010c010b200410292201450d0420012006200c6a200410f6041a0b200aad4220862109200dad210e2004ad222842208621290240200b450d002006102e0b2009200e8421092029202884210e2005410874201341ff0171722103410121040b200020043a000420004100360200200041056a20022f001d3b0000200041186a200e370200200041146a20013602002000410c6a2009370200200041086a2003360200200041206a200229020c370200200041076a2002411f6a2d00003a0000200041286a2002410c6a41086a2902003702000c060b200c20031035000b1032000b20044101102c000b4100210a4100210d0b200aad422086200dad842109200b450d002006102e0b20004101360200200041106a2001360200200041086a200937020020002008410874200741ff0171723602040b200241f080046a24000bf404010b7f230041c080016b2202240020022001109404410121030240024020022802004101470d0020002002290204370204200041013602002000410c6a2002410c6a2902003702000c010b20022802042104200241004180800110f5042105410021064100210702400240024002402004450d00410021084100210641012103410021090340024002402001280204220a200128020822076b200420096b220b41808001200b41808001491b220b490d002007200b6a220c2007490d04200a200c4f0d01200c200a105e000b200541013a008f8001200541b480016a4101360200200542013702a48001200541e8d4c5003602a08001200541213602bc80012005200541b880016a3602b0800120052005418f80016a3602b880012005419080016a200541a080016a108a042005418b80016a2005419880016a2802003600002005200529039080013700838001200041053a00042000200529008080013700052000410c6a2005418780016a290000370000200041013602002006450d062003102e0c060b2005200128020020076a200b10f604210a2001200c36020802400240200620086b200b490d00200b20086a21070c010b2008200b6a22072008490d052006410174220c20072007200c491b220c4100480d050240024020060d00200c102921030c010b20032006200c102a21030b2003450d04200c21060b200320086a200a200b10f6041a200721082004200b20096a22094b0d000b0b2000200336020420004100360200200041146a2007360200200041106a41003602002000410c6a2007360200200041086a20063602000c030b2007200c1035000b200c4101102c000b102d000b200241c080016a24000b0e0020003502004101200110b5010bf60201037f230041c0006b22022400200141086a2802002103200128020421042002200128020022013602100240024002402001418080044b0d0002402004450d0020022003360214200120034b0d022003418080044d0d002002413c6a41013602002002420237022c200241e0b1c5003602282002410136021c200241bcb1c5003602182002200241186a3602382002200241286a108a040c030b200241003602000c020b2002413c6a41013602002002420237022c200241c0b1c5003602282002410136021c200241bcb1c5003602182002200241186a3602382002200241286a108a040c010b200241246a41013602002002413c6a41023602002002420237022c200241d0b1c5003602282002410136021c2002200241186a3602382002200241106a3602202002200241146a3602182002200241286a108a040b024002402002280200450d0020002002290300370200200041086a200241086a2802003602000c010b200041003602000b200241c0006a24000bf90501037f230041f0006b2204240002400240024002400240024020012802084102460d00412e10292201450d01200041013a0000200141266a41002900d4b345370000200141206a41002900ceb345370000200141186a41002900c6b345370000200141106a41002900beb345370000200141086a41002900b6b345370000200141002900aeb345370000200041086a42ae808080e005370200200041046a20013602000c050b02400240024002400240200128020022052d0000416e6a2201411e4b0d004100210620010e1f03000000000000000000000000000000000000000000000000000008040102030b412010292201450d05200041013a0000200141186a41002900f4b345370000200141106a41002900ecb345370000200141086a41002900e4b345370000200141002900dcb345370000200041086a42a08080808004370200200041046a20013602000c080b410221060c060b410321060c050b20042005280204220136020c0240024020012003490d0041fcb3c5002105200441e8006a2103200441d0006a2101200441c0006a21020c010b200220014101746a22012d0001450d04418cb4c5002105200441386a2103200441206a2101200441106a21020b20034101360204200141146a410136020020012003360210200142023702042001200536020020032004410c6a36020020022001108a04200041013a00002000410c6a200241086a280200360200200041046a20022902003702000c050b410121060c030b412e4101102c000b41204101102c000b20012d000021060b0240200541106a2d00004106470d00200041003a0000200020063a00010c010b0240412910292201450d00200041013a0000200141286a41002d00c4b4453a0000200141206a41002900bcb445370000200141186a41002900b4b445370000200141106a41002900acb445370000200141086a41002900a4b4453700002001410029009cb445370000200041086a42a98080809005370200200041046a20013602000c010b41294101102c000b200441f0006a24000b8f0201017f230041106b220224000240024002400240024020002d00000e0401020300010b2002200128021841b8d4c50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c030b2002200128021841bbd4c50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c020b2002200128021841bed4c50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c010b2002200128021841c1d4c50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040b200241106a240020000bf5c30103077f027e027f230041f0006b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00000eac0100df010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01000b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810292200450dab012003421837025c20032000360258200341d8006a4100411810a20420032003280260220041186a3602602000200328025822016a411841eab6c500411810a3042003200329025c37025c2003200136025841faabc500413b200341d8006a41b8acc5001053000b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490dde0120044101742209200820082009491b22094100480dde010240024020040d002009102921080c010b200128021820042009102a21080b2008450dad01200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a220210f5041a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060cde010b0240200141306a2802002204200141346a22062802004f0d002002310001210a200141206a350200210b024020042001412c6a280200470d00200441016a22022004490ddd0120044101742206200220022006491b220241ffffffff01712002470ddd01200241037422064100480ddd010240024020040d002006102921040c010b200128022820044103742006102a21040b2004450dad01200120043602282001412c6a2002360200200141306a28020021040b200128022820044103746a200a422886200b84370200200141306a2201200128020041016a3602000cde010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450ddd012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450ddd012000200329023c370204200020013602000cde010b0240200141306a2802002204200141346a22062802004f0d002002310001210a200141206a350200210b024020042001412c6a280200470d00200441016a22022004490ddc0120044101742206200220022006491b220241ffffffff01712002470ddc01200241037422064100480ddc010240024020040d002006102921040c010b200128022820044103742006102a21040b2004450dad01200120043602282001412c6a2002360200200141306a28020021040b200128022820044103746a200a422886200b8442808080803084370200200141306a2201200128020041016a3602000cdd010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450ddc012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450ddc012000200329023c370204200020013602000cdd010b2002310001210a200341d8006a200141186a200141286a2204410010a404024020032d00584101470d002000200329025c370200200041086a200341e4006a2802003602000cdd010b0240200141306a2802002202200141346a22062802004f0d00200141206a350200210b024020022001412c6a280200470d00200241016a22062002490ddb0120024101742205200620062005491b220641ffffffff01712006470ddb01200641037422054100480ddb010240024020020d002005102921020c010b200428020020024103742005102a21020b2002450dad01200120023602282001412c6a2006360200200141306a28020021020b200128022820024103746a200a422886200b8442808080801084370200200141306a2201200128020041016a3602000cdc010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450ddb012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450ddb012000200329023c370204200020013602000cdc010b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810292200450dac012003421837025c20032000360258200341d8006a4100411810a20420032003280260220041186a3602602000200328025822016a411841eab6c500411810a3042003200329025c37025c2003200136025841c8acc5004134200341d8006a41b8acc5001053000b02400240200141286a220228020020044103746a22042d00044101470d002004310005210a200341d8006a200141186a200210a5042003280258450d0120002003290358370200200041086a200341d8006a41086a2802003602000cdd010b411a10292201450dad01200141186a41002f0094ad453b0000200141106a410029008cad45370000200141086a4100290084ad45370000200141002900fcac453700002000429a808080a003370204200020013602000cdc010b0240200141306a2802002204200141346a22062802004f0d00200141206a350200210b024020042001412c6a280200470d00200441016a22062004490dda0120044101742205200620062005491b220641ffffffff01712006470dda01200641037422054100480dda010240024020040d002005102921020c010b200228020020044103742005102a21020b2002450daf01200120023602282001412c6a2006360200200141306a28020021040b200128022820044103746a200a422886200b8442808080802084370200200141306a2201200128020041016a3602000cdb010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450dda012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dda012000200329023c370204200020013602000cdb010b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810292200450dae012003421837025c20032000360258200341d8006a4100411810a20420032003280260220041186a3602602000200328025822016a411841eab6c500411810a3042003200329025c37025c2003200136025841c8acc5004134200341d8006a41b8acc5001053000b200141286a220528020020044103746a22042d00052106024020042d00044101470d00200641ff01714104470daf010b0240024020024101460d00200341d8006a200141186a2202200510a5042003280258450d0120002003290358370200200041086a200341d8006a41086a2802003602000cdc010b20012d003822024104460dd901200341d8006a200141186a22062005200210a4040240024020032d00584101460d000240200141206a2802002204200141246a22082802004f0d00024020042001411c6a280200470d00200441016a22082004490ddc0120044101742207200820082007491b22084100480ddc010240024020040d002008102921040c010b200628020020042008102a21040b2004450db401200120043602182001411c6a2008360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cdc010b200341ec006a220241013602002003420137025c200341e4b7c500360258200341013602042003200836020020032003360268200341106a200341d8006a108a0420032802102204450ddb012003200329021437021420032004360210200241013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382202450ddb01200329023c210a0c010b200328025c2202450dda01200341e0006a290300210a0b2000200a370204200020023602000cdb010b200641ff01714104460dd9010240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490dd90120044101742208200520052008491b22054100480dd9010240024020040d002005102921020c010b200228020020042005102a21020b2002450db201200120023602182001411c6a2005360200200141206a28020021040b200128021820046a20063a0000200141206a2201200128020041016a3602000cda010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200536020020032003360268200341106a200341d8006a108a0420032802102202450dd9012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dd9012000200329023c370204200020013602000cda010b2003200241046a280200220236024802400240200141306a280200220420024d0d0020042002417f736a22022004490d0141c6b7c500411d109b01000b200341ec006a220241023602002003411c6a41013602002003420237025c20034184b7c50036025820034101360214200320043602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a108a04200328023821042003200329023c37021420032004360210200241013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a042003280214450dd1012003280210102e0cd1010b200141286a220428020020024103746a22022d00044103460dd10120022d0005220241ff01714104460dd101200341d8006a200141186a22062004200210a404024020032d00584101460d000240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490dd90120044101742208200520052008491b22054100480dd9010240024020040d002005102921040c010b200628020020042005102a21040b2004450db301200120043602182001411c6a2005360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cd3010b200341ec006a220241013602002003420137025c200341e4b7c500360258200341013602042003200536020020032003360268200341106a200341d8006a108a0420032802102204450dd2012003200329021437021420032004360210200241013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a042003280214450dd1012003280210102e0cd1010b200328025c2202450dd101200341e0006a290300210a0cd2010b200241046a2802002102200341d8006a200141186a2205200141286a2206410010a4040240024020032d00584101470d00200341e0006a290300210a200328025c22010d010cd9010b200141306a28020021042003200236024802400240200420024d0d0020042002417f736a22022004490d0141c6b7c500411d109b01000b200341ec006a220141023602002003411c6a41013602002003420237025c20034184b7c50036025820034101360214200320043602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a108a04200328023821022003200329023c37021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b200329023c210a200328023822010d010cd9010b200628020020024103746a22022d00044103460dd80120022d0005220241ff01714104460dd801200341d8006a20052006200210a404024020032d00584101460d000240200141206a2802002204200141246a22062802004f0d00024020042001411c6a280200470d00200441016a22062004490dd90120044101742208200620062008491b22064100480dd9010240024020040d002006102921040c010b200528020020042006102a21040b2004450db401200120043602182001411c6a2006360200200141206a28020021040b200128021820046a20023a0000200141206a2201200128020041016a3602000cda010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450dd9012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dd901200329023c210a0c010b200328025c2201450dd801200341e0006a290300210a0b2000200a370204200020013602000cd8010b200241086a2802002105200241046a280200210420032002410c6a280200220636024802400240200141306a280200220220064d0d0020022006417f736a22062002490d0141c6b7c500411d109b01000b200341ec006a22044102360200200341106a410c6a41013602002003420237025c20034184b7c50036025820034101360214200320023602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a108a04200328023821022003200329023c37021420032002360210200441013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b2003200329023c370204200320032802383602000ccd010b410421090240200141286a220c280200220820064103746a22062d00044103460d0020062d000521090b200320093a00302005450dc801200941ff0171220d4104460dc701200541027421050340200320042802002206360248200220064d0dca0120022006417f736a220620024f0dce01200820064103746a22062d00044103460dcb0120062d000522074104460dcb01200d2007470dcb01200441046a21042005417c6a22050d000cc9010b0b20012d003822024104460dc501200341d8006a200141186a2206200141286a200210a4040240024020032d00584101460d000240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490dd70120044101742208200520052008491b22054100480dd7010240024020040d002005102921040c010b200628020020042005102a21040b2004450db301200120043602182001411c6a2005360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cc8010b200341ec006a220241013602002003420137025c200341e4b7c500360258200341013602042003200536020020032003360268200341106a200341d8006a108a0420032802102204450dc7012003200329021437021420032004360210200241013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382202450dc701200329023c210a0c010b200328025c2202450dc601200341e0006a290300210a0b2000200a370204200020023602000cd6010b200128020021042003200241046a2802002202360254024002400240200441386a28020020024b0d00200341ec006a41013602002003420237025c200341ccb5c500360258200341013602342003200341306a3602682003200341d4006a360230200341386a200341d8006a108a04200341186a200329023c370300200341013602102003200328023822043602140c010b2003200428023020024102746a2802002202360200024002402004412c6a28020020024b0d0041012106200341ec006a41013602002003420237025c200341dcb5c5003602582003410136024c2003200341c8006a36026820032003360248200341386a200341d8006a108a04200341186a200329023c220a370300200a422088a7210820032802382104200aa721020c010b2003411c6a200428022420024104746a22042d000d22083a0000200341186a2004280208220236020020042802002104410021060b20032006360210200320043602142006450d010b200341186a21010cc3010b02402002450d002004417f6a2104200141286a2106200141186a21050340200341d8006a20052006200420026a2d000010a404024020032d00584101470d00200341e0006a2101200328025c21040cc5010b2002417f6a22020d000b0b200841ff01714104460dd4010240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490dd40120024101742206200420042006491b22044100480dd4010240024020020d002004102921020c010b200128021820022004102a21020b2002450db101200120023602182001411c6a2004360200200141206a28020021020b200128021820026a20083a0000200141206a2201200128020041016a3602000cd5010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200436020020032003360268200341106a200341d8006a108a0420032802102202450dd4012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382204450dd401200329023c210a0cc3010b200241046a28020021052001280200210220034100360238024002400240200241146a2802000d00200341d8006a41146a41013602002003420237025c200341acb5c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a108a040c010b200341d8006a200141186a2204200141286a2206410010a404024020032d00584101470d00200341e0006a290300210a0cc2010b20012802002208412c6a280200210220032005360238200220054b0d01200341ec006a41013602002003420237025c200341dcb5c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a108a040b2003290214210a200328021022010dc1010cd4010b200828022420054104746a22052d000d2108024020052802082202450d002005280200417f6a21050340200341d8006a20042006200520026a2d000010a404024020032d00584101470d00200341e0006a290300210a0cc2010b2002417f6a22020d000b0b200841ff01714104460dd3010240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490dd30120024101742205200620062005491b22064100480dd3010240024020020d002006102921020c010b200428020020022006102a21020b2002450db101200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20083a0000200141206a2201200128020041016a3602000cd4010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450dd3012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dd301200329023c210a0cc0010b200341d8006a200141186a200141286a410410a40420032d00584101470dd201200328025c2201450dd2012000200341e0006a290300370204200020013602000cd3010b200341d8006a200141186a2204200141286a2206410010a404200341d8006a21020240024020032d00584101460d00200341d8006a20042006410410a404200341d8006a210220032d00584101460d00200341d8006a2004200620032d0059220510a404200341d8006a210220032d00584101460d000240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490dd30120024101742208200620062008491b22064100480dd3010240024020020d002006102921020c010b200428020020022006102a21020b2002450db201200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20053a0000200141206a2201200128020041016a3602000cd4010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450dd3012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dd301200329023c210a0c010b200241046a2802002201450dd201200241086a290200210a0b2000200a370204200020013602000cd2010b200341d8006a200141046a200241046a28020010a6040240024020032d00584101460d000240200141206a2802002202200141246a22042802004f0d0020032d00592104024020022001411c6a280200470d00200241016a22062002490dd20120024101742205200620062005491b22064100480dd2010240024020020d002006102921020c010b200128021820022006102a21020b2002450db201200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20043a0000200141206a2201200128020041016a3602000cd3010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200436020020032003360268200341106a200341d8006a108a0420032802102202450dd2012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dd201200329023c210a0c010b200328025c2201450dd101200341e0006a290300210a0b2000200a370204200020013602000cd1010b2003200241046a2802002202360200200341d8006a200141046a200210a604024020032d00584101470d002003200328025c22013602382003200341e0006a290300220a37023c0cbb010b200320032d005922023a0030200341d8006a200141186a200141286a410410a404024020032d00584101470d00200341c0006a200341e4006a2802003602002003200329025c3703380cba010b200320032d005922013a004820014104460dcf01200241ff01712001460dcf01200341106a41146a41273602002003411c6a4122360200200341d8006a41146a41033602002003420337025c200341b8adc500360258200341013602142003200341106a3602682003200341c8006a3602202003200341306a36021820032003360210200341386a200341d8006a108a040cb9010b200341d8006a200141046a200241046a28020010a6040240024020032d00584101460d00200341d8006a200141186a2206200141286a20032d0059220410a404024020032d00584101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490dd10120024101742208200520052008491b22054100480dd1010240024020020d002005102921020c010b200628020020022005102a21020b2002450db201200120023602182001411c6a2005360200200141206a28020021020b200128021820026a20043a0000200141206a2201200128020041016a3602000cd2010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200536020020032003360268200341106a200341d8006a108a0420032802102202450dd1012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dd101200329023c210a0c020b200328025c2201450dd001200341e0006a290300210a0c010b200328025c2201450dcf01200341e0006a290300210a0b2000200a370204200020013602000ccf010b200128020021042003200241046a280200220236023802400240200441206a28020020024d0d000240200141206a2802002206200141246a22052802004f0d00200428021820024101746a2d00002102024020062001411c6a280200470d00200641016a22042006490dcf0120064101742205200420042005491b22044100480dcf010240024020060d002004102921060c010b200128021820062004102a21060b2006450db101200120063602182001411c6a2004360200200141206a28020021060b200128021820066a20023a0000200141206a2201200128020041016a3602000cd0010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200536020020032003360268200341106a200341d8006a108a0420032802102202450dcf012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dcf01200329023c210a0c010b200341ec006a41013602002003420237025c200341fcb5c5003602582003410136024c2003200341c8006a3602682003200341386a360248200341106a200341d8006a108a0420032802102201450dce012003290214210a0b2000200a370204200020013602000cce010b2003200241046a28020022023602282001280200210420032002360254024002400240200441206a28020020024b0d00200341ec006a41013602002003420237025c200341fcb5c5003602582003410136024c2003200341c8006a3602682003200341d4006a360248200341106a200341d8006a108a040c010b200428021820024101746a22022d00010d01200341ec006a41013602002003420237025c2003418cb6c50036025820034101360204200320033602682003200341d4006a360200200341106a200341d8006a108a040b2003280210210120032003290214220a37023c200320013602380cb6010b200320022d000022023a002f200341d8006a200141186a200141286a410410a404024020032d00584101470d00200341c0006a200341e4006a2802003602002003200329025c3703380cb5010b200320032d005922013a00002001200241ff0171460dcc0120014104460dcc01200341106a41146a41273602002003411c6a4127360200200341d8006a41146a41033602002003420337025c200341d0adc500360258200341013602142003200341106a3602682003200336022020032003412f6a3602182003200341286a360210200341386a200341d8006a108a040cb4010b200341d8006a2001200241046a2802004104410010a8042003280258450dcb0120002003290358370200200041086a200341d8006a41086a2802003602000ccc010b200341d8006a2001200241046a2802004108410110a8042003280258450dca0120002003290358370200200041086a200341d8006a41086a2802003602000ccb010b200341d8006a2001200241046a2802004104410210a8042003280258450dc90120002003290358370200200041086a200341d8006a41086a2802003602000cca010b200341d8006a2001200241046a2802004108410310a8042003280258450dc80120002003290358370200200041086a200341d8006a41086a2802003602000cc9010b200341d8006a2001200241046a2802004101410010a8042003280258450dc70120002003290358370200200041086a200341d8006a41086a2802003602000cc8010b200341d8006a2001200241046a2802004101410010a8042003280258450dc60120002003290358370200200041086a200341d8006a41086a2802003602000cc7010b200341d8006a2001200241046a2802004102410010a8042003280258450dc50120002003290358370200200041086a200341d8006a41086a2802003602000cc6010b200341d8006a2001200241046a2802004102410010a8042003280258450dc40120002003290358370200200041086a200341d8006a41086a2802003602000cc5010b200341d8006a2001200241046a2802004101410110a8042003280258450dc30120002003290358370200200041086a200341d8006a41086a2802003602000cc4010b200341d8006a2001200241046a2802004101410110a8042003280258450dc20120002003290358370200200041086a200341d8006a41086a2802003602000cc3010b200341d8006a2001200241046a2802004102410110a8042003280258450dc10120002003290358370200200041086a200341d8006a41086a2802003602000cc2010b200341d8006a2001200241046a2802004102410110a8042003280258450dc00120002003290358370200200041086a200341d8006a41086a2802003602000cc1010b200341d8006a2001200241046a2802004104410110a8042003280258450dbf0120002003290358370200200041086a200341d8006a41086a2802003602000cc0010b200341d8006a2001200241046a2802004104410110a8042003280258450dbe0120002003290358370200200041086a200341d8006a41086a2802003602000cbf010b200341d8006a2001200241046a2802004104410010a9042003280258450dbd0120002003290358370200200041086a200341d8006a41086a2802003602000cbe010b200341d8006a2001200241046a2802004108410110a9042003280258450dbc0120002003290358370200200041086a200341d8006a41086a2802003602000cbd010b200341d8006a2001200241046a2802004104410210a9042003280258450dbb0120002003290358370200200041086a200341d8006a41086a2802003602000cbc010b200341d8006a2001200241046a2802004108410310a9042003280258450dba0120002003290358370200200041086a200341d8006a41086a2802003602000cbb010b200341d8006a2001200241046a2802004101410010a9042003280258450db90120002003290358370200200041086a200341d8006a41086a2802003602000cba010b200341d8006a2001200241046a2802004102410010a9042003280258450db80120002003290358370200200041086a200341d8006a41086a2802003602000cb9010b200341d8006a2001200241046a2802004101410110a9042003280258450db70120002003290358370200200041086a200341d8006a41086a2802003602000cb8010b200341d8006a2001200241046a2802004102410110a9042003280258450db60120002003290358370200200041086a200341d8006a41086a2802003602000cb7010b200341d8006a2001200241046a2802004104410110a9042003280258450db50120002003290358370200200041086a200341d8006a41086a2802003602000cb6010b20012802002102200341003602380240024020022802080d00200341ec006a41013602002003420237025c200341fcb4c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a108a0420032802102202450d002003290214210a0c010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db50120024101742206200420042006491b22044100480db5010240024020020d002004102921020c010b200128021820022004102a21020b2002450d9801200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb6010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200436020020032003360268200341106a200341d8006a108a0420032802102202450db5012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382202450db501200329023c210a0b2000200a370204200020023602000cb5010b20012802002102200341003602380240024020022802080d00200341ec006a41013602002003420237025c200341fcb4c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a108a0420032802102202450d002003290214210a0c010b200341d8006a200141186a2204200141286a410010a404024020032d00584101460d000240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490db50120024101742205200620062005491b22064100480db5010240024020020d002006102921020c010b200428020020022006102a21020b2002450d9901200120023602182001411c6a2006360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb6010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450db5012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382202450db501200329023c210a0c010b200328025c2202450db401200341e0006a290300210a0b2000200a370204200020023602000cb4010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db20120024101742206200420042006491b22044100480db2010240024020020d002004102921020c010b200128021820022004102a21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb3010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200436020020032003360268200341106a200341d8006a108a0420032802102202450db2012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450db2012000200329023c370204200020013602000cb3010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db10120024101742206200420042006491b22044100480db1010240024020020d002004102921020c010b200128021820022004102a21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000cb2010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200436020020032003360268200341106a200341d8006a108a0420032802102202450db1012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450db1012000200329023c370204200020013602000cb2010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db00120024101742206200420042006491b22044100480db0010240024020020d002004102921020c010b200128021820022004102a21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000cb1010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200436020020032003360268200341106a200341d8006a108a0420032802102202450db0012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450db0012000200329023c370204200020013602000cb1010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490daf0120024101742206200420042006491b22044100480daf010240024020020d002004102921020c010b200128021820022004102a21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000cb0010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200436020020032003360268200341106a200341d8006a108a0420032802102202450daf012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450daf012000200329023c370204200020013602000cb0010b200341d8006a2001410010aa042003280258450dae0120002003290358370200200041086a200341d8006a41086a2802003602000caf010b200341d8006a2001410010ab042003280258450dad0120002003290358370200200041086a200341d8006a41086a2802003602000cae010b200341d8006a2001410010ab042003280258450dac0120002003290358370200200041086a200341d8006a41086a2802003602000cad010b200341d8006a2001410010ab042003280258450dab0120002003290358370200200041086a200341d8006a41086a2802003602000cac010b200341d8006a2001410010ab042003280258450daa0120002003290358370200200041086a200341d8006a41086a2802003602000cab010b200341d8006a2001410010ab042003280258450da90120002003290358370200200041086a200341d8006a41086a2802003602000caa010b200341d8006a2001410010ab042003280258450da80120002003290358370200200041086a200341d8006a41086a2802003602000ca9010b200341d8006a2001410010ab042003280258450da70120002003290358370200200041086a200341d8006a41086a2802003602000ca8010b200341d8006a2001410010ab042003280258450da60120002003290358370200200041086a200341d8006a41086a2802003602000ca7010b200341d8006a2001410010ab042003280258450da50120002003290358370200200041086a200341d8006a41086a2802003602000ca6010b200341d8006a2001410010ab042003280258450da40120002003290358370200200041086a200341d8006a41086a2802003602000ca5010b200341d8006a2001410110aa042003280258450da30120002003290358370200200041086a200341d8006a41086a2802003602000ca4010b200341d8006a2001410110ab042003280258450da20120002003290358370200200041086a200341d8006a41086a2802003602000ca3010b200341d8006a2001410110ab042003280258450da10120002003290358370200200041086a200341d8006a41086a2802003602000ca2010b200341d8006a2001410110ab042003280258450da00120002003290358370200200041086a200341d8006a41086a2802003602000ca1010b200341d8006a2001410110ab042003280258450d9f0120002003290358370200200041086a200341d8006a41086a2802003602000ca0010b200341d8006a2001410110ab042003280258450d9e0120002003290358370200200041086a200341d8006a41086a2802003602000c9f010b200341d8006a2001410110ab042003280258450d9d0120002003290358370200200041086a200341d8006a41086a2802003602000c9e010b200341d8006a2001410110ab042003280258450d9c0120002003290358370200200041086a200341d8006a41086a2802003602000c9d010b200341d8006a2001410110ab042003280258450d9b0120002003290358370200200041086a200341d8006a41086a2802003602000c9c010b200341d8006a2001410110ab042003280258450d9a0120002003290358370200200041086a200341d8006a41086a2802003602000c9b010b200341d8006a2001410110ab042003280258450d990120002003290358370200200041086a200341d8006a41086a2802003602000c9a010b200341d8006a2001410210ab042003280258450d980120002003290358370200200041086a200341d8006a41086a2802003602000c99010b200341d8006a2001410210ab042003280258450d970120002003290358370200200041086a200341d8006a41086a2802003602000c98010b200341d8006a2001410210ab042003280258450d960120002003290358370200200041086a200341d8006a41086a2802003602000c97010b200341d8006a2001410210ab042003280258450d950120002003290358370200200041086a200341d8006a41086a2802003602000c96010b200341d8006a2001410210ab042003280258450d940120002003290358370200200041086a200341d8006a41086a2802003602000c95010b200341d8006a2001410210ab042003280258450d930120002003290358370200200041086a200341d8006a41086a2802003602000c94010b200341d8006a2001410310ab042003280258450d920120002003290358370200200041086a200341d8006a41086a2802003602000c93010b200341d8006a2001410310ab042003280258450d910120002003290358370200200041086a200341d8006a41086a2802003602000c92010b200341d8006a2001410310ab042003280258450d900120002003290358370200200041086a200341d8006a41086a2802003602000c91010b200341d8006a2001410310ab042003280258450d8f0120002003290358370200200041086a200341d8006a41086a2802003602000c90010b200341d8006a2001410310ab042003280258450d8e0120002003290358370200200041086a200341d8006a41086a2802003602000c8f010b200341d8006a2001410310ab042003280258450d8d0120002003290358370200200041086a200341d8006a41086a2802003602000c8e010b200341d8006a2001410010ac042003280258450d8c0120002003290358370200200041086a200341d8006a41086a2802003602000c8d010b200341d8006a2001410010ac042003280258450d8b0120002003290358370200200041086a200341d8006a41086a2802003602000c8c010b200341d8006a2001410010ac042003280258450d8a0120002003290358370200200041086a200341d8006a41086a2802003602000c8b010b200341d8006a2001410010ad042003280258450d890120002003290358370200200041086a200341d8006a41086a2802003602000c8a010b200341d8006a2001410010ad042003280258450d880120002003290358370200200041086a200341d8006a41086a2802003602000c89010b200341d8006a2001410010ad042003280258450d870120002003290358370200200041086a200341d8006a41086a2802003602000c88010b200341d8006a2001410010ad042003280258450d860120002003290358370200200041086a200341d8006a41086a2802003602000c87010b200341d8006a2001410010ad042003280258450d850120002003290358370200200041086a200341d8006a41086a2802003602000c86010b200341d8006a2001410010ad042003280258450d840120002003290358370200200041086a200341d8006a41086a2802003602000c85010b200341d8006a2001410010ad042003280258450d830120002003290358370200200041086a200341d8006a41086a2802003602000c84010b200341d8006a2001410010ad042003280258450d820120002003290358370200200041086a200341d8006a41086a2802003602000c83010b200341d8006a2001410010ad042003280258450d810120002003290358370200200041086a200341d8006a41086a2802003602000c82010b200341d8006a2001410010ad042003280258450d800120002003290358370200200041086a200341d8006a41086a2802003602000c81010b200341d8006a2001410010ad042003280258450d7f20002003290358370200200041086a200341d8006a41086a2802003602000c80010b200341d8006a2001410010ad042003280258450d7e20002003290358370200200041086a200341d8006a41086a2802003602000c7f0b200341d8006a2001410010ad042003280258450d7d20002003290358370200200041086a200341d8006a41086a2802003602000c7e0b200341d8006a2001410010ad042003280258450d7c20002003290358370200200041086a200341d8006a41086a2802003602000c7d0b200341d8006a2001410010ad042003280258450d7b20002003290358370200200041086a200341d8006a41086a2802003602000c7c0b200341d8006a2001410110ac042003280258450d7a20002003290358370200200041086a200341d8006a41086a2802003602000c7b0b200341d8006a2001410110ac042003280258450d7920002003290358370200200041086a200341d8006a41086a2802003602000c7a0b200341d8006a2001410110ac042003280258450d7820002003290358370200200041086a200341d8006a41086a2802003602000c790b200341d8006a2001410110ad042003280258450d7720002003290358370200200041086a200341d8006a41086a2802003602000c780b200341d8006a2001410110ad042003280258450d7620002003290358370200200041086a200341d8006a41086a2802003602000c770b200341d8006a2001410110ad042003280258450d7520002003290358370200200041086a200341d8006a41086a2802003602000c760b200341d8006a2001410110ad042003280258450d7420002003290358370200200041086a200341d8006a41086a2802003602000c750b200341d8006a2001410110ad042003280258450d7320002003290358370200200041086a200341d8006a41086a2802003602000c740b200341d8006a2001410110ad042003280258450d7220002003290358370200200041086a200341d8006a41086a2802003602000c730b200341d8006a2001410110ad042003280258450d7120002003290358370200200041086a200341d8006a41086a2802003602000c720b200341d8006a2001410110ad042003280258450d7020002003290358370200200041086a200341d8006a41086a2802003602000c710b200341d8006a2001410110ad042003280258450d6f20002003290358370200200041086a200341d8006a41086a2802003602000c700b200341d8006a2001410110ad042003280258450d6e20002003290358370200200041086a200341d8006a41086a2802003602000c6f0b200341d8006a2001410110ad042003280258450d6d20002003290358370200200041086a200341d8006a41086a2802003602000c6e0b200341d8006a2001410110ad042003280258450d6c20002003290358370200200041086a200341d8006a41086a2802003602000c6d0b200341d8006a2001410110ad042003280258450d6b20002003290358370200200041086a200341d8006a41086a2802003602000c6c0b200341d8006a2001410110ad042003280258450d6a20002003290358370200200041086a200341d8006a41086a2802003602000c6b0b200341d8006a2001410110ad042003280258450d6920002003290358370200200041086a200341d8006a41086a2802003602000c6a0b200341d8006a2001410210ac042003280258450d6820002003290358370200200041086a200341d8006a41086a2802003602000c690b200341d8006a2001410210ac042003280258450d6720002003290358370200200041086a200341d8006a41086a2802003602000c680b200341d8006a2001410210ac042003280258450d6620002003290358370200200041086a200341d8006a41086a2802003602000c670b200341d8006a2001410210ac042003280258450d6520002003290358370200200041086a200341d8006a41086a2802003602000c660b200341d8006a2001410210ac042003280258450d6420002003290358370200200041086a200341d8006a41086a2802003602000c650b200341d8006a2001410210ac042003280258450d6320002003290358370200200041086a200341d8006a41086a2802003602000c640b200341d8006a2001410210ac042003280258450d6220002003290358370200200041086a200341d8006a41086a2802003602000c630b200341d8006a2001410210ad042003280258450d6120002003290358370200200041086a200341d8006a41086a2802003602000c620b200341d8006a2001410210ad042003280258450d6020002003290358370200200041086a200341d8006a41086a2802003602000c610b200341d8006a2001410210ad042003280258450d5f20002003290358370200200041086a200341d8006a41086a2802003602000c600b200341d8006a2001410210ad042003280258450d5e20002003290358370200200041086a200341d8006a41086a2802003602000c5f0b200341d8006a2001410210ad042003280258450d5d20002003290358370200200041086a200341d8006a41086a2802003602000c5e0b200341d8006a2001410210ad042003280258450d5c20002003290358370200200041086a200341d8006a41086a2802003602000c5d0b200341d8006a2001410210ad042003280258450d5b20002003290358370200200041086a200341d8006a41086a2802003602000c5c0b200341d8006a2001410310ac042003280258450d5a20002003290358370200200041086a200341d8006a41086a2802003602000c5b0b200341d8006a2001410310ac042003280258450d5920002003290358370200200041086a200341d8006a41086a2802003602000c5a0b200341d8006a2001410310ac042003280258450d5820002003290358370200200041086a200341d8006a41086a2802003602000c590b200341d8006a2001410310ac042003280258450d5720002003290358370200200041086a200341d8006a41086a2802003602000c580b200341d8006a2001410310ac042003280258450d5620002003290358370200200041086a200341d8006a41086a2802003602000c570b200341d8006a2001410310ac042003280258450d5520002003290358370200200041086a200341d8006a41086a2802003602000c560b200341d8006a2001410310ac042003280258450d5420002003290358370200200041086a200341d8006a41086a2802003602000c550b200341d8006a2001410310ad042003280258450d5320002003290358370200200041086a200341d8006a41086a2802003602000c540b200341d8006a2001410310ad042003280258450d5220002003290358370200200041086a200341d8006a41086a2802003602000c530b200341d8006a2001410310ad042003280258450d5120002003290358370200200041086a200341d8006a41086a2802003602000c520b200341d8006a2001410310ad042003280258450d5020002003290358370200200041086a200341d8006a41086a2802003602000c510b200341d8006a2001410310ad042003280258450d4f20002003290358370200200041086a200341d8006a41086a2802003602000c500b200341d8006a2001410310ad042003280258450d4e20002003290358370200200041086a200341d8006a41086a2802003602000c4f0b200341d8006a2001410310ad042003280258450d4d20002003290358370200200041086a200341d8006a41086a2802003602000c4e0b200341d8006a20014101410010ae042003280258450d4c20002003290358370200200041086a200341d8006a41086a2802003602000c4d0b200341d8006a20014102410010ae042003280258450d4b20002003290358370200200041086a200341d8006a41086a2802003602000c4c0b200341d8006a20014102410010ae042003280258450d4a20002003290358370200200041086a200341d8006a41086a2802003602000c4b0b200341d8006a20014103410010ae042003280258450d4920002003290358370200200041086a200341d8006a41086a2802003602000c4a0b200341d8006a20014103410010ae042003280258450d4820002003290358370200200041086a200341d8006a41086a2802003602000c490b200341d8006a20014100410110ae042003280258450d4720002003290358370200200041086a200341d8006a41086a2802003602000c480b200341d8006a20014100410110ae042003280258450d4620002003290358370200200041086a200341d8006a41086a2802003602000c470b200341d8006a20014102410110ae042003280258450d4520002003290358370200200041086a200341d8006a41086a2802003602000c460b200341d8006a20014102410110ae042003280258450d4420002003290358370200200041086a200341d8006a41086a2802003602000c450b200341d8006a20014103410110ae042003280258450d4320002003290358370200200041086a200341d8006a41086a2802003602000c440b200341d8006a20014103410110ae042003280258450d4220002003290358370200200041086a200341d8006a41086a2802003602000c430b200341d8006a20014100410210ae042003280258450d4120002003290358370200200041086a200341d8006a41086a2802003602000c420b200341d8006a20014100410210ae042003280258450d4020002003290358370200200041086a200341d8006a41086a2802003602000c410b200341d8006a20014101410210ae042003280258450d3f20002003290358370200200041086a200341d8006a41086a2802003602000c400b200341d8006a20014101410210ae042003280258450d3e20002003290358370200200041086a200341d8006a41086a2802003602000c3f0b200341d8006a20014103410210ae042003280258450d3d20002003290358370200200041086a200341d8006a41086a2802003602000c3e0b200341d8006a20014100410310ae042003280258450d3c20002003290358370200200041086a200341d8006a41086a2802003602000c3d0b200341d8006a20014100410310ae042003280258450d3b20002003290358370200200041086a200341d8006a41086a2802003602000c3c0b200341d8006a20014101410310ae042003280258450d3a20002003290358370200200041086a200341d8006a41086a2802003602000c3b0b200341d8006a20014101410310ae042003280258450d3920002003290358370200200041086a200341d8006a41086a2802003602000c3a0b200341d8006a20014102410310ae042003280258450d3820002003290358370200200041086a200341d8006a41086a2802003602000c390b200341d8006a20014102410010ae042003280258450d3720002003290358370200200041086a200341d8006a41086a2802003602000c380b200341d8006a20014103410110ae042003280258450d3620002003290358370200200041086a200341d8006a41086a2802003602000c370b200341d8006a20014100410210ae042003280258450d3520002003290358370200200041086a200341d8006a41086a2802003602000c360b200341d8006a20014101410310ae0420032802580d1b0c340b41184101102c000b20094101102c000b20064104102c000b20064104102c000b20054104102c000b41184101102c000b411a4101102c000b20054104102c000b41184101102c000b200341ec006a41013602002003420237025c20034198adc5003602582003412836023c2003200441056a3602382003200341386a360268200341106a200341d8006a108a04200041086a200341106a41086a280200360200200020032903103702000c2b0b20084101102c000b20054101102c000b20054101102c000b20064101102c000b20054101102c000b20044101102c000b20064101102c000b20064101102c000b20064101102c000b20054101102c000b20044101102c000b20044101102c000b20064101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20002003290358370200200041086a200341d8006a41086a2802003602000c190b200329023c210a200328023821010b2001450d162000200a370204200020013602000c170b200329023c210a200328023821010b2001450d142000200a370204200020013602000c150b200328025c2201450d130b2000200a370204200020013602000c130b2004450d112001290200210a0b2000200a370204200020043602000c110b0240024002400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810292200450d012003421837025c20032000360258200341d8006a4100411810a20420032003280260220041186a3602602000200328025822016a411841eab6c500411810a3042003200329025c37025c2003200136025841faabc500413b200341d8006a41b8acc5001053000b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490d1120044101742209200820082009491b22094100480d110240024020040d002009102921080c010b200128021820042009102a21080b2008450d03200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a220210f5041a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060c110b41184101102c000b20094101102c000b200541027421050340200320042802002206360248200220064d0d0220022006417f736a220620024f0d060240200820064103746a22062d00044103460d0020062d00054104470d040b200441046a21042005417c6a22050d000b410421090b200341d8006a200141186a2202200c410010a40420032d00584101470d02200341086a200341e4006a2802003602002003200329025c3703000c030b200341ec006a220441023602002003411c6a41013602002003420237025c20034184b7c50036025820034101360214200320023602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a108a04200328023821022003200329023c37021420032002360210200441013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b2003200329023c370204200320032802383602000c020b2003411c6a4128360200200341ec006a41023602002003420237025c200341a8adc5003602582003200641056a360218200341283602142003200341106a3602682003200341306a3602102003200341d8006a108a040c010b0240200941ff01714104460d00200341d8006a2002200c200910a40402400240024020032d00584101460d000240200141206a2802002204200141246a22062802004f0d00024020042001411c6a280200470d00200441016a22062004490d0e20044101742205200620062005491b22064100480d0e0240024020040d002006102921020c010b200228020020042006102a21020b2002450d04200120023602182001411c6a2006360200200141206a28020021040b200128021820046a20093a0000200141206a2202200228020041016a3602000c040b200341ec006a220241013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102204450d032003200329021437021420032004360210200241013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382202450d03200329023c210a0c010b200328025c2202450d02200341e0006a290300210a0b2003200a370204200320023602000c020b20064101102c000b200341003602000b024020032802002202450d0020002003290204370204200020023602000c0b0b0240024002400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810292200450d012003421837025c20032000360258200341d8006a4100411810a20420032003280260220041186a3602602000200328025822016a411841eab6c500411810a3042003200329025c37025c2003200136025841faabc500413b200341d8006a41b8acc5001053000b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490d0b20044101742209200820082009491b22094100480d0b0240024020040d002009102921080c010b200128021820042009102a21080b2008450d03200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a220210f5041a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060c0b0b41184101102c000b20094101102c000b41c6b7c500411d109b01000b20032802382202450d00200329023c210a0c010b0240200141306a2802002202417f6a220420024f0d00200420024d0d020b411810292200450d022003421837025c20032000360258200341d8006a4100411810a20420032003280260220041186a3602602000200328025822016a411841eab6c500411810a3042003200329025c37025c2003200136025841faabc500413b200341d8006a41b8acc5001053000b2000200a370204200020023602000c060b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490d0420044101742209200820082009491b22094100480d040240024020040d002009102921080c010b200128021820042009102a21080b2008450d03200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a220210f5041a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060c040b41184101102c000b20094101102c000b102d000b200341d8006a200141186a200510a5042003280258450d0020002003290358370200200041086a200341d8006a41086a2802003602000c010b200041003602000b200341f0006a24000b6501017f230041206b2202240020024129360204200220003602002001411c6a2802002100200128021821012002411c6a41013602002002420137020c200241e897c6003602082002200236021820012000200241086a10b5042101200241206a240020010b0c002000280200200110b7040bcd0201067f02400240024002402001450d0020014108490d010240200141ffffffff01712001470d00200141037441076e21010c030b41e8aac5001058000b200041106a4200370200200041086a4280808080c000370200200041046a4180abc5003602000c020b200141016a21010b02400240417f2001417f6a6776220141016a220241ffffffff01712002470d00200141086a417c712203200141056a2204490d00200320024103746a22052003490d002005417d4f0d00200510292206450d012001200241037641076c20014108491b2107200641ff01200410f504220520036a21030240200241034b0d00200520026a418001410320016b10f5041a0b200041146a2007360200200041106a41003602002000410c6a2003360200200041086a2001360200200041046a20053602000c020b41e8aac5001058000b20054104102c000b200041003a00000b9d0d02107f017e230041206b220124000240024002400240200028020c220241016a22032002490d00200041046a28020022022104024020024108490d00200241016a41037641076c21040b024020032004410176490d00200141086a2003109f0420012d00084101460d042001411c6a2802002105200141146a2802002106200141106a2802002107200128020c210820002802002209280200417f7341808182847871210a200041046a28020020096a41016a210b2000280208210c200028020c210d03400240024002400240200a0d00200941046a210203402002200b4f0d02200c41206a210c20022802002103200241046a220421022003418081828478712203418081828478460d000b200341808182847873210a2004417c6a21090b200c200a684138716a220e280200210f410021030240200e41046a28020022104104490d0041002103200f2102201021040340200228000020034105777341b9f3ddf1796c2103200241046a21022004417c6a220441034b0d000b2010417c6a22022002417c7122026b21102002200f6a41046a210f0b201041014b0d01200f21040c020b2000200d36020c2000200636020820002005200d6b3602102000280200210420002008360200200041046a22032802002102200320073602002002450d070240200241016a220341ffffffff01712003470d00200241086a417c712208200241056a490d00200820034103746a2008491a0b2004102e0c070b200f41026a21042010417e6a21102003410577200f2f00007341b9f3ddf1796c21030b200a417f6a210202402010450d00200341057720042d00007341b9f3ddf1796c21030b2002200a71210a41002102200341057741ff017341b9f3ddf1796c220f21030340200241046a2202200320077122046a2103200820046a280000418081828478712210450d000b0240200820106841037620046a20077122026a2c00004100480d002008280200418081828478716841037621020b200820026a200f41197622033a00002002417c6a20077120086a41046a20033a0000200620024103746a200e2902003702000c000b0b200241016a21044100210341002102024003400240024020034101710d00200220044f0d0320022103200241016a21020c010b200241036a220320024922080d0220032004492207450d022004200241046a20081b200420071b21020b200028020020036a220320032802002203410776417f73418182840871200341fffefdfb07726a360200410121030c000b0b20002802002102200041046a220428020041016a220341044f0d01200241046a2002200310f7041a2004280200220220002802006a41016a418001410320026b10f5041a0c020b41e8aac5001058000b200220036a20022800003600000b417f210202400240200041046a2206280200220341016a220f2003490d00200041086a21094100210b0340200b220c41016a210b0240200c20002802006a2d0000418001470d00024003402009280200200c4103746a220e2802002107410021030240200e41046a28020022084104490d004100210320072102200821040340200228000020034105777341b9f3ddf1796c2103200241046a21022004417c6a220441034b0d000b2008417c6a22022002417c7122026b2108200220076a41046a21070b02400240200841014b0d00200721020c010b200741026a21022008417e6a2108200341057720072f00007341b9f3ddf1796c21030b02402008450d00200341057720022d00007341b9f3ddf1796c21030b200628020021082000280200210741002102200341057741ff017341b9f3ddf1796c220a21030340200241046a2202200320087122046a2103200720046a280000418081828478712210450d000b0240200720106841037620046a20087122026a2c00004100480d002007280200418081828478716841037621020b2002200a20087122036b200c20036b732008714104490d01200720026a22032d000021042003200a41197622103a00002002417c6a20087120076a41046a20103a00000240200441ff01460d00200928020020024103746a220229020021112002200e290200370200200e20113702000c010b0b20002802002203200c6a41ff013a000020032006280200200c417c6a716a41046a41ff013a0000200928020020024103746a200e2902003702000c010b2007200c6a200a41197622023a00002008200c417c6a7120076a41046a20023a00000b200b200f470d000b200041046a28020022024108490d010b200241016a41037641076c21020b20002002200028020c6b3602100b200141206a24000b19002000200141186a280200360204200020012802103602000b810101017f024002400240200041046a280200220320016b20024f0d00200120026a22022001490d0220034101742201200220022001491b22014100480d020240024020030d002001102921020c010b200028020020032001102a21020b2002450d0120002002360200200041046a20013602000b0f0b20014101102c000b102d000bea0101017f230041e0006b22042400200420013602082004200336020c024020012003470d0020002002200110f6041a200441e0006a24000f0b200441286a41146a411d360200200441346a4120360200200441106a41146a41033602002004200441086a36024020042004410c6a360244200441c8006a41146a4100360200200442033702142004419ce7c5003602102004412036022c200441c8ecc5003602582004420137024c200441f0e7c5003602482004200441286a3602202004200441c8006a3602382004200441c4006a3602302004200441c0006a360228200441106a41ace8c500106a000bbb0601037f230041d0006b22042400200420033a000f0240024002400240024020022802082205417f6a220620054f0d00200620054d0d010b411810292202450d012004421837023420042002360230200441306a4100411810a20420042004280238220241186a3602382002200428023022056a411841eab6c500411810a304200420042902343702342004200536023041c8acc5004134200441306a41b8acc5001053000b200141086a2802002105200228020020064103746a2206280200210202400240024020062d0006450d0020052002460d010b024002400240200520024d0d00200141086a2005417f6a2202360200200128020020026a2d00002205417c6a220241014b0d02024020020e020400040b4118102922020d0141184101102c000b412b10292202450d05200041013a0000200241276a41002800e6b045360000200241206a41002900dfb045370000200241186a41002900d7b045370000200241106a41002900cfb045370000200241086a41002900c7b045370000200241002900bfb045370000200041086a42ab808080b005370200200041046a20023602000c060b200241106a41002900fab645370000200241086a41002900f2b645370000200241002900eab64537000020044298808080800337022420042002360220200441c4006a410136020020044201370234200441acb1c5003602302004412336024c2004200441c8006a3602402004200441206a360248200441106a200441306a108a0402402004280224450d002004280220102e0b200041013a0000200041046a20042903103702002000410c6a200441106a41086a2802003602000c050b0240200341ff017122024104460d0020052002470d020b200041003a0000200020053a00010c040b20004180083b01000c030b200420053a0048200441c4006a4102360200200441206a410c6a412736020020044202370234200441ecb0c500360230200441273602242004200441206a3602402004200441c8006a36022820042004410f6a360220200441106a200441306a108a042000410c6a200441186a280200360200200041046a2004290310370200200041013a00000c020b41184101102c000b412b4101102c000b200441d0006a24000bc00502047f017e230041d0006b22032400024002400240024002400240200241086a2802002204417f6a220520044f0d00200520044d0d010b411810292202450d01200241106a41002900fab645370000200241086a41002900f2b645370000200241002900eab64537000020034298808080800337022420032002360220200341cc006a41013602002003420137023c200341acb1c500360238200341233602142003200341106a3602482003200341206a3602102000200341386a108a042003280224450d042003280220102e0c040b0240024002402002280200220620054103746a2d000522054104460d00200341386a20012002200510a404024020032d00384101470d002000200329023c370200200041086a200341c4006a2802003602000c070b200241086a2802002204450d01200228020021060b200241086a2004417f6a2202360200200620024103746a290200220742808080808080c0ff0083428080808080808001520d010b411810292202450d02200241106a41002900fab645370000200241086a41002900f2b645370000200241002900eab64537000020034298808080800337022420032002360220200341cc006a41013602002003420137023c200341acb1c500360238200341233602142003200341106a3602482003200341206a3602102000200341386a108a042003280224450d042003280220102e0c040b200141086a28020021022003200737030820022007a7470d02200041003602000c030b41184101102c000b41184101102c000b200341cc006a41023602002003412c6a41013602002003420237023c2003418cb0c50036023820034101360224200320023602342003200341206a3602482003200341086a3602282003200341346a360220200341106a200341386a108a04200041086a200341106a41086a280200360200200020032903103702000b200341d0006a24000bad0301057f230041c0006b2203240020032002360200024002402001280204220420024b0d002001280208417c6a21052001410c6a280200410374210102400340024020010d00200320043602042003412c6a4102360200200341306a410c6a41013602002003420337021c200341b4b8c500360218200341013602342003200341306a3602282003200341046a36023820032003360230200341086a200341186a108a042000410c6a200341106a280200360200200041046a2003290308370200200041013a00000c040b02402004200541046a2802006a220620044f0d00412010292204450d02200041013a0000200441186a41002900acb845370000200441106a41002900a4b845370000200441086a410029009cb84537000020044100290094b845370000200041086a42a08080808004370200200041046a20043602000c040b200141786a2101200541086a2105200420024b21072006210420070d0020062104200620024d0d000b20052d00002104200041003a0000200020043a00010c020b41204101102c000b200041003a00002000200128020020026a2d00003a00010b200341c0006a24000bbe0201037f230041106b220224000240024020002d00004104470d002002200128021841e8aec50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c010b2002200128021841ebaec50041082001411c6a28020028020c1104003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41f4aec50010b004210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d00410121002004280218418499c60041012004411c6a28020028020c1104000d010b2001280200220028021841bb98c60041012000411c6a28020028020c11040021000b200120003a00080b200241106a2400200041ff01714100470b820601037f230041d0006b22052400200520023602082005200336020c024002400240417f41012002411f71742002411f4b1b20034b0d00200541386a200141186a2203200141286a410010a40420052d00384101470d012000200529023c370200200041086a200541c4006a2802003602000c020b200541cc006a41023602002005411c6a41013602002005420337023c200541e8adc500360238200541013602142005200541106a36024820052005410c6a3602182005200541086a360210200541206a200541386a108a04200041086a200541206a41086a280200360200200020052903203702000c010b2001280200210220054100360220024020022802080d00200541cc006a41013602002005420237023c200541fcb4c500360238200541013602342005200541306a3602482005200541206a360230200541106a200541386a108a0420052802102202450d0020002005290214370204200020023602000c010b0240024002400240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490d0320024101742207200620062007491b22064100480d030240024020020d002006102921020c010b200328020020022006102a21020b2002450d02200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20043a0000200141206a2202200228020041016a3602000c030b200541cc006a220241013602002005420137023c200541e4b7c50036023820054101360234200520063602302005200541306a360248200541106a200541386a108a0420052802102201450d022005200529021437021420052001360210200241013602002005420137023c200541acb1c500360238200541233602342005200541306a3602482005200541106a360230200541206a200541386a108a0402402005280214450d002005280210102e0b20052802202202450d0220002005290224370204200020023602000c030b20064101102c000b102d000b200041003602000b200541d0006a24000bb00301017f230041d0006b22052400200520023602082005200336020c024002400240417f41012002411f71742002411f4b1b20034b0d00200128020021022005410036023420022802080d01200541cc006a41013602002005420237023c200541fcb4c500360238200541013602142005200541106a3602482005200541346a360210200541206a200541386a108a0420052802202202450d0120002005290224370204200020023602000c020b200541cc006a41023602002005412c6a41013602002005420337023c200541e8adc500360238200541013602242005200541206a36024820052005410c6a3602282005200541086a360220200541106a200541386a108a04200041086a200541106a41086a280200360200200020052903103702000c010b200541386a200141186a2202200141286a2203200410a404024020052d00384101470d002000200529023c370200200041086a200541c4006a2802003602000c010b200541386a20022003410010a404024020052d00384101470d002000200529023c370200200041086a200541c4006a2802003602000c010b200041003602000b200541d0006a24000be70301047f230041c0006b22032400200341286a200141186a2204200141286a200210a4040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d0320024101742206200520052006491b22054100480d030240024020020d002005102921020c010b200428020020022005102a21020b2002450d02200120023602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341e4b7c50036022820034101360214200320053602102003200341106a360238200341186a200341286a108a0420032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341acb1c500360228200341233602142003200341106a3602382003200341186a3602102003200341286a108a040240200328021c450d002003280218102e0b20032802002201450d0220002003290204370204200020013602000c030b20054101102c000b102d000b200041003602000b200341c0006a24000ba00401047f230041c0006b22032400200341286a200141186a2204200141286a2205200210a4040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b200341286a20042005200210a404024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d0320024101742206200520052006491b22054100480d030240024020020d002005102921020c010b200428020020022005102a21020b2002450d02200120023602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341e4b7c50036022820034101360214200320053602102003200341106a360238200341186a200341286a108a0420032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341acb1c500360228200341233602142003200341106a3602382003200341186a3602102003200341286a108a040240200328021c450d002003280218102e0b20032802002201450d0220002003290204370204200020013602000c030b20054101102c000b102d000b200041003602000b200341c0006a24000be70301057f230041c0006b22032400200341286a200141186a2204200141286a200210a4040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002205200141246a22062802004f0d00024020052001411c6a280200470d00200541016a22062005490d0320054101742207200620062007491b22064100480d030240024020050d002006102921050c010b200428020020052006102a21050b2005450d02200120053602182001411c6a2006360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341e4b7c50036022820034101360214200320063602102003200341106a360238200341186a200341286a108a0420032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341acb1c500360228200341233602142003200341106a3602382003200341186a3602102003200341286a108a040240200328021c450d002003280218102e0b20032802002201450d0220002003290204370204200020013602000c030b20064101102c000b102d000b200041003602000b200341c0006a24000ba00401057f230041c0006b22032400200341286a200141186a2204200141286a2205200210a4040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b200341286a20042005200210a404024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002205200141246a22062802004f0d00024020052001411c6a280200470d00200541016a22062005490d0320054101742207200620062007491b22064100480d030240024020050d002006102921040c010b200428020020052006102a21040b2004450d02200120043602182001411c6a2006360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341e4b7c50036022820034101360214200320063602102003200341106a360238200341186a200341286a108a0420032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341acb1c500360228200341233602142003200341106a3602382003200341186a3602102003200341286a108a040240200328021c450d002003280218102e0b20032802002201450d0220002003290204370204200020013602000c030b20064101102c000b102d000b200041003602000b200341c0006a24000be70301047f230041c0006b22042400200441286a200141186a2205200141286a200210a4040240024020042d00284101470d002000200429022c370200200041086a200441346a2802003602000c010b0240024002400240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490d0320024101742207200620062007491b22064100480d030240024020020d002006102921020c010b200528020020022006102a21020b2002450d02200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20033a0000200141206a2201200128020041016a3602000c030b2004413c6a220141013602002004420137022c200441e4b7c50036022820044101360214200420063602102004200441106a360238200441186a200441286a108a0420042802182202450d022004200429021c37021c20042002360218200141013602002004420137022c200441acb1c500360228200441233602142004200441106a3602382004200441186a3602102004200441286a108a040240200428021c450d002004280218102e0b20042802002201450d0220002004290204370204200020013602000c030b20064101102c000b102d000b200041003602000b200441c0006a24000bc10201037f230041206b220224000240024020002d00004104470d0020022001280218419ad4c50041082001411c6a28020028020c11040022003a001820022001360210200241003a0019200241003602140c010b2002200128021841a2d4c50041052001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a41a8d4c50010b004210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d00410121002004280218418499c60041012004411c6a28020028020c1104000d010b2001280200220028021841bb98c60041012000411c6a28020028020c11040021000b200120003a00080b200241206a2400200041ff01714100470bf30202047f057e230041d0006b2203240041012104024020002d00080d00200028020421050240200028020022062d00004104710d0041012104200628021841da98c600418199c60020051b4102410120051b2006411c6a28020028020c1104000d0120012000280200200228020c11020021040c010b024020050d00410121042006280218418299c60041022006411c6a28020028020c1104000d01200028020021060b41012104200341013a00172003200341176a3602102006290208210720062902102108200341346a41c098c60036020020032006290218370308200629022021092006290228210a200320062d00303a00482006290200210b2003200a3703402003200937033820032008370328200320073703202003200b3703182003200341086a3602302001200341186a200228020c1102000d00200328023041d898c6004102200328023428020c11040021040b200020043a00082000200028020441016a360204200341d0006a240020000b02000b17000240200041046a280200450d002000280200102e0b0b1600200028020022002802002000280208200110b3010b11002001200028020020002802081093040bbd0801087f230041c0006b22032400200341246a2001360200200341346a200241146a2802002204360200200341033a00382003412c6a2002280210220520044103746a36020020034280808080800437030820032000360220410021062003410036021820034100360210200320053602302003200536022802400240024002400240200228020822070d0020022802002108200228020422092004200420094b1b220a450d0141012104200020082802002008280204200128020c1104000d04200841086a210241012106034002402005280200200341086a200541046a280200110200450d00410121040c060b2006200a4f0d02200241046a210020022802002101200541086a2105200241086a210241012104200641016a2106200328022020012000280200200328022428020c110400450d000c050b0b20022802002108200228020422092002410c6a2802002205200520094b1b220a450d0041012104200020082802002008280204200128020c1104000d03200741106a2105200841086a21024101210603402003200541786a28020036020c2003200541106a2d00003a003820032005417c6a28020036020841002101410021040240024002400240200541086a2802000e0400010203000b2005410c6a2802002100410121040c020b02402005410c6a2802002207200328023422044f0d0041002104200328023020074103746a2207280204412a470d0220072802002802002100410121040c020b4188f2c500200720041038000b4100210420032802282207200328022c460d002003200741086a360228410021042007280204412a470d0020072802002802002100410121040b2003200036021420032004360210024002400240024002400240024020052802000e0404010006040b20032802282200200328022c470d010c050b200541046a2802002200200328023422044f0d01200328023020004103746a2200280204412a470d04200028020028020021040c030b2003200041086a3602282000280204412a470d03200028020028020021040c020b4188f2c500200020041038000b200541046a28020021040b410121010b2003200436021c2003200136021802400240200541706a2802004101460d0020032802282204200328022c460d042003200441086a3602280c010b200541746a2802002204200328023422004f0d04200328023020044103746a21040b02402004280200200341086a200441046a280200110200450d00410121040c050b2006200a4f0d01200241046a210020022802002101200541246a2105200241086a210241012104200641016a2106200328022020012000280200200328022428020c110400450d000c040b0b0240200920064d0d00410121042003280220200820064103746a22052802002005280204200328022428020c1104000d030b410021040c020b41d8f0c5001058000b4198f2c500200420001038000b200341c0006a240020040bfc0101027f230041106b220224002002200128021841e099c60041052001411c6a28020028020c1104003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a4184b8c50010b0041a20022d00082101024020022802042203450d00200141ff0171210041012101024020000d00024020034101470d0020022d000941ff0171450d00200228020022002d00004104710d00410121012000280218418499c60041012000411c6a28020028020c1104000d010b2002280200220128021841bb98c60041012001411c6a28020028020c11040021010b200220013a00080b200241106a2400200141ff01714100470ba46601037f230041206b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00000eac010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab0100010b2002200128021841ebc8c50041112001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000cab010b2002200128021841fcc8c500410b2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000caa010b200220012802184187c9c50041032001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000ca9010b20022001280218418ac9c50041052001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4190c9c50010b00421000ca8010b2002200128021841a0c9c50041042001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4190c9c50010b00421000ca7010b2002200128021841a4c9c50041022001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4190c9c50010b00421000ca6010b2002200128021841a6c9c50041042001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000ca5010b2002200128021841aac9c50041032001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000ca4010b2002200128021841adc9c50041022001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000ca3010b2002200128021841c0c9c50041042001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000ca2010b2002200128021841c4c9c50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41ccc9c50010b004210120022000410c6a36020c20012002410c6a41b0c9c50010b00421000ca1010b2002200128021841dcc9c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000ca0010b2002200128021841e2c9c50041042001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000c9f010b2002200128021841e6c9c500410c2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041016a36020c20012002410c6a41f4c9c50010b00421000c9e010b200220012802184184cac50041042001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c9d010b200220012802184188cac50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c9c010b20022001280218418ecac50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000c9b010b200220012802184196cac50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000c9a010b20022001280218419ecac50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000c99010b2002200128021841a6cac50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000c98010b2002200128021841afcac50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000c97010b2002200128021841b8cac50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c96010b2002200128021841bfcac50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c95010b2002200128021841c6cac50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c94010b2002200128021841cdcac50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c93010b2002200128021841d4cac50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c92010b2002200128021841ddcac50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c91010b2002200128021841e6cac500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c90010b2002200128021841f0cac500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c8f010b2002200128021841facac50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c8e010b200220012802184183cbc50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c8d010b20022001280218418ccbc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c8c010b200220012802184196cbc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c8b010b2002200128021841a0cbc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c8a010b2002200128021841aacbc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c89010b2002200128021841b4cbc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c88010b2002200128021841bccbc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c87010b2002200128021841c4cbc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c86010b2002200128021841cccbc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c85010b2002200128021841d4cbc50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c84010b2002200128021841ddcbc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c83010b2002200128021841e7cbc50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c82010b2002200128021841f0cbc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c81010b2002200128021841facbc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c80010b200220012802184184ccc500410d2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41f4c9c50010b00421000c7f0b200220012802184191ccc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41f4c9c50010b00421000c7e0b20022001280218419bccc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a4ccc50010b00421000c7d0b2002200128021841b4ccc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a41bcccc50010b00421000c7c0b2002200128021841ccccc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000c7b0b2002200128021841d4ccc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a41dcccc50010b00421000c7a0b2002200128021841ecccc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c790b2002200128021841f2ccc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c780b2002200128021841f7ccc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c770b2002200128021841fcccc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c760b200220012802184182cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c750b200220012802184188cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c740b20022001280218418ecdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c730b200220012802184194cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c720b20022001280218419acdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c710b2002200128021841a0cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c700b2002200128021841a6cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6f0b2002200128021841accdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6e0b2002200128021841b2cdc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6d0b2002200128021841b7cdc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6c0b2002200128021841bccdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6b0b2002200128021841c2cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6a0b2002200128021841c8cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c690b2002200128021841cecdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c680b2002200128021841d4cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c670b2002200128021841dacdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c660b2002200128021841e0cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c650b2002200128021841e6cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c640b2002200128021841eccdc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c630b2002200128021841f1cdc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c620b2002200128021841f6cdc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c610b2002200128021841fbcdc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c600b200220012802184180cec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5f0b200220012802184185cec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5e0b20022001280218418acec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5d0b20022001280218418fcec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5c0b200220012802184194cec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5b0b200220012802184199cec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5a0b20022001280218419ecec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c590b2002200128021841a3cec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c580b2002200128021841a8cec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c570b2002200128021841aecec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c560b2002200128021841b4cec50041092001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c550b2002200128021841bdcec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c540b2002200128021841c3cec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c530b2002200128021841c9cec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c520b2002200128021841cfcec50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c510b2002200128021841d6cec50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c500b2002200128021841ddcec50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4f0b2002200128021841e4cec50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4e0b2002200128021841ebcec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4d0b2002200128021841f1cec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4c0b2002200128021841f6cec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4b0b2002200128021841fccec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4a0b200220012802184182cfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c490b200220012802184189cfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c480b200220012802184190cfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c470b200220012802184197cfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c460b20022001280218419ecfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c450b2002200128021841a4cfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c440b2002200128021841aacfc50041092001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c430b2002200128021841b3cfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c420b2002200128021841b9cfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c410b2002200128021841bfcfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c400b2002200128021841c5cfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3f0b2002200128021841cccfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3e0b2002200128021841d3cfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3d0b2002200128021841dacfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3c0b2002200128021841e1cfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3b0b2002200128021841e7cfc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3a0b2002200128021841eccfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c390b2002200128021841f2cfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c380b2002200128021841f8cfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c370b2002200128021841ffcfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c360b200220012802184186d0c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c350b20022001280218418dd0c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c340b200220012802184194d0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c330b20022001280218419ad0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c320b2002200128021841a0d0c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c310b2002200128021841a7d0c50041082001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c300b2002200128021841afd0c50041082001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2f0b2002200128021841b7d0c500410a2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2e0b2002200128021841c1d0c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2d0b2002200128021841c8d0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2c0b2002200128021841ced0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2b0b2002200128021841d4d0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2a0b2002200128021841dad0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c290b2002200128021841e0d0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c280b2002200128021841e6d0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c270b2002200128021841ecd0c500410b2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c260b2002200128021841f7d0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c250b2002200128021841fdd0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c240b200220012802184183d1c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c230b20022001280218418ad1c50041082001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c220b200220012802184192d1c50041082001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c210b20022001280218419ad1c500410a2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c200b2002200128021841a4d1c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1f0b2002200128021841abd1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1e0b2002200128021841b1d1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1d0b2002200128021841b7d1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1c0b2002200128021841bdd1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1b0b2002200128021841c3d1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1a0b2002200128021841c9d1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c190b2002200128021841cfd1c500410b2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c180b2002200128021841dad1c500410a2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c170b2002200128021841e4d1c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c160b2002200128021841f0d1c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c150b2002200128021841fcd1c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c140b200220012802184188d2c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c130b200220012802184194d2c500410d2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c120b2002200128021841a1d2c500410d2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c110b2002200128021841aed2c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c100b2002200128021841bad2c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0f0b2002200128021841c6d2c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0e0b2002200128021841d2d2c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0d0b2002200128021841ded2c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0c0b2002200128021841ecd2c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0b0b2002200128021841fad2c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0a0b200220012802184188d3c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c090b200220012802184196d3c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c080b2002200128021841a2d3c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c070b2002200128021841b0d3c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c060b2002200128021841bed3c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c050b2002200128021841ccd3c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c040b2002200128021841dad3c500410d2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c030b2002200128021841e7d3c50041112001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c020b2002200128021841f8d3c50041112001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c010b200220012802184189d4c50041112001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000b20002d00082101024020002802042203450d00200141ff0171210441012101024020040d00024020034101470d0020002d0009450d00200028020022042d00004104710d00410121012004280218418499c60041012004411c6a28020028020c1104000d010b2000280200220128021841bb98c60041012001411c6a28020028020c11040021010b200020013a00080b200241206a2400200141ff01714100470bd00201027f230041106b22022400200028020028020021002001280218418ab9c50041052001411c6a28020028020c1104002103200241003a0005200220033a00042002200136020020022000410c6a36020c2002418fb9c500410e2002410c6a41a0b9c50010b90421012002200036020c200141b0b9c50041092002410c6a41bcb9c50010b90421012002200041046a36020c200141ccb9c500410c2002410c6a41bcb9c50010b90421012002200041086a36020c200141d8b9c500410c2002410c6a41bcb9c50010b9041a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d00200341fe98c6004102200111040021000c010b2003418099c6004101200111040021000b200220003a00040b200241106a2400200041ff01714100470bdd0302047f057e230041d0006b2205240041012106024020002d00040d0020002d000521070240200028020022082d00004104710d0041012106200828021841da98c60041f898c600200741ff017122071b4102410320071b2008411c6a28020028020c1104000d014101210620002802002208280218200120022008411c6a28020028020c1104000d014101210620002802002208280218419098c60041022008411c6a28020028020c1104000d0120032000280200200428020c11020021060c010b0240200741ff01710d0041012106200828021841fb98c60041032008411c6a28020028020c1104000d01200028020021080b41012106200541013a00172005200541176a360210200829020821092008290210210a200541346a41c098c600360200200520082902183703082008290220210b2008290228210c200520082d00303a00482008290200210d2005200c3703402005200b3703382005200a370328200520093703202005200d3703182005200541086a360230200541086a2001200210ea040d00200541086a419098c600410210ea040d002003200541186a200428020c1102000d00200528023041d898c6004102200528023428020c11040021060b200041013a0005200020063a0004200541d0006a240020000b865f010b7f23004190016b220324002003200136021c2002280208220441586a2105200241106a2802002206412c6c2101024002400240024002400240024002400240024002400240024002400240024002400240024003402001450d01200141546a2101200541286a21072005412c6a2208210520072d00004104470d000b2006412c6c2101200441586a210503402001450d02200141546a2101200541286a21072005412c6a2209210520072d0000410b470d000b2006412c6c2101200441586a210503402001450d03200141546a2101200541286a21072005412c6a2204210520072d00004102470d000b024041002802e899464105490d002003410136023c20032003411c6a36023841002802ec9946210120034188016a41980136020020034180016a42ec80808010370300200341f8006a4125360200200341f0006a4101360200200341e0006a4201370300200341d8006a410a3602002003419bbdc50036027c200341f6bcc500360274200341ec006a200341386a36020020034198bac50036025c200341ecbcc5003602542003410536025041f099c60041c8ecc500200141024622011b200341d0006a41c4e1c50041dce1c50020011b2802101100000b200341106a200810b7032003280214200328021c22014d0d03200328021020014102746a2201450d03200341086a200410b7030240200328020c200128020022014d0d00200328020820014104746a22010d050b412510292201450d092001411d6a41002900bdba45370000200141186a41002900b8ba45370000200141106a41002900b0ba45370000200141086a41002900a8ba45370000200141002900a0ba45370000200041086a42a5808080d00437020020002001360204200041013602000c120b411310292201450d042001410f6a41002800f3b945360000200141086a41002900ecb945370000200141002900e4b945370000200041086a4293808080b00237020020002001360204200041013602000c110b410f10292201450d04200141076a41002900feb945370000200141002900f7b945370000200041086a428f808080f00137020020002001360204200041013602000c100b410f10292201450d04200141076a410029008dba4537000020014100290086ba45370000200041086a428f808080f00137020020002001360204200041013602000c0f0b412510292201450d042001411d6a41002900bdba45370000200141186a41002900b8ba45370000200141106a41002900b0ba45370000200141086a41002900a8ba45370000200141002900a0ba45370000200041086a42a5808080d00437020020002001360204200041013602000c0e0b0240200941086a280200200328021c22054b0d00412710292201450d062001411f6a41002900e4ba45370000200141186a41002900ddba45370000200141106a41002900d5ba45370000200141086a41002900cdba45370000200141002900c5ba45370000200041086a42a7808080f00437020020002001360204200041013602000c0e0b20092802002109200341206a41086a420037030020034280808080c00037032020012d000d2107410021012003410036024020032007410447220a36023c2003200a360238200341003a0044024041002802e8994641044b0d00200341d0006a41086a200341386a41086a29030037030020032003290338370350200341d0006a21070c070b2003412b36024c2003200341386a36024841002802ec9946210120034188016a41cb0036020020034180016a42ec80808010370300200341f8006a4125360200200341f0006a4101360200200341e0006a4201370300200341d0006a41086a2207410a3602002003419bbdc50036027c200341f6bcc500360274200341ec006a200341c8006a360200200341ecbac50036025c200341ecbcc5003602542003410536025041f099c60041c8ecc500200141024622011b200341d0006a41c4e1c50041dce1c50020011b280210110000200328022c2108200328022821012007200341386a41086a29030037030020032003290338370350200341d0006a210720082001460d0620032802242101200341d0006a21070c070b41134101102c000b410f4101102c000b410f4101102c000b41254101102c000b41254101102c000b41274101102c000b200141016a22082001490d0520014101742206200820082006491b220841ffffffff00712008470d05200841047422064100480d050240024020010d002006102921010c010b200328022420014104742006102a21010b2001450d012003200836022820032001360224200328022c21080b200120084104746a22012007290200370200200141086a200741086a2902003702002003200328022c41016a36022c410021072009200541186c6a2201280214450d022009200541186c6a410c6a2109200141146a2108200341d0006a410472210b410021074100210103400240200328022020074d0d00200341d0006a200341206a410010bc04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c060b2007200328022020032802542d000c1b21070b02400240024002400240024002402001200828020022054f0d002003200928020020014104746a2205360234024041002802e899464105490d002003412436023c2003200341346a36023841002802ec99462105200341c90136028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc5003602742003410136027020034201370360200341e897c60036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328023421050b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020052d000022060eac0102220000002201030405060708090a0b0c0d0e0f1010101010101010101010101010111111111111111111121314141414151616161616161616161615161616161616161616161616161616161616161616161717171818181818181818181818181818181717171818181818181818181818181818181717171717171718181818181818171717171717171818181818181819191919191919191919191919191919191919191919191919020b20052d00012105200320032802203602402003200541044722053602382003200641034720057136023c200341003a0044024041002802e899464105490d002003412b36024c2003200341386a36024841002802ec99462105200341cb0036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc5003602742003410136027020034201370360200341ecbac50036025c2003410a360258200341ecbcc500360254200341053602502003200341c8006a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b2802101100000b200341d0006a41086a200341386a41086a2903003703002003200329033837035002400240200328022c22052003280228460d00200328022421060c010b200541016a22062005490d282005410174220c20062006200c491b220c41ffffffff0071200c470d28200c410474220d4100480d280240024020050d00200d102921060c010b20032802242005410474200d102a21060b2006450d1d2003200c36022820032006360224200328022c21050b200620054104746a22052003290350370200200541086a200341d0006a41086a2903003702002003200328022c41016a36022c0c210b41002105024041002802e899464105490d000240200328022c2206417f6a220c20064b0d002003280224200c4104746a4100200c2006491b21050b2003412c36024c200320053602382003200341386a36024841002802ec99462105200341d30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc5003602742003410136027020034201370360200341f4bac50036025c2003410a360258200341ecbcc500360254200341053602502003200341c8006a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b2802101100000b0240200328022c2205450d0020032005417f6a220536022c200328022420054104746a22052d000c4102470d1a0b411710292201450d1c2001410f6a410029008bbb45370000200141086a4100290084bb45370000200141002900fcba45370000200041086a4297808080f00237020020002001360204200041013602000c250b024041002802e899464105490d0041002802ec99462105200341c10036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc500360274200341003602702003420137036020034194bbc50036025c2003410a360258200341ecbcc50036025420034105360250200341c8ecc50036026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b2802101100000b0240200328022c2205417f6a220620054f0d00200620054d0d180b411710292201450d1e2001410f6a410029008bbb45370000200141086a4100290084bb45370000200141002900fcba45370000200041086a4297808080f00237020020002001360204200041013602000c240b200341d0006a200341206a200541046a28020010bc04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c240b200341d0006a200341206a200328025428020410be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b024041002802e899464105490d0041002802ec99462105200341c10036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc500360274200341003602702003420137036020034194bbc50036025c2003410a360258200341ecbcc50036025420034105360250200341c8ecc50036026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b2802101100000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102922010d0141174101102c000b200328022420064104746a41013a000c0c1f0b2001410f6a410029008bbb45370000200141086a4100290084bb45370000200141002900fcba45370000200041086a4297808080f00237020020002001360204200041013602000c230b200341d0006a200341206a200541046a28020010bc04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c230b200341d0006a200341206a2003280254280204220510be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c230b200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c230b20032005360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c1e0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c220b200341d0006a200341206a2005410c6a28020010bc04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c220b2003280254280204210c200541086a2802004102742106200541046a280200210502400340024020060d00200341d0006a200341206a200c10be042003280250450d0220002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b200341d0006a200341206a200528020010bc04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c240b2006417c6a2106200541046a21052003280254280204200c460d000b412710292201450d1a2001411f6a41002900d1bb45370000200141186a41002900cabb45370000200141106a41002900c2bb45370000200141086a41002900babb45370000200141002900b2bb45370000200041086a42a7808080f00437020020002001360204200041013602000c220b024041002802e899464105490d0041002802ec99462105200341c10036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc500360274200341003602702003420137036020034194bbc50036025c2003410a360258200341ecbcc50036025420034105360250200341c8ecc50036026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b2802101100000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102922010d0141174101102c000b200328022420064104746a41013a000c0c1d0b2001410f6a410029008bbb45370000200141086a4100290084bb45370000200141002900fcba45370000200041086a4297808080f00237020020002001360204200041013602000c210b200341d0006a200341206a200a10be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c210b024041002802e899464105490d0041002802ec99462105200341c10036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc500360274200341003602702003420137036020034194bbc50036025c2003410a360258200341ecbcc50036025420034105360250200341c8ecc50036026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b2802101100000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102922010d0141174101102c000b200328022420064104746a41013a000c0c1c0b2001410f6a410029008bbb45370000200141086a4100290084bb45370000200141002900fcba45370000200041086a4297808080f00237020020002001360204200041013602000c200b200341d0006a200541046a280200200210bf04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c200b200341d0006a200341206a2003280254220528020810be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c200b200320052d000d4104472205360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c1b0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c1f0b2003200410b703024002402003280204200541046a28020022054d0d002003280200220620054104746a220c0d010b410e10292201450d18200141066a41002900dfbb45370000200141002900d9bb45370000200041086a428e808080e00137020020002001360204200041013602000c1f0b200341d0006a200341206a200620054104746a28020810be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1f0b2003200c2d000d4104472205360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c1a0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c1e0b200341d0006a200341206a410110be042003280250450d1820002003290350370204200041013602002000410c6a200341d8006a2802003602000c1d0b200341d0006a200341206a410210be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1d0b41012105200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1d0b20034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c180b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c1c0b4101210520034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c170b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c1b0b200341d0006a200341206a410110be042003280250450d1520002003290350370204200041013602002000410c6a200341d8006a2802003602000c1a0b41012105200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1a0b20034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c150b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c190b4101210520034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c140b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c180b200341d0006a200341206a410110be042003280250450d1220002003290350370204200041013602002000410c6a200341d8006a2802003602000c170b41012105200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c170b20034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c120b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c160b200341d0006a200341206a410210be042003280250450d1020002003290350370204200041013602002000410c6a200341d8006a2802003602000c150b4101210520034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c100b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c140b41012105200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c140b20034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c0f0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c130b4101210520034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c0e0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c120b41012105200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c120b20034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c0d0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c110b200341d0006a200341206a410210be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c110b4101210520034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c0c0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c100b41012105200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c100b20034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c0b0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c0f0b200341d0006a200341206a410210be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c0f0b4101210520034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c0a0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c0e0b41012105200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c0e0b20034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c090b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c0d0b200328022420064104746a41013a000c0c070b20052802002106200320052802082205360238024041002802e899464105490d002003410136024c2003200341386a36024841002802ec99462105200341db0036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc5003602742003410136027020034201370360200341e8bbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341c8006a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328023821050b2003200536022020032006360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b28021011000020032802202105200328024821060b0240200520066a220620054f0d00410e102922010d0a410e4101102c000b200320063602200c060b41f0bbc500200120051038000b200d4104102c000b41174101102c000b41274101102c000b410e4101102c000b41174101102c000b200141016a22012008280200490d000c030b0b20064104102c000b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c010b20004100360200200020073602042003280228450d022003280224102e0c020b2003280228450d012003280224102e0c010b102d000b20034190016a24000bc60201027f230041106b220224002001280218418ab9c50041052001411c6a28020028020c1104002103200241003a0005200220033a00042002200136020020022000410c6a36020c2002418fb9c500410e2002410c6a41a0b9c50010b90421012002200036020c200141b0b9c50041092002410c6a41bcb9c50010b90421012002200041046a36020c200141ccb9c500410c2002410c6a41bcb9c50010b90421012002200041086a36020c200141d8b9c500410c2002410c6a41bcb9c50010b9041a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d00200341fe98c6004102200111040021000c010b2003418099c6004101200111040021000b200220003a00040b200241106a2400200041ff01714100470b9b0201027f024002400240024002402001410c6a2802002203417f6a220420034d0d00411610292201450d01200020013602042001410e6a41002900f9be45370000200141086a41002900f3be45370000200141002900ebbe45370000200041086a4296808080e0023702000c040b0240200420026b220220044d0d00411b10292201450d0220002001360204200141176a4100280098bf45360000200141106a4100290091bf45370000200141086a4100290089bf4537000020014100290081bf45370000200041086a429b808080b0033702000c040b200320024d0d022000200128020420024104746a360204200041003602000f0b41164101102c000b411b4101102c000b419cbfc500200220031038000b200041013602000bbb0201037f230041106b220224000240024020002802000d002002200128021841a899c60041042001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c010b2002200128021841ac99c60041042001411c6a28020028020c1104003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41f8c6c50010b004210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d00410121002004280218418499c60041012004411c6a28020028020c1104000d010b2001280200220028021841bb98c60041012000411c6a28020028020c11040021000b200120003a00080b200241106a2400200041ff01714100470bc50401027f230041d0006b2203240020032002360204024041002802e899464105490d002003410136020c2003200341046a36020841002802ec99462102200341c8006a41ef00360200200341c0006a42ec80808010370300200341386a4125360200200341306a4101360200200341206a4201370300200341186a410a3602002003419bbdc50036023c200341f6bcc5003602342003412c6a200341086a36020020034194bec50036021c200341ecbcc5003602142003410536021041f099c60041c8ecc500200241024622021b200341106a41c4e1c50041dce1c50020021b280210110000200328020421020b0240024002402002450d00200341106a2001410010bc0420032802104101470d012000200341106a4104722202290200370200200041086a200241086a2802003602000c020b200041003602000c010b02400240024002402001280200220220032802142204280208460d00200220032802046b220420024d0d02410f102922020d01410f4101102c000b024020042d000c0d00412510292202450d03200042a5808080d004370204200020023602002002411d6a41002900b9be45370000200241186a41002900b4be45370000200241106a41002900acbe45370000200241086a41002900a4be453700002002410029009cbe453700000c040b200041003602000c030b2000428f808080f00137020420002002360200200241076a41002900c8be45370000200241002900c1be453700000c020b20004100360200200120043602000c010b41254101102c000b200341d0006a24000bda09010b7f230041e0006b22032400200320013602202002280208220441586a2105200241106a2802002206412c6c210202400340024020020d00410021070c020b200241546a2102200541286a21072005412c6a2208210520072d00004102470d000b200341186a200810b70320032802182107200328021c21020b2002410020071b21092006412c6c2102200441586a2105200741c8ecc50020071b210a02400340024020020d004100210b0c020b200241546a2102200541286a21072005412c6a2208210520072d00004104470d000b200341106a200810b7032003280210210b2003280214210c0b2006412c6c2102200441586a2105200b41c8ecc500200b1b210d0240024002400240024002400240024003402002450d01200241546a2102200541286a21072005412c6a2208210520072d00004103470d000b200841086a2802002202450d00200241286c2107200828020041186a2102410021050340200520022d0000456a2105200241286a2102200741586a22070d000b200520014d0d012006412c6c2102200441586a210502400240024003402002450d01200241546a2102200541286a21072005412c6a2208210520072d00004103470d000b200341086a200810b70320032802082207200328020c41286c6a2108024003400240024002402008200722026b41f8004b0d0020022008460d0f2002411c6a2105034020022d0018450d02200541286a2105200241286a22022008470d000c100b0b20022d00180d012002411c6a2105200241286a21070c060b2005410c6a21070c050b200241c0006a2d0000450d01200241e8006a2d0000450d03200241a0016a210720024190016a2d00000d000b20024194016a21050c030b200241c4006a2105200241d0006a21070c020b41f5c2c50041c200109b01000b200241ec006a2105200241f8006a21070b2001450d0203402001417f6a21010240024003400240024002402008200722026b41f8004b0d0020022008460d0e2002411c6a2105034020022d0018450d02200541286a2105200241286a22022008460d0f0c000b0b20022d00180d01200241286a210720010d052002411c6a21050c080b2005410c6a21072001450d070c040b200241c0006a2d0000450d02200241e8006a2d0000450d01200241a0016a210720024190016a2d00000d000b20010d0220024194016a21050c050b200241f8006a210720010d01200241ec006a21050c040b200241d0006a210720010d000b200241c4006a21050c020b410021050b200c4100200b1b200120056b22024d0d01200d20024102746a2205450d010b200320052802002202360224200920024d0d01200a20024104746a2202450d0120002002360204410021020c030b200341cc006a41013602002003420237023c20034194c4c5003602382003410136022c2003200341286a3602482003200341206a360228200341d0006a200341386a108a04200341d0006a21020c010b200341cc006a4102360200200341dc006a41013602002003420337023c200341a4c4c500360238200341013602542003200341d0006a3602482003200341206a3602582003200341246a360250200341286a200341386a108a04200341286a21020b20022802002105200041086a200229020437020020002005360204410121020b20002002360200200341e0006a24000f0b41b7c3c50041dd00109b01000bc60902057f017e024020010d00200041ac013a00000f0b02400240024002400240024020012d00002202414f6a41fb004f0d000c010b02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020020e312c2c0001022c2c0304052c06072c2c08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292c0b20012d00012103410221020c2b0b20012d00012103410321020c2a0b20012d00012103410421020c290b200141046a2802002104410721020c270b200141046a2802002104410821020c260b2001280208220541ffffffff03712005470d2720054102742202417f4c0d270240024020020d00410421040c010b200210292204450d290b02402005450d00200128020421022005410274210620042103034020032002280200360200200341046a2103200241046a21022006417c6a22060d000b0b200135020c4220862005ad842107410921020c250b200141046a2802002104410b21020c240b200141046a280200210420012d00012103410c21020c240b200141046a2802002104410f21020c220b200141046a2802002104411021020c210b200141046a2802002104411121020c200b200141046a2802002104411221020c1f0b200141046a2802002104411321020c1e0b200141046a280200210420013502082107411421020c1d0b200141046a280200210420013502082107411521020c1c0b200141046a280200210420013502082107411621020c1b0b200141046a280200210420013502082107411721020c1a0b200141046a280200210420013502082107411821020c190b200141046a280200210420013502082107411921020c180b200141046a280200210420013502082107411a21020c170b200141046a280200210420013502082107411b21020c160b200141046a280200210420013502082107411c21020c150b200141046a280200210420013502082107411d21020c140b200141046a280200210420013502082107411e21020c130b200141046a280200210420013502082107411f21020c120b200141046a280200210420013502082107412021020c110b200141046a280200210420013502082107412121020c100b200141046a280200210420013502082107412221020c0f0b200141046a280200210420013502082107412321020c0e0b200141046a280200210420013502082107412421020c0d0b200141046a280200210420013502082107412521020c0c0b200141046a280200210420013502082107412621020c0b0b200141046a280200210420013502082107412721020c0a0b200141046a280200210420013502082107412821020c090b200141046a280200210420013502082107412921020c080b200141046a280200210420013502082107412a21020c070b20012d00012103412b21020c070b20012d00012103412c21020c060b200141046a2802002104412d21020c040b20012903082107412e21020c020b200141046a2802002104412f21020c020b20012903082107413021020b0b0b200020033a0001200020023a0000200041086a2007370300200041046a20043602000f0b1032000b20024104102c000b8d0301067f230041106b220224000240024002400240200041046a2802002203200041086a28020022046b20012802042205200128020022066b4104762207490d00200028020021030c010b200420076a22062004490d0220034101742205200620062005491b220641ffffffff00712006470d02200641047422054100480d020240024020030d002005102921030c010b200028020020034104742005102a21030b2003450d0120002003360200200041046a2006360200200041086a280200210420012802042105200128020021060b0240024020062005470d00410021060c010b2001200641106a3602000b2002200610c004024020022d000041ac01460d00200320044104746a2106034020062002290300370300200641086a200241086a29030037030002400240200128020022052001280204470d00410021050c010b2001200541106a3602000b200441016a2104200641106a21062002200510c00420022d000041ac01470d000b0b200041086a2004360200200241106a24000f0b20054108102c000b102d000b110020002802003502004101200110b5010bea0302057f017e02402001450d00034020002802940321002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d00200020014105746a220441c4006a2802002105200441386a2802002106200441346a2802002107200141016a21010c010b02400240200028020022010d002003ad210841002104410021010c010b20003301044220862003ad842108410121040b2000102e2008a72103024002402008422088a7220620012f01064f0d00200121050c010b034002400240200128020022050d002003ad2108410021050c010b200441016a210420013301044220862003ad8421080b2001102e2008a72103200521012008422088a7220620052f01064f0d000b0b200641027420056a4198036a2802002100200520064105746a220141c4006a2802002105200141386a2802002106200141346a280200210702402004417f6a2201450d00034020002802940321002001417f6a22010d000b0b410021010b20054102460d012002417f6a210202402006450d002007102e0b20020d000b0b0240200041e08dc000460d00200028020021012000102e2001450d00200128020021052001102e2005450d00024020052802002201450d0003402005102e2001210520012802002200210120000d000b0b2005102e0b0b23002001418d97c600418897c60020002802002d000022001b4104410520001b1093040bc60201037f230041206b2202240002400240200028020022002d00004104470d0020022001280218419ad4c50041082001411c6a28020028020c11040022003a001820022001360210200241003a0019200241003602140c010b2002200128021841a2d4c50041052001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a41a8d4c50010b004210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d00410121002004280218418499c60041012004411c6a28020028020c1104000d010b2001280200220028021841bb98c60041012000411c6a28020028020c11040021000b200120003a00080b200241206a2400200041ff01714100470b0c0020002802002001109b040b890501047f230041d0006b220224002000280200220041046a28020021032000280200210041012104200128021841b998c60041012001411c6a28020028020c110400210502402003450d0020022000360204024020050d00024020012d0000410471450d0041012104200128021841bc98c6004101200128021c28020c1104000d012001280200210541012104200241013a001720022005360218200241c098c60036023420022001290218370308200220012d00303a00482002200128020436021c200220012902283703402002200129022037033820022001290210370328200220012902083703202002200241176a3602102002200241086a360230200241046a200241186a109e010d01200228023041d898c6004102200228023428020c11040021040c010b200241046a2001109e0121040b024020034101470d00200421050c010b200041046a21002003410274417c6a210320042105034020022000360204200541ff0171210441012105024020040d00024020012802002204410471450d00200241013a001720022004360218200241c098c60036023420022001290218370308200220012d00303a00482002200128020436021c200220012902283703402002200129022037033820022001290210370328200220012902083703202002200241176a3602102002200241086a360230200241046a200241186a109e010d01200228023041d898c6004102200228023428020c11040021050c010b200128021841da98c6004102200128021c28020c1104000d00200241046a2001109e0121050b200041046a21002003417c6a22030d000b0b41012100024020050d00200128021841ba98c6004101200128021c28020c11040021000b200241d0006a240020000b8c0e01087f024020002802082201450d00200028020022022001412c6c6a2103034020022204412c6a21020240024020042d00002200410d4b0d00024002400240024002400240024002400240024002400240024020000e0e0001020304050607080e090a0b0c000b200441086a280200450d0d200441046a280200102e0c0d0b0240200441086a280200450d00200441046a280200102e0b200441146a280200450d0c200441106a280200102e0c0c0b02402004410c6a2802002201450d00200441046a28020021002001410474210103400240200041046a280200450d002000280200102e0b200041106a2100200141706a22010d000b0b200441086a280200450d0b2004280204102e0c0b0b02402004410c6a2802002201450d00200441046a2802002100200141286c210103400240200041046a280200450d002000280200102e0b0240200041106a280200450d002000410c6a280200102e0b200041286a2100200141586a22010d000b0b200441086a280200450d0a2004280204102e0c0a0b200441086a280200450d09200441046a280200102e0c090b200441086a280200450d08200441046a280200102e0c080b200441086a280200450d07200441046a280200102e0c070b02402004410c6a2802002200450d00200441046a280200220520004104746a21060340024020052802082201450d0020052802002100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a280200102e0b200041106a2100200141706a22010d000b0b200541106a21000240200541046a280200450d002005280200102e0b2000210520002006470d000b0b200441086a280200450d062004280204102e0c060b02402004410c6a2802002201450d00200441046a2802002100200141146c210103400240200041046a280200450d002000280200102e0b200041146a21002001416c6a22010d000b0b200441086a280200450d052004280204102e0c050b02402004410c6a2802002200450d00200441046a28020022052000411c6c6a2106034002402005410c6a2802002201450d0020052802042100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a280200102e0b200041106a2100200141706a22010d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21000240200541146a280200450d002005280210102e0b2000210520002006470d000b0b200441086a280200450d042004280204102e0c040b02402004410c6a2802002200450d00200441046a2802002205200041186c6a210603400240200541046a280200450d002005280200102e0b0240200541146a2802002201450d00200528020c2100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a280200102e0b200041106a2100200141706a22010d000b0b200541186a21000240200541106a280200450d00200528020c102e0b2000210520002006470d000b0b200441086a280200450d032004280204102e0c030b02402004410c6a2802002200450d00200441046a28020022052000411c6c6a2106034002402005410c6a2802002201450d0020052802042100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a280200102e0b200041106a2100200141706a22010d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21000240200541146a280200450d002005280210102e0b2000210520002006470d000b0b200441086a280200450d022004280204102e0c020b0240200441046a2d0000220041024b0d0002400240024020000e03000102000b2004410c6a280200450d04200441086a280200102e0c040b0240200441146a2802002201450d002004410c6a28020021002001410c6c21010340024020002802002205450d00200041046a280200450d002005102e0b2000410c6a2100200141746a22010d000b0b200441106a280200450d03200428020c102e0c030b0240200441146a2802002200450d002004410c6a280200220720004104746a210803402007220641106a2107024020062802042200450d0002402006410c6a2802002201450d002001410c6c21010340024020002802002205450d00200041046a280200450d002005102e0b2000410c6a2100200141746a22010d000b0b200641086a280200450d002006280204102e0b20072008470d000b0b200441106a280200450d02200428020c102e0c020b2004410c6a280200450d01200441086a280200102e0c010b0240200441086a280200450d00200441046a280200102e0b0240200441146a2802002200450d00200441186a280200450d002000102e0b200441246a280200450d00200441206a280200102e0b20022003470d000b0b0bd00203027f017e017f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210020034120710d012000ac22042004423f8722047c2004852000417f73411f76200110b50121000c020b20002802002103410021000340200220006a41ff006a2003410f712205413072200541d7006a2005410a491b3a00002000417f6a2100200341047622030d000b20004180016a22034181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021030340200220036a41ff006a2000410f712205413072200541376a2005410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d022001410141f8efc5004102200220036a4180016a410020036b10b60121000b20024180016a240020000f0b20034180011035000b20004180011035000bd00202027f027e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120042004423f8722057c2005852004427f55200110b50121000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000b20024180016a240020000f0b20034180011035000b20034180011035000bc30201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff01834101200110b50121000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000b20024180016a240020000f0b20044180011035000b20044180011035000b040041000b02000b02000baf0301047f230041c0006b2202240020002802002100410121030240200128021841aa97c600410c2001411c6a28020028020c1104000d0002400240200028020822030d0020002802002203200028020428020c11070042e4aec285979ba58811520d012002200336020c2002412d36021420022002410c6a36021020012802182104200128021c2105410121032002413c6a41013602002002420237022c200241b897c6003602282002200241106a36023820042005200241286a10b5040d020c010b2002200336020c2002412e36021420022002410c6a36021020012802182104200128021c2105410121032002413c6a41013602002002420237022c200241b897c6003602282002200241106a36023820042005200241286a10b5040d010b200241106a41146a4101360200200241106a410c6a41013602002002411c3602142002200041186a3602202002200041146a36021820022000410c6a36021020012802182100200128021c2101200241286a41146a41033602002002420337022c200241c897c6003602282002200241106a36023820002001200241286a10b50421030b200241c0006a240020030b160020012000280200220028020020002802041093040b6a01037f230041206b220224002001411c6a280200210320012802182104200241086a41106a2000280200220141106a290200370300200241086a41086a200141086a2902003703002002200129020037030820042003200241086a10b5042101200241206a240020010b6f01017f230041c0006b220124002001200036020c200141346a410136020020014201370224200141e897c6003602202001412f36023c2001200141386a36023020012001410c6a360238200141106a200141206a108a042001280210200128021810d304200141106a10d40400000b08002000200110090b17000240200041046a280200450d002000280200102e0b0b0600200010250b0600200010260b2801017f0240200210252203450d002003200020022001200120024b1b10f6041a200010260b20030b1c01017f0240200010252201450d0020014100200010f5041a0b20010bb10101037f0240024002400240200028020022002802042203200028020822046b2002490d00200028020021030c010b200420026a22052004490d0220034101742204200520052004491b22044100480d020240024020030d002004102921030c010b200028020020032004102a21030b2003450d012000200436020420002003360200200028020821040b2000200420026a360208200320046a2001200210f6041a41000f0b20044101102c000b102d000ba70401047f230041106b220224002000280200210002400240024002400240024002402001418001490d002002410036020c2001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c040b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c030b0240200028020822032000280204470d00200341016a22042003490d0620034101742205200420042005491b22044100480d060240024020030d002004102921030c010b200028020020032004102a21030b2003450d022000200436020420002003360200200028020821030b200028020020036a20013a00002000200028020841016a3602080c030b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b20044101102c000b0240024020002802042204200028020822036b2001490d00200028020021040c010b200320016a22052003490d0320044101742203200520052003491b22034100480d030240024020040d002003102921040c010b200028020020042003102a21040b2004450d022000200336020420002004360200200028020821030b2000200320016a360208200420036a2002410c6a200110f6041a0b200241106a240041000f0b20034101102c000b102d000b6401017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a418ce9c500200241086a10b5042101200241206a240020010b0d00429b8bdbb5d1988ae5dc000b5401017f024002402001418080c400460d0041012104200028021820012000411c6a2802002802101102000d010b024020020d0041000f0b2000280218200220032000411c6a28020028020c11040021040b20040bcd0801067f230041f0006b220424002004200336020c20042002360208410121052001210602402001418102490d00410020016b2107418002210803400240200820014f0d00200020086a2c000041bf7f4c0d0041002105200821060c020b2008417f6a21064100210520084101460d01200720086a21092006210820094101470d000b0b200420063602142004200036021020044100410520051b36021c200441c8ecc50041faefc50020051b3602180240024002400240200220014b22080d00200320014b0d00200220034b0d01024002402002450d0020012002460d00200120024d0d01200020026a2c00004140480d010b200321020b200420023602202002450d0220022001460d02200141016a210903400240200220014f0d00200020026a2c000041404e0d040b2002417f6a210820024101460d0420092002462106200821022006450d000c040b0b20042002200320081b360228200441306a41146a4103360200200441c8006a41146a411c360200200441d4006a411c3602002004420337023420044180f0c5003602302004410136024c2004200441c8006a3602402004200441186a3602582004200441106a3602502004200441286a360248200441306a4198f0c500106a000b200441e4006a411c360200200441c8006a41146a411c360200200441d4006a4101360200200441306a41146a410436020020044204370234200441a8f0c5003602302004410136024c2004200441c8006a3602402004200441186a3602602004200441106a36025820042004410c6a3602502004200441086a360248200441306a41c8f0c500106a000b200221080b024020082001460d00410121060240024002400240200020086a22092c00002202417f4a0d0041002105200020016a220621010240200941016a2006460d00200941026a210120092d0001413f7121050b2002411f712109200241ff017141df014b0d01200520094106747221010c020b2004200241ff0171360224200441286a21020c020b4100210020062107024020012006460d00200141016a210720012d0000413f7121000b200020054106747221010240200241ff017141f0014f0d0020012009410c747221010c010b41002102024020072006460d0020072d0000413f7121020b20014106742009411274418080f00071722002722201418080c400460d020b2004200136022441012106200441286a21022001418001490d00410221062001418010490d0041034104200141808004491b21060b200420083602282004200620086a36022c200441306a41146a4105360200200441ec006a411c360200200441e4006a411c360200200441c8006a41146a4130360200200441d4006a413136020020044205370234200441f0f0c500360230200420023602582004410136024c2004200441c8006a3602402004200441186a3602682004200441106a3602602004200441246a3602502004200441206a360248200441306a4198f1c500106a000b41d8f0c5001058000b7c01037f230041206b2202240002402000200110e2040d002001411c6a2802002103200128021821042002411c6a4100360200200241c8ecc5003602182002420137020c20024180f2c50036020820042003200241086a10b5040d00200041046a200110e2042101200241206a240020010f0b200241206a240041010bf00a03037f017e047f410121020240200128021841272001411c6a2802002802101102000d004102210302400240024002402000280200220241776a2200411e4d0d00200241dc00470d010c020b41f400210402400240024020000e1f05010303000303030303030303030303030303030303030303040303030304050b41f20021040c010b41ee0021040b0c020b02400240200210e104450d00200241017267410276410773ad4280808080d0008421050c010b024002400240200241808004490d000240024002402002418080084f0d0020024180fe0371410876210641f183c600210041002107200241ff017121040340200041026a2108200720002d000122036a2109024020002d000022002006460d00200020064b0d062009210720082100200841b784c600470d010c060b20092007490d02200941a6014b0d03200741b784c6006a2100024003402003450d012003417f6a210320002d00002107200041016a210020072004470d000c080b0b2009210720082100200841b784c600470d000c050b0b200241ef83384b0d04200241e28b746a41e28d2c490d042002419fa8746a419f18490d04200241dee2746a410e490d04200241feffff0071419ef00a460d04200241a9b2756a4129490d04200241cb91756a410a4d0d0441012103200221040c070b200720091035000b200941a601105e000b20024180fe0371410876210641c0fec500210041002107200241ff01712104024002400340200041026a2108200720002d000122036a2109024020002d000022002006460d00200020064b0d03200921072008210020084192ffc500470d010c030b024020092007490d00200941a5024b0d0220074192ffc5006a2100024003402003450d012003417f6a210320002d00002107200041016a210020072004470d000c070b0b200921072008210020084192ffc500470d010c030b0b200720091035000b200941a502105e000b200241ffff0371210741b781c60021034101210402400340200341016a21090240024020032d0000220041187441187522084100480d00200921030c010b200941f183c600460d02200841ff007141087420032d0001722100200341026a21030b0240200720006b22074100480d0020044101732104200341f183c600470d010b0b4101210320044101710d040c020b41d8f0c5001058000b200241ffff0371210741dd85c60021034101210402400340200341016a21090240024020032d0000220041187441187522084100480d00200921030c010b200941f588c600460d02200841ff007141087420032d0001722100200341026a21030b0240200720006b22074100480d0020044101732104200341f588c600470d010b0b4101210320044101710d030c010b41d8f0c5001058000b200241017267410276410773ad4280808080d0008421050b41032103200221040c010b200221040b03402003210741dc0021004101210241012103024002400240024020070e0401020300010b024002400240024002402005422088a741ff01710e06050403020100050b200542ffffffff8f60834280808080c000842105410321030c060b200542ffffffff8f608342808080803084210541f5002100410321030c050b200542ffffffff8f608342808080802084210541fb002100410321030c040b20042005a72207410274411c7176410f712203413072200341d7006a2003410a491b210002402007450d002005427f7c42ffffffff0f83200542808080807083842105410321030c040b200542ffffffff8f6083428080808010842105410321030c030b200542ffffffff8f6083210541fd002100410321030c020b20012802184127200128021c2802101102000f0b41002103200421000b20012802182000200128021c280210110200450d000b0b20020b950201017f024002402000418010490d00024002400240024002400240200041808004490d002000410c7641706a2201418002490d01419889c60020014180021038000b200041067641606a220141df074b0d01200141e0f4c5006a2d0000220141c9004b0d02200141037441f089c6006a21010c060b200141c0fcc5006a2d00004106742000410676413f7172220141ff034b0d02200141c08ec6006a2d0000220141394b0d03200141037441c092c6006a21010c050b41f888c600200141e0071038000b418889c600200141ca001038000b41a889c60020014180041038000b41b889c6002001413a1038000b200041037641f8ffffff017141c8f2c5006a21010b200129030042012000413f71ad86834200520bb20201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad4101200110b50121000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000b20024180016a240020000f0b20044180011035000b20044180011035000b0e0020003502004101200110b5010b1c002001280218419197c600410b2001411c6a28020028020c1104000b1c002001280218419c97c600410e2001411c6a28020028020c1104000b140020002802002001200028020428020c1102000bc30501077f410021040240024020024103712205450d00410420056b2205450d00200220032005200520034b1b22046a210641002105200141ff017121072004210820022109024003400240200620096b41034b0d0041002107200141ff0171210603402008450d04200920076a210a2008417f6a2108200741016a2107200a2d0000220a2006470d000b2005200a200141ff01714641016a4101716a20076a417f6a21050c020b200520092d0000220a2007476a2105200a2007460d012005200941016a2d0000220a2007476a2105200a2007460d012005200941026a2d0000220a2007476a2105200a2007460d012005200941036a2d0000220a2007476a21052008417c6a2108200941046a2109200a2007470d000b0b410121090c010b200141ff017121070240024020034108490d002004200341786a220a4b0d00200741818284086c210502400340200220046a220941046a2802002005732208417f73200841fffdfb776a7120092802002005732209417f73200941fffdfb776a7172418081828478710d01200441086a2204200a4d0d000b0b200420034b0d010b200220046a2109200220036a2102200320046b2108410021050240024003400240200220096b41034b0d0041002107200141ff0171210203402008450d04200920076a210a2008417f6a2108200741016a2107200a2d0000220a2002470d000b200a200141ff01714641016a41017120056a20076a417f6a21050c020b200520092d0000220a2007476a2105200a2007460d012005200941016a2d0000220a2007476a2105200a2007460d012005200941026a2d0000220a2007476a2105200a2007460d012005200941036a2d0000220a2007476a21052008417c6a2108200941046a2109200a2007470d000b0b41012109200520046a21050c020b41002109200520076a20046a21050c010b200420031035000b20002005360204200020093602000b2701017f2000280200220128020020012802042000280204280200200028020828020010de04000b02000ba60401077f230041306b220324000240024020020d00410021040c010b200341286a210502400240024002400340024020002802082d0000450d00200028020041f498c6004104200028020428020c1104000d050b2003410a3602282003428a808080103703202003200236021c200341003602182003200236021420032001360210200341086a410a2001200210e704024002400240024020032802084101470d00200328020c210403402003200420032802186a41016a2204360218024002402004200328022422064f0d00200328021421070c010b200328021422072004490d00200641054f0d072003280210200420066b22086a22092005460d0420092005200610f804450d040b200328021c22092004490d0220072009490d0220032006200341106a6a41176a2d0000200328021020046a200920046b10e7042003280204210420032802004101460d000b0b2003200328021c3602180b200028020841003a0000200221040c010b200028020841013a0000200841016a21040b2000280204210920002802002106024020044520022004467222070d00200220044d0d03200120046a2c000041bf7f4c0d030b200620012004200928020c1104000d04024020070d00200220044d0d04200120046a2c000041bf7f4c0d040b200120046a2101200220046b22020d000b410021040c040b20064104105e000b200120024100200410de04000b200120022004200210de04000b410121040b200341306a240020040bfa0101017f230041106b220224002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b20002002410c6a200110ea042101200241106a240020010b6101017f230041206b2202240020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41dc98c600200241086a10b5042101200241206a240020010b0e0020002802002001200210ea040b810201017f230041106b22022400200028020021002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b20002002410c6a200110ea042101200241106a240020010b6401017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41dc98c600200241086a10b5042101200241206a240020010bc30201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff01834101200110b50121000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000b20024180016a240020000f0b20044180011035000b20044180011035000b0c002000280200200110e2040b820201027f230041106b22022400200128021841b099c60041092001411c6a28020028020c1104002103200241003a0005200220033a0004200220013602002002200036020c200241b999c600410b2002410c6a418899c60010b90421012002200041046a36020c200141c499c60041092002410c6a41d099c60010b9041a20022d00042101024020022d0005450d00200141ff0171210041012101024020000d0020022802002201411c6a28020028020c210020012802182103024020012d00004104710d00200341fe98c6004102200011040021010c010b2003418099c6004101200011040021010b200220013a00040b200241106a2400200141ff01714100470bb60201027f230041106b2202240002400240200028020022002d00004101460d00200128021841a899c60041042001411c6a28020028020c11040021010c010b2002200128021841ac99c60041042001411c6a28020028020c1104003a000820022001360200200241003a0009200241003602042002200041016a36020c20022002410c6a419899c60010b0041a20022d00082101024020022802042203450d00200141ff0171210041012101024020000d00024020034101470d0020022d000941ff0171450d00200228020022002d00004104710d00410121012000280218418499c60041012000411c6a28020028020c1104000d010b2002280200220128021841bb98c60041012001411c6a28020028020c11040021010b200220013a00080b200141ff017141004721010b200241106a240020010b1c00200128021841e099c60041052001411c6a28020028020c1104000b2c01017f02402002450d00200021030340200320013a0000200341016a21032002417f6a22020d000b0b20000b3601017f02402002450d00200021030340200320012d00003a0000200341016a2103200141016a21012002417f6a22020d000b0b20000b7101017f0240024020012000490d002002450d01200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000c020b0b2002450d002001417f6a21012000417f6a21030340200320026a200120026a2d00003a00002002417f6a22020d000b0b20000b4a01037f4100210302402002450d000240034020002d0000220420012d00002205470d01200141016a2101200041016a21002002417f6a2202450d020c000b0b200420056b21030b20030b5701017e02400240200341c000710d002003450d012001410020036b413f71ad8820022003413f71ad220486842102200120048621010c010b20012003413f71ad862102420021010b20002001370300200020023703080b5701017e02400240200341c000710d002003450d0120012003413f71ad2204882002410020036b413f71ad86842101200220048821020c010b20022003413f71ad882101420021020b20002001370300200020023703080b7501027e200020034220882205200142208822067e200320027e7c200420017e7c200342ffffffff0f832203200142ffffffff0f8322017e2204422088200320067e7c22034220887c200342ffffffff0f83200520017e7c22034220887c37030820002003422086200442ffffffff0f83843703000b3e01017f230041106b2205240020052001200220032004410010fe04200529030021012000200541086a29030037030820002001370300200541106a24000b4c01017f230041206b22052400200542003703182005420037031020052001200220032004200541106a10fe04200529031021012000200529031837030820002001370300200541206a24000be20502037f067e230041306b2206240002400240024002400240024002400240024002402002500d002003500d012004500d02200479a7200279a76b2207413f4b0d0341ff0020076b2108200741016a21070c080b02402004500d0020050d040c060b024002402005450d0020034200510d0620054200370308200520012003823703000c010b20034200510d050b200120038021010c060b2004500d030240024002402001500d0020047b4201510d01200479a7200279a76b2207413e4b0d0241ff0020076b2108200741016a21070c090b02402005450d0020054200370300200520022004823703080b200220048021010c070b02402005450d002005200137030020052004427f7c2002833703080b200220047a423f838821010c060b2005450d040c020b024020037b4201510d0041bf7f200379a7200279a76b22076b2108200741c1006a21070c060b02402005450d002005420037030820052003427f7c2001833703000b20034201510d06200641206a2001200220037aa710fa04200641286a2903002102200629032021010c060b2005450d020b2005200137030020052002370308420021010c020b00000b420021010b420021020c010b200620012002200841ff007110f904200641106a20012002200741ff007110fa04200641086a2903002102200641106a41086a2903002109200629030021012006290310210a0240024020070d004200210b4200210c0c010b4200210c4200210d03402009420186200a423f8884220b200b427f8520047c200a4201862002423f8884220a427f85220b20037c200b54ad7c423f87220b2004837d200a200b200383220e54ad7d2109200a200e7d210a420020024201862001423f8884842102200d2001420186842101200b420183220b210d2007417f6a22070d000b0b02402005450d002005200a370300200520093703080b200c20024201862001423f8884842102200b20014201868421010b2000200137030020002002370308200641306a24000b0b809a060200418080c0000be59906180010001d000000f862110013000000dc03000009000000617373657274696f6e206661696c65643a20696e646578203c206c656e0000005000100043000000f10a00003000000000000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962616c6c6f632f7665632e7273005000100043000000fd0a00002c000000320000000000000001000000330000003400000035000000360000003700000038000000e0001000190000000001100048000000bb0100002d000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f6f70732f61726974682e72734469676573744974656d206e6f7420657175616c53657373696f6e20486973746f726963616c53657373696f6e7372656163686564206d6178696d756d2064657074682c2063616e6e6f742063726561746500003900000018000000040000003a0000003b0000003c0000003d0000003e0000003f0000006e6f7420656e6f7567682067617320746f20706179206261736520696e7374616e7469617465206665656e6f7420656e6f7567682067617320746f20706179207472616e736665722066656572656163686564206d6178696d756d2064657074682c2063616e6e6f74206d616b6520612063616c6c6e6f7420656e6f7567682067617320746f2070617920626173652063616c6c20666565636f6e747261637420686173206265656e20657669637465640000009002100048000000900a00000a0000000000000000000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e72739003100048000000b1010000230000009003100048000000b201000023000000690310001c0000007477110018000000e50300000d0000002003100049000000870200001d0000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f736f72742e7273617373657274696f6e206661696c65643a206d6964203c3d206c656e00000000000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e727320031000490000009d0000003a0000002003100049000000a4000000300000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d312e302e342f7372632f636f6d706163742e72730000000000e00410000a00000000000000a8f21000020000000000000000000000ec041000010000000000000000000000f40410000d00000000000000b0231100010000000000000000000000040510000100000000000000000000003cd0100008000000000000000c0510000400000000000000000000002c05100001000000000000004e65774163636f756e740000770510001b0000005265617065644163636f756e740000006005100017000000d823110009000000d82311000900000019241100070000001924110007000000340510002c000000205472616e7366657220737563636565646564202866726f6d2c20746f2c2076616c75652c2066656573292e20416e206163636f756e7420776173207265617065642e2041206e6577206163636f756e742077617320637265617465642e76657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c75656163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c62656e6566696369617279206163636f756e74206d757374207072652d6578697374746f6f2066657720667265652066756e647320696e206163636f756e747061796d656e7420776f756c64206b696c6c206163636f756e7442616c616e63657320546f74616c49737375616e636542616c616e636573204672656542616c616e636542616c616e63657320526573657276656442616c616e636542616c616e636573204c6f636b7374696d657374616d702073657420696e20626c6f636b20646f65736e2774206d6174636820736c6f7420696e207365616c003d07100036000000f8031000630000005e01000005000000000000000000000000000000000710003d000000f8031000630000006501000005000000736869667465642073756666696369656e74206269747320726967687420746f206c656164206f6e6c79206c656164696e67207a65726f733b2071656450726576696f7573206d617463682061726d206d61746368657320616e7974696e67206c657373207468616e20325e33303b20716564003d07100036000000f8031000630000008a010000050000000000000000000000000000000000000000000000f803100063000000910100000500000042616c616e6365732056657374696e6765706f636820696e64696365732077696c6c206e6576657220726561636820325e3634206265666f726520746865206465617468206f662074686520756e6976657273653b20716564000000000000006408100008000000000000006c0810000200000000000000000000009c081000170000000000000000000000540910000b0000000000000060091000030000000000000000000000a80910000d000000000000007472616e736665720000000072d910000400000000000000a7ff100023000000000000005f3511000500000000000000c50b100013000000e40b10003600000048761100000000001a0c1000420000005c0c100048000000a40c100045000000e90c10002d0000004876110000000000160d1000460000004876110000000000c52d11000b0000005c0d10004c000000a80d100033000000db0d10005a0000004876110000000000350e1000130000004876110000000000480e1000540000009c0e10004b000000e70e1000350000001c0f100037000000530f1000560000004876110000000000d82d11000c0000007365745f62616c616e63650000000000629910000300000000000000a7ff10002300000000000000bd0b10000800000000000000c50b10001300000000000000d80b10000c00000000000000c50b100013000000100a1000250000004876110000000000350a1000480000007d0a100042000000bf0a100046000000050b10003a00000048761100000000003f0b10002d0000004876110000000000c52d11000b0000006c0b1000200000008c0b100031000000d82d11000c00000020536574207468652062616c616e636573206f66206120676976656e206163636f756e742e20546869732077696c6c20616c74657220604672656542616c616e63656020616e642060526573657276656442616c616e63656020696e2073746f726167652e2069742077696c6c20616c736f2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d202860546f74616c49737375616e636560292e20496620746865206e65772066726565206f722072657365727665642062616c616e63652069732062656c6f7720746865206578697374656e7469616c206465706f7369742c2069742077696c6c20726573657420746865206163636f756e74206e6f6e636520286073797374656d3a3a4163636f756e744e6f6e636560292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e202d20496e646570656e64656e74206f662074686520617267756d656e74732e202d20436f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e64207772697465732e6e65775f66726565436f6d706163743c543a3a42616c616e63653e6e65775f7265736572766564205472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e20607472616e73666572602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e2049742077696c6c2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d2062792074686520605472616e73666572466565602e204966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74206f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e202d20446570656e64656e74206f6e20617267756d656e747320627574206e6f7420637269746963616c2c20676976656e2070726f70657220696d706c656d656e746174696f6e7320666f72202020696e70757420636f6e6669672074797065732e205365652072656c617465642066756e6374696f6e732062656c6f772e202d20497420636f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e642077726974657320696e7465726e616c6c7920616e64206e6f20636f6d706c657820636f6d7075746174696f6e2e2052656c617465642066756e6374696f6e733a2020202d2060656e737572655f63616e5f77697468647261776020697320616c776179732063616c6c656420696e7465726e616c6c792062757420686173206120626f756e64656420636f6d706c65786974792e2020202d205472616e7366657272696e672062616c616e63657320746f206163636f756e7473207468617420646964206e6f74206578697374206265666f72652077696c6c20636175736520202020202060543a3a4f6e4e65774163636f756e743a3a6f6e5f6e65775f6163636f756e746020746f2062652063616c6c65642e2020202d2052656d6f76696e6720656e6f7567682066756e64732066726f6d20616e206163636f756e742077696c6c2074726967676572202020202060543a3a4475737452656d6f76616c3a3a6f6e5f756e62616c616e6365646020616e642060543a3a4f6e4672656542616c616e63655a65726f3a3a6f6e5f667265655f62616c616e63655f7a65726f602e00000000000000641110000d0000000000000000000000711110000a00000000000000000000000000000000000000000000000000000000000000e88c11004412100000000000000000007c11100001000000000000000100000000000000841110000700000001010000000000000b2e11000c000000000000008b1110002b00000000000000000000000000000000000000e88c1100b81110000000000000000000c811100001000000000000000000000000000000d01110000b00000001010000000000000b2e11000c00000000000000711110000a00000000000000000000000000000000000000e88c1100441210000000000000000000dc1110000b000000000000000100000000000000341210000f00000001010000000000000b2e11000c00000000000000711110000a00000000000000000000000000000000000000e88c1100441210000000000000000000541210000b000000000000000100000000000000ac1210000500000001010000000000000b2e11000c00000000000000b11210002c00000000000000000000000000000000000000e88c1100e01210000000000000000000f0121000010000000000000001000000546f74616c49737375616e6365543a3a42616c616e636500211810002600000056657374696e6756657374696e675363686564756c653c543a3a42616c616e63652c20543a3a426c6f636b4e756d6265723e000032000000000000000100000040000000eb171000360000004672656542616c616e636500711510002700000048761100000000009815100050000000e81510005d00000045161000550000009a1610004f000000e9161000510000003a1710001500000048761100000000004f17100057000000a617100045000000526573657276656442616c616e63650032000000000000000100000041000000261310005d00000083131000270000004876110000000000aa1310005b000000051410004900000048761100000000004e1410005d000000ab1410002d0000004876110000000000d8141000530000002b151000460000004c6f636b735665633c42616c616e63654c6f636b3c543a3a42616c616e63652c20543a3a426c6f636b4e756d6265723e3e00000032000000000000000100000042000000f81210002e00000020416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e2054686520616d6f756e74206f66207468652062616c616e6365206f66206120676976656e206163636f756e7420746861742069732065787465726e616c6c792072657365727665643b20746869732063616e207374696c6c2067657420736c61736865642c20627574206765747320736c6173686564206c617374206f6620616c6c2e20546869732062616c616e63652069732061202772657365727665272062616c616e63652074686174206f746865722073756273797374656d732075736520696e206f7264657220746f2073657420617369646520746f6b656e73207468617420617265207374696c6c20276f776e65642720627920746865206163636f756e7420686f6c6465722c20627574207768696368206172652073757370656e6461626c652e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e2074686973202772657365727665206163636f756e74272069732064656c657465643a207370656369666963616c6c792c2060526573657276656442616c616e6365602e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c6574656420696620604672656542616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e2920546865202766726565272062616c616e6365206f66206120676976656e206163636f756e742e205468697320697320746865206f6e6c792062616c616e63652074686174206d61747465727320696e207465726d73206f66206d6f7374206f7065726174696f6e73206f6e20746f6b656e732e20497420616c6f6e65206973207573656420746f2064657465726d696e65207468652062616c616e6365207768656e20696e2074686520636f6e747261637420657865637574696f6e20656e7669726f6e6d656e742e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e20746865202763757272656e74206163636f756e74272069732064656c657465643a207370656369666963616c6c7920604672656542616c616e6365602e20467572746865722c2074686520604f6e4672656542616c616e63655a65726f602063616c6c6261636b20697320696e766f6b65642c20676976696e672061206368616e636520746f2065787465726e616c206d6f64756c657320746f20636c65616e2075702064617461206173736f6369617465642077697468207468652064656c65746564206163636f756e742e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c657465642069662060526573657276656442616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e20496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e2054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e0000000000601910001200000000000000711110000a00000000000000e88c11007419100000000000000000008419100001000000000000000000000034e810000b00000000000000711110000a00000000000000e88c11008c191000000000000000000040e8100001000000000000000000000048e810000b00000000000000711110000a00000000000000e88c11008c191000000000000000000054e810000100000000000000000000005ce810001200000000000000711110000a00000000000000e88c11008c191000000000000000000070e8100001000000000000000000000078e810001200000000000000711110000a00000000000000e88c11009c19100000000000000000009ce8100001000000000000004578697374656e7469616c4465706f736974000032000000000000000100000043000000ac19100035000000320000000000000001000000440000003200000000000000010000004500000020546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e6e6f7420656e6f75676820667265652066756e64730000946a110028000000101a1000430000008c010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f62616c616e6365732f7372632f6c69622e727300101a1000430000008c0100000100000064657374696e6174696f6e2062616c616e636520746f6f206869676820746f20726563656976652076616c756562616c616e636520746f6f206c6f7720746f2073656e642076616c7565676f74206f766572666c6f7720616674657220616464696e6720612066656520746f2076616c756576616c756520746f6f206c6f7720746f20637265617465206163636f756e7400000000000000241b10002200000000000000481b1000010000000000000000000000601b100003000000000000007365745f70656e64696e675f7365636f6e646172795f736c6f74735f6368616e6765000000000000281c100006000000000000002e1c10000c000000781b100045000000bd1b100043000000001c100028000000205365747320612070656e64696e67206368616e676520746f20656e61626c65202f2064697361626c65207365636f6e6461727920736c6f742061737369676e6d656e742e205468652070656e64696e67206368616e67652077696c6c206265207365742061742074686520656e64206f66207468652063757272656e742065706f636820616e642077696c6c20626520656e6163746564206174206063757272656e745f65706f6368202b2032602e6368616e67654f7074696f6e3c626f6f6c3e000000000000042010000a00000000000000000000009ae110000300000000000000000000000000000000000000000000000000000000000000e88c11008c20100000000000000000001020100001000000000000000100000000000000007d10000b0000000000000000000000182010002700000000000000000000000000000000000000000000000000000000000000e88c11004020100000000000000000005020100001000000000000000100000000000000582010000e00000000000000000000009ae110000300000000000000000000000000000000000000000000000000000000000000e88c11008c20100000000000000000006820100003000000000000000100000000000000802010000b00000000000000000000009ae110000300000000000000000000000000000000000000000000000000000000000000e88c11008c20100000000000000000009c20100001000000000000000100000000000000a42010000e0000000000000000000000b22010000c00000000000000000000000000000000000000000000000000000000000000e88c1100c02010000000000000000000d020100002000000000000000100000000000000e02010001b0000000000000000000000ff2311000400000000000000000000000000000000000000000000000000000000000000e88c1100382210000000000000000000fc201000020000000000000000000000000000000c2110000a0000000000000000000000162110000800000000000000000000000000000000000000000000000000000000000000e88c1100802110000000000000000000202110000a000000000000000100000000000000702110000e0000000000000000000000162110000800000000000000000000000000000000000000000000000000000000000000e88c11008021100000000000000000009021100001000000000000000100000000000000982110000c00000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c1100a42110000000000000000000b421100009000000000000000100000000000000fc2110001100000001010000000000009ef3100003000000000000000d2210000d00000000000000000000000000000000000000e88c11001c221000000000000000000048761100000000000000000001000000000000002c2210000b0000000000000000000000ff2311000400000000000000000000000000000000000000000000000000000000000000e88c11003822100000000000000000004822100002000000000000000000000045706f6368496e6465780000a9271000150000005665633c28417574686f7269747949642c2042616265417574686f72697479576569676874293e00320000000000000001000000420000008e2710001b00000045706f63685374617274536c6f740000f526100040000000352710003e000000732710001b00000043757272656e74536c6f740032000000000000000100000046000000e0261000150000005365636f6e64617279536c6f747328626f6f6c2c20626f6f6c290000320000000000000001000000470000006026100042000000a22610003e00000050656e64696e675365636f6e64617279536c6f74734368616e676500ff2510003f0000003e2610002200000052616e646f6d6e6573735b75383b2033325d0000392410002e0000004876110000000000672410000b00000048761100000000007224100041000000b32410003e000000f12410004500000036251000450000007b25100041000000bc251000430000004e65787452616e646f6d6e65737300003200000000000000010000004800000022241000170000005365676d656e74496e64657832000000000000000100000049000000dd2210001f0000004876110000000000fc2210003d0000003923100040000000792310002500000048761100000000009e2310003b000000d9231000420000001b24100007000000556e646572436f6e737472756374696f6e5665633c5b75383b2033325d3e000032000000000000000100000042000000496e697469616c697a65640032000000000000000100000040000000582210003e00000096221000470000002054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732074727565206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e205765206d616b6520612074726164656f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e2057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f2060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e20576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572792065706f63682e204e6578742065706f63682072616e646f6d6e6573732e205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e20232053656375726974792054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e792063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d626572732074686174207468697320286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e20626520757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e2050656e64696e67206368616e676520746f20656e61626c652f64697361626c65207365636f6e6461727920736c6f74732077686963682077696c6c20626520747269676765726564206174206063757272656e745f65706f6368202b2032602e2057686574686572207365636f6e6461727920736c6f74732061726520656e61626c656420696e206361736520746865205652462d626173656420736c6f7420697320656d70747920666f72207468652063757272656e742065706f636820616e6420746865206e6578742065706f63682c20726573706563746976656c792e2043757272656e7420736c6f74206e756d6265722e20536c6f74206174207768696368207468652063757272656e742065706f636820737461727465642e20497420697320706f737369626c652074686174206e6f20626c6f636b2077617320617574686f7265642061742074686520676976656e20736c6f7420616e64207468652065706f6368206368616e676520776173207369676e616c6c6564206c61746572207468616e20746869732e2043757272656e742065706f636820617574686f7269746965732e2043757272656e742065706f636820696e6465782e000000000000302810000d000000000000009ae110000300000000000000e88c110040281000000000000000000050281000020000000000000000000000602810001100000000000000c7a710000900000000000000e88c110074281000000000000000000084281000050000000000000045706f63684475726174696f6e0000003200000000000000010000004a000000dc291000430000001f2a10003f0000004578706563746564426c6f636b54696d650000003200000000000000010000004b000000ac28100041000000ed2810004400000031291000410000007229100042000000b42910002800000020546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e6720626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f7574207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f74206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e20546865206e756d626572206f66202a2a736c6f74732a2a207468617420616e2065706f63682074616b65732e20576520636f75706c652073657373696f6e7320746f2065706f6368732c20692e652e2077652073746172742061206e65772073657373696f6e206f6e636520746865206e65772065706f636820626567696e732e000000000000ec22110008000000000000003c2b1000010000000000000000000000442b10000100000000000000000000004c2b100008000000000000005cf21000010000000000000000000000542b10000100000000000000000000005c2b10000700000000000000642b10000300000000000000000000007c2b1000010000000000000000000000842b100005000000000000005cf210000100000000000000000000008c2b1000010000000000000000000000942b100008000000000000005cf210000100000000000000000000009c2b10000100000000000000b8a010000d0000006d2c10000e0000005370656e64696e67332c10003a0000004177617264656400b8a010000d0000001924110007000000d823110009000000132c1000200000004275726e74000000f02b100023000000526f6c6c6f766572a42b10004c000000205370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e20536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20536f6d652066756e64732068617665206265656e20616c6c6f63617465642e205765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e204e65772070726f706f73616c2e54696d657374616d702055706461746554696d657374616d7020526563656e7448696e7473b82c100031000000e92c10004b0000007e0000000400000046696e616c2068696e74206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f66696e616c6974792d747261636b65722f7372632f6c69622e72734c2d100023000000e92c10004b0000007f0000000400000046696e616c697a6564206865696768742061626f766520626c6f636b206e756d62657254726561737572792050726f706f73616c73000000946a1100280000009c2d10004300000084000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f74726561737572792f7372632f6c69622e72730000000000642e10000d00000000000000742e1000020000000000000000000000a42e1000090000000000000000000000ec2e10000f00000000000000fc2e1000010000000000000000000000142f10000700000000000000000000004c2f10001000000000000000fc2e10000100000000000000000000005c2f1000080000000000000070726f706f73655f7370656e64000000000000005f35110005000000000000006435110015000000000000003a3110000b00000000000000a7ff100023000000683010004b000000b33010004d00000000311000150000004876110000000000c52d11000b000000d02d110008000000c5b61000190000001531100025000000d82d11000c00000072656a6563745f70726f706f73616c00000000005d3010000b0000000000000065ac1000160000001e3010003f0000004876110000000000c52d11000b000000d02d110008000000c5b6100019000000512e110010000000d82d11000c000000617070726f76655f70726f706f73616c9c2f100057000000f32f10002b0000004876110000000000c52d11000b000000d02d110008000000c5b6100019000000deb6100011000000d82d11000c00000020417070726f766520612070726f706f73616c2e2041742061206c617465722074696d652c207468652070726f706f73616c2077696c6c20626520616c6c6f636174656420746f207468652062656e656669636961727920616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e2052656a65637420612070726f706f736564207370656e642e20546865206f726967696e616c206465706f7369742077696c6c20626520736c61736865642e70726f706f73616c5f69642050757420666f727761726420612073756767657374696f6e20666f72207370656e64696e672e2041206465706f7369742070726f706f7274696f6e616c20746f207468652076616c756520697320726573657276656420616e6420736c6173686564206966207468652070726f706f73616c2069732072656a65637465642e2049742069732072657475726e6564206f6e6365207468652070726f706f73616c20697320617761726465642e202d204f6e65204442206368616e67652c206f6e6520657874726120444220656e7472792e62656e65666963696172790000000000000040b010000d0000000000000000000000b8a010000d00000000000000000000000000000000000000000000000000000000000000e88c11005032100000000000000000006032100001000000000000000100000000000000d0af1000090000000101000000000000b8a010000d00000000000000683210002400000000000000000000000000000000000000e88c11008c32100000000000000000009c32100001000000000000000000000000000000a4321000090000000000000000000000ad3210001200000000000000000000000000000000000000000000000000000000000000e88c1100c03210000000000000000000d032100001000000000000000100000032000000000000000100000049000000353310002900000050726f706f73616c3c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e32000000000000000100000040000000163310001f000000417070726f76616c735665633c50726f706f73616c496e6465783e0032000000000000000100000042000000d83210003e0000002050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e2050726f706f73616c7320746861742068617665206265656e206d6164652e204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e000000000000403410000c000000000000004c3410000700000000000000e88c1100543410000000000000000000643410000200000000000000000000007434100013000000000000007a4511000c00000000000000e88c110088341000000000000000000098341000010000000000000000000000a03410000b00000000000000923111000e00000000000000e88c1100ac3410000000000000000000bc341000010000000000000000000000c434100004000000000000004c3410000700000000000000e88c1100c83410000000000000000000d8341000010000000000000050726f706f73616c426f6e645065726d696c6c003200000000000000010000004c0000009835100055000000ed3510004400000050726f706f73616c426f6e644d696e696d756d003200000000000000010000004300000046351000520000005370656e64506572696f64003200000000000000010000004d00000024351000220000004275726e3200000000000000010000004e000000e0341000440000002050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e20506572696f64206265747765656e2073756363657373697665207370656e64732e204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e204672616374696f6e206f6620612070726f706f73616c27732076616c756520746861742073686f756c6420626520626f6e64656420696e206f7264657220746f20706c616365207468652070726f706f73616c2e20416e2061636365707465642070726f706f73616c2067657473207468657365206261636b2e20412072656a65637465642070726f706f73616c20646f6573206e6f742e496e636f6e73697374656e74207374617465202d20636f756c646e277420736574746c6520696d62616c616e636520666f722066756e6473207370656e74206279207472656173757279576974686472617720686173206265656e20636865636b65642061626f76653b0a090909647565735f6c696d69746564203c2072656e745f627564676574203c2062616c616e6365202d2073756273697374656e6365203c2062616c616e6365202d206578697374656e7469616c5f6465706f7369743b0a0909097165640000004f00000008000000040000005000000054696d657374616d70204f72646572656448696e747354696d657374616d70204d656469616e616c77617973206174206c65617374206f6e6520726563656e742073616d706c653b20716564726563656e7420616e64206f72646572656420636f6e7461696e207468652073616d65206974656d733b207165640000510000000400000004000000520000000838100043000000e92c10004b000000b700000004000000c037100048000000900a00000a0000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e72737072756e696e672064696374617465642062792077696e646f775f73697a6520776869636820697320616c776179732073617475726174656420617420313b207165640000000000783810000a00000000000000843810000100000000000000000000009c381000020000000000000066696e616c5f68696e74000000000000c25010000400000000000000de2e110017000000ac3810003d000000e93810001b0000002048696e7420746861742074686520617574686f72206f66207468697320626c6f636b207468696e6b732074686520626573742066696e616c697a656420626c6f636b2069732074686520676976656e206e756d6265722e00000000743910000a00000000000000923111000e00000000000000e88c110080391000000000000000000090391000010000000000000000000000983910000d00000000000000923111000e00000000000000e88c1100a83910000000000000000000b8391000010000000000000057696e646f7753697a65000032000000000000000100000053000000073a1000460000005265706f72744c6174656e637900000032000000000000000100000054000000c039100047000000205468652064656c617920616674657220776869636820706f696e74207468696e6773206265636f6d6520737573706963696f75732e2044656661756c7420697320313030302e20546865206e756d626572206f6620726563656e742073616d706c657320746f206b6565702066726f6d207468697320636861696e2e2044656661756c74206973203130312e0000009c2d100043000000840000000100000050726f706f73657227732062616c616e636520746f6f206c6f774e6f2070726f706f73616c206174207468617420696e6465780000000000443b10000b0000000000000094231100020000000000000000000000503b1000010000000000000000000000583b10001000000000000000b0231100010000000000000000000000683b1000010000000000000000000000703b10000c00000000000000a4d010000100000000000000000000007c3b1000010000000000000000000000843b10000e00000000000000943b1000020000000000000000000000a43b10000100000000000000566f74657252656170656400423c100015000000426164526561706572536c6173686564333c10000f00000054616c6c7953746172746564fe3b10003500000054616c6c7946696e616c697a65640000202411000e000000202411000e000000ac3b10005200000020412074616c6c792028666f7220617070726f76616c20766f746573206f662073656174287329292068617320656e646564202877697468206f6e65206f72206d6f7265206e6577206d656d62657273292e20412074616c6c792028666f7220617070726f76616c20766f746573206f662073656174287329292068617320737461727465642e20736c6173686564207265617065722072656170656420766f7465722c20726561706572436f756e63696c205265676973746572496e666f4f66436f756e63696c204d656d62657273436f756e63696c204e65787446696e616c697a65803d100048000000900a00000a000000436f756e63696c205465726d4475726174696f6e436f756e63696c2050726573656e746174696f6e4475726174696f6e436f756e63696c204c6561646572626f61726400803d100048000000960a00000e000000436f756e63696c2043616e64696461746573436f756e63696c20566f746572496e666f4f6647757275206d656469746174696f6e66696e616c697a652063616e206f6e6c792062652063616c6c656420616674657220612074616c6c7920697320737461727465642e436f756e63696c20417070726f76616c734f66436f756e63696c20566f7465727300002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000803f10000d00000000000000903f1000030000000000000000000000d83f1000180000000000000000000000984010001300000000000000903f1000030000000000000000000000ac401000060000000000000000000000dc4010001300000000000000f0401000040000000000000000000000504110000c0000000000000000000000b04110000d00000000000000c0411000010000000000000000000000d84110000a000000000000000000000028421000100000000000000038421000010000000000000000000000504210000d0000000000000000000000b84210000e00000000000000c842100003000000000000000000000010431000080000000000000000000000504310001100000000000000644310000100000000000000000000007c431000030000000000000000000000f09610000d0000000000000094431000010000000000000000000000ac431000040000000000000000000000cc4310001900000000000000e843100001000000000000000000000000441000020000000000000000000000104410001100000000000000e84310000100000000000000000000002444100002000000000000007365745f617070726f76616c7300000000000000b45010000500000000000000b9501000090000000000000060ac100005000000000000009d4710001200000000000000c25010000400000000000000c650100008000000824c100058000000364c1000100000004876110000000000da4c1000300000000a4d10004a0000004876110000000000544d100035000000894d100051000000da4d10002c000000064e100053000000594e100062000000bb4e1000600000001b4f10001d000000384f1000570000008f4f1000350000004876110000000000c44f10006b0000002f5010001d0000004876110000000000c52d11000b000000d02d1100080000004c501000270000007350100041000000d82d11000c00000070726f78795f7365745f617070726f76616c7300d14b100065000000364c1000100000004876110000000000c52d11000b000000464c10003c000000d82d11000c000000726561705f696e6163746976655f766f7465720000000000a84b10000e00000000000000fa2e11000c00000000000000629910000300000000000000a7ff10002300000000000000b64b10000900000000000000fa2e11000c00000000000000bf4b100012000000000000009d47100012000000474a1000580000009f4a10005c000000fb4a1000280000004876110000000000234b1000450000004876110000000000684b1000400000004876110000000000c52d11000b000000d02d110008000000204a100027000000d82d11000c000000726574726163745f766f7465720000000000000060ac10000500000000000000fa2e11000c000000444910004b00000048761100000000008f491000420000004876110000000000d14910004f0000004876110000000000c52d11000b000000d02d110008000000204a100027000000d82d11000c0000007375626d69745f63616e64696461637900000000404910000400000000000000fa2e11000c000000af4710001e0000004876110000000000cd47100044000000487611000000000011481000480000005948100051000000aa4810004c000000f64810001e0000004876110000000000c52d11000b00000014491000180000002c49100014000000d82d11000c00000070726573656e745f77696e6e65720000000000008f4710000900000000000000a7ff1000230000000000000098471000050000000000000064351100150000000000000060ac100005000000000000009d471000120000009b46100059000000f4461000680000005c4710001e0000004876110000000000c52d11000b0000007a47100015000000deb6100011000000d82d11000c0000007365745f646573697265645f736561747300000000000000f64410000500000000000000fa2e11000c000000db451000590000003446100052000000864610001500000000000000629910000300000000000000a7ff100023000000fb44100048000000487611000000000043451000480000008b451000500000007365745f70726573656e746174696f6e5f6475726174696f6e00000000000000f64410000500000000000000de2e110017000000a04410005600000088441000180000007365745f7465726d5f6475726174696f6e0000003444100054000000884410001800000020536574207468652070726573656e746174696f6e206475726174696f6e2e2049662074686572652069732063757272656e74206120766f7465206265696e672070726573656e74656420666f722c2077696c6c20696e766f6b65206066696e616c697a655f766f7465602e20536574207468652070726573656e746174696f6e206475726174696f6e2e2049662074686572652069732063757272656e746c79206120766f7465206265696e672070726573656e74656420666f722c2077696c6c636f756e742052656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c792e204e6f74653a20412074616c6c792073686f756c642068617070656e20696e7374616e746c7920286966206e6f7420616c726561647920696e20612070726573656e746174696f6e20706572696f642920746f2066696c6c2074686520736561742069662072656d6f76616c206d65616e732074686174207468652064657369726564206d656d6265727320617265206e6f74206d65742e20536574207468652064657369726564206d656d62657220636f756e743b206966206c6f776572207468616e207468652063757272656e7420636f756e742c207468656e2073656174732077696c6c206e6f7420626520757020656c656374696f6e207768656e2074686579206578706972652e204966206d6f72652c207468656e2061206e657720766f74652077696c6c2062652073746172746564206966206f6e65206973206e6f7420616c726561647920696e2070726f67726573732e20436c61696d207468617420607369676e656460206973206f6e65206f662074686520746f702053656c663a3a63617272795f636f756e742829202b2063757272656e745f766f746528292e312063616e646964617465732e204f6e6c7920776f726b73206966207468652060626c6f636b5f6e756d626572203e3d2063757272656e745f766f746528292e306020616e6420603c2063757272656e745f766f746528292e30202b2070726573656e746174696f6e5f6475726174696f6e28296020607369676e6564602073686f756c642068617665206174206c65617374202d204f28766f746572732920636f6d707574652e63616e646964617465746f74616c436f6d706163743c566f7465496e6465783e205375626d6974206f6e6573656c6620666f722063616e6469646163792e204163636f756e74206d757374206861766520656e6f756768207472616e736665727261626c652066756e647320696e20697420746f207061792074686520626f6e642e204e4f54453a20696620606f726967696e602068617320616c72656164792061737369676e656420617070726f76616c7320766961205b607365745f617070726f76616c73605d2c2069742077696c6c204e4f54206861766520616e7920757361626c652066756e647320746f20706173732063616e64696461637920626f6e6420616e64206d75737420666972737420726574726163742e204e6f746520746861742073657474696e6720617070726f76616c732077696c6c206c6f636b2074686520656e746972652062616c616e6365206f662074686520766f74657220756e74696c2072657472616374696f6e206f72206265696e67207265706f727465642e202d20496e646570656e64656e74206f6620696e7075742e202d205468726565204442206368616e6765732e736c6f742052656d6f7665206120766f7465722e20416c6c20766f746573206172652063616e63656c6c656420616e642074686520766f746572206465706f7369742069732072657475726e65642e2054686520696e646578206d7573742062652070726f7669646564206173206578706c61696e656420696e205b60766f7465725f6174605d2066756e6374696f6e2e20416c736f2072656d6f76657320746865206c6f636b206f6e207468652062616c616e6365206f662074686520766f7465722e20536565205b60646f5f7365745f617070726f76616c732829605d2e202d2054776f20666577657220444220656e74726965732c206f6e65204442206368616e67652e2052656d6f7665206120766f7465722e20466f72206974206e6f7420746f206265206120626f6e642d636f6e73756d696e67206e6f2d6f702c20616c6c20617070726f7665642063616e64696461746520696e6469636573206d757374206e6f772062652065697468657220756e72656769737465726564206f72207265676973746572656420746f20612063616e646964617465207468617420726567697374657265642074686520736c6f742061667465722074686520766f7465722067617665207468656972206c61737420617070726f76616c207365742e20426f746820696e6469636573206d7573742062652070726f7669646564206173206578706c61696e656420696e205b60766f7465725f6174605d2066756e6374696f6e2e204d61792062652063616c6c656420627920616e796f6e652e2052657475726e732074686520766f746572206465706f73697420746f20607369676e6564602e7265706f727465725f696e64657877686f5f696e646578617373756d65645f766f74655f696e646578205365742063616e64696461746520617070726f76616c732066726f6d20612070726f78792e20417070726f76616c20736c6f747320737461792076616c6964206173206c6f6e672061732063616e6469646174657320696e2074686f736520736c6f74732061726520726567697374657265642e202d2053616d6520617320607365745f617070726f76616c73602077697468206f6e65206164646974696f6e616c2073746f7261676520726561642e205365742063616e64696461746520617070726f76616c732e20417070726f76616c20736c6f747320737461792076616c6964206173206c6f6e672061732063616e6469646174657320696e2074686f736520736c6f7473204c6f636b732074686520746f74616c2062616c616e6365206f662063616c6c657220696e646566696e6974656c792e204f6e6c79205b60726574726163745f766f746572605d206f72205b60726561705f696e6163746976655f766f746572605d2063616e20756e6c6f636b207468652062616c616e63652e206068696e746020617267756d656e7420697320696e74657270726574656420646966666572656e746c79206261736564206f6e3a202d20696620606f726967696e602069732073657474696e6720617070726f76616c7320666f72207468652066697273742074696d653a2054686520696e6465782077696c6c20626520636865636b656420666f72206265696e6720612076616c6964205f686f6c655f20696e2074686520766f746572206c6973742e2020202d206966207468652068696e7420697320636f72726563746c7920706f696e74696e6720746f206120686f6c652c206e6f206665652069732064656475637465642066726f6d20606f726967696e602e2020202d204f74686572776973652c207468652063616c6c2077696c6c2073756363656564206275742074686520696e6465782069732069676e6f72656420616e642073696d706c792061207075736820746f20746865206c617374206368756e6b2020207769746820667265652073706163652068617070656e732e20496620746865206e65772070757368206361757365732061206e6577206368756e6b20746f20626520637265617465642c20612066656520696e646963617465642062792020205b60566f74696e67466565605d2069732064656475637465642e202d20696620606f726967696e6020697320616c7265616479206120766f7465723a2074686520696e646578205f5f6d7573745f5f2062652076616c696420616e6420706f696e7420746f2074686520636f727265637420706f736974696f6e206f662074686520606f726967696e6020696e207468652063757272656e7420766f74657273206c6973742e204e6f7465207468617420616e7920747261696c696e67206066616c73656020766f74657320696e2060766f746573602069732069676e6f7265643b20496e20617070726f76616c20766f74696e672c206e6f7420766f74696e6720666f7220612063616e64696461746520616e6420766f74696e672066616c73652c2061726520657175616c2e202d2054776f20657874726120444220656e74726965732c206f6e65204442206368616e67652e202d20417267756d656e742060766f74657360206973206c696d6974656420696e206c656e67746820746f206e756d626572206f662063616e646964617465732e766f7465735665633c626f6f6c3e68696e74536574496e64657800000000000050561000140000000000000000000000923111000e00000000000000000000000000000000000000000000000000000000000000e88c110018621000000000000000000064561000010000000000000001000000000000006c5610000c0000000000000000000000923111000e00000000000000000000000000000000000000000000000000000000000000e88c11001862100000000000000000007856100001000000000000000100000000000000805610000c00000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c11001862100000000000000000008c5610000100000000000000010000000000000058b01000070000000000000000000000945610002300000000000000000000000000000000000000000000000000000000000000e88c1100285810000000000000000000b856100004000000000000000100000000000000d8561000090000000000000000000000e15610000900000000000000000000000000000000000000000000000000000000000000e88c1100186210000000000000000000ec56100001000000000000000100000000000000f45610000b0000000101000000000000ff5610001800000000000000175710001100000000000000000000000000000000000000e88c11002858100000000000000000002857100005000000000000000100000000000000505710000e00000001010000000000000b2e11000c000000000000005e5710001000000000000000000000000000000000000000e88c11007057100000000000000000008057100002000000000000000000000000000000905710000b00000001010000000000000b2e11000c000000000000009b5710001700000000000000000000000000000000000000e88c1100b45710000000000000000000c457100001000000000000000000000000000000cc571000060000000101000000000000c65010000800000000000000d25710001900000000000000000000000000000000000000e88c1100285810000000000000000000ec57100001000000000000000100000000000000f45710000c0000000000000000000000c65010000800000000000000000000000000000000000000000000000000000000000000e88c11001862100000000000000000000058100001000000000000000100000000000000085810000a0000000000000000000000c65010000800000000000000000000000000000000000000000000000000000000000000e88c110018621000000000000000000014581000010000000000000001000000000000001c5810000a0000000000000000000000253c11001100000000000000000000000000000000000000000000000000000000000000e88c11002858100000000000000000003858100001000000000000000100000000000000405810000e00000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c11001862100000000000000000005058100001000000000000000100000000000000585810000c0000000000000000000000645810002800000000000000000000000000000000000000000000000000000000000000e88c11008c58100000000000000000009c58100001000000000000000000000000000000a45810000b0000000000000000000000af5810002100000000000000000000000000000000000000000000000000000000000000e88c1100d05810000000000000000000e058100002000000000000000000000000000000a83c11000500000001010000000000000b2e11000c000000000000000b2e11000c00000000000000000000000000000000000000e88c1100f05810000000000000000000c03c110002000000000000000000000050726573656e746174696f6e4475726174696f6e4f5e10004f0000005465726d4475726174696f6e295e100026000000446573697265645365617473ef5d10003a0000005665633c28543a3a4163636f756e7449642c20543a3a426c6f636b4e756d626572293e00c75c10005e000000255d10005c000000815d100054000000d55d10001a000000566f7465436f756e74566f7465496e6465780000805c100047000000417070726f76616c734f6628543a3a4163636f756e7449642c20536574496e646578295665633c417070726f76616c466c61673e6b5b1000680000004876110000000000d35b10005900000048761100000000002c5c1000540000005265676973746572496e666f4f6628566f7465496e6465782c2075333229000032000000000000000100000055000000f65a10005f000000555b100016000000566f746572496e666f4f66566f746572496e666f3c42616c616e63654f663c543e3e000032000000000000000100000040000000d55a100021000000566f746572735665633c4f7074696f6e3c543a3a4163636f756e7449643e3e00925a1000430000004e657874566f746572536574535a10003f000000566f746572436f756e740000395a10001a00000043616e646964617465730000320000000000000001000000420000001d5a10001c00000043616e646964617465436f756e740000f9591000240000004e65787446696e616c697a6528543a3a426c6f636b4e756d6265722c207533322c205665633c543a3a4163636f756e7449643e2932000000000000000100000056000000b1591000480000004c6561646572626f6172645665633c2842616c616e63654f663c543e2c20543a3a4163636f756e744964293e320000000000000001000000400000000059100067000000675910004a000000320000000000000001000000400000002047657420746865206c6561646572626f61726420696620776527726520696e207468652070726573656e746174696f6e2070686173652e2054686520666972737420656c656d656e742069732074686520776569676874206f66206561636820656e7472793b204974206d617920626520746865206469726563742073756d6d656420617070726f76616c207374616b65732c206f7220612077656967687465642076657273696f6e206f662069742e20546865206163636f756e747320686f6c64696e672074686520736561747320746861742077696c6c206265636f6d652066726565206f6e20746865206e6578742074616c6c792e2043757272656e74206e756d626572206f66206163746976652063616e64696461746573205468652070726573656e742063616e646964617465206c6973742e2043757272656e74206e756d626572206f6620566f746572732e20746865206e65787420667265652073657420746f2073746f7265206120766f74657220696e2e20546869732077696c6c206b6565702067726f77696e672e205468652070726573656e7420766f746572206c69737420286368756e6b656420616e6420636170706564206174205b60564f5445525f5345545f53495a45605d292e20426173696320696e666f726d6174696f6e2061626f7574206120766f7465722e2054686520766f746520696e64657820616e64206c69737420736c6f742074686174207468652063616e646964617465206077686f60207761732072656769737465726564206f7220604e6f6e6560206966207468657920617265206e6f742063757272656e746c7920726567697374657265642e2041206c697374206f6620766f74657320666f72206561636820766f7465722e2054686520766f746573206172652073746f726564206173206e756d657269632076616c75657320616e642070617273656420696e2061206269742d77697365206d616e6e65722e20496e206f7264657220746f2067657420612068756d616e2d7265616461626c6520726570726573656e746174696f6e2028605665633c626f6f6c3e60292c20757365205b60616c6c5f617070726f76616c735f6f66605d2e20467572746865726d6f72652c206561636820766563746f72206f66207363616c617273206973206368756e6b656420776974682074686520636170206f662060415050524f56414c5f5345545f53495a45602e2054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e6564206f722061726520696e2070726f67726573732e205468652063757272656e74206d656d626572736869702e205768656e2074686572652773206120766f746520676f696e67206f6e2c20746869732073686f756c64207374696c6c206265207573656420666f7220657865637574697665206d6174746572732e2054686520626c6f636b206e756d62657220287365636f6e6420656c656d656e7420696e20746865207475706c65292069732074686520626c6f636b207468617420746865697220706f736974696f6e2069732061637469766520756e74696c202863616c63756c61746564206279207468652073756d206f662074686520626c6f636b206e756d626572207768656e20746865206d656d6265722077617320656c656374656420616e64207468656972207465726d206475726174696f6e292e204e756d626572206f66206163636f756e747320746861742073686f756c6420636f6e737469747574652074686520636f6c6c6563746976652e20486f77206c6f6e67206561636820706f736974696f6e2069732061637469766520666f722e20486f77206c6f6e6720746f2067697665206561636820746f702063616e64696461746520746f2070726573656e74207468656d73656c7665732061667465722074686520766f746520656e64732e000000000000d06010000d000000000000007a4511000c00000000000000e88c1100e06010000000000000000000f0601000020000000000000000000000006110000a000000000000007a4511000c00000000000000e88c11000c61100000000000000000001c6110000100000000000000000000002461100009000000000000007a4511000c00000000000000e88c1100306110000000000000000000406110000200000000000000000000005061100014000000000000007a4511000c00000000000000e88c110064611000000000000000000074611000020000000000000000000000846110000a000000000000009ef310000300000000000000e88c1100906110000000000000000000a0611000020000000000000000000000b06110001300000000000000e15610000900000000000000e88c1100c46110000000000000000000d4611000030000000000000000000000584511000c00000000000000923111000e00000000000000e88c1100ec6110000000000000000000fc6110000200000000000000000000000c6210000a000000000000009ef310000300000000000000e88c110018621000000000000000000028621000050000000000000000000000506210000e000000000000009ef310000300000000000000e88c1100606210000000000000000000706210000100000000000000000000007862100011000000000000009ef310000300000000000000e88c11008c62100000000000000000009c621000010000000000000043616e646964616379426f6e6400000032000000000000000100000057000000ac6610004e000000fa66100014000000566f74696e67426f6e640000320000000000000001000000430000006a66100042000000566f74696e6746656500000032000000000000000100000058000000036610004a0000004d6610001d00000050726573656e74536c617368506572566f746572320000000000000001000000440000009f65100045000000e46510001f0000004361727279436f756e7400003200000000000000010000005900000031651000470000007865100027000000496e6163746976654772616365506572696f64003200000000000000010000005a000000946410004c000000e06410004b0000002b651000060000003200000000000000010000005b00000042641000490000008b641000090000004465636179526174696f000032000000000000000100000049000000ef6210004d0000003c631000410000007d63100047000000c46310004a0000000e64100034000000564f5445525f5345545f53495a4500003200000000000000010000005c000000cb62100024000000415050524f56414c5f5345545f53495a450000003200000000000000010000005d000000a46210002700000020546865206368756e6b2073697a65206f662074686520617070726f76616c20766563746f722e20546865206368756e6b2073697a65206f662074686520766f74657220766563746f722e20446563617920666163746f72206f6620776569676874207768656e206265696e6720616363756d756c617465642e2049742073686f756c64207479706963616c6c792062652073657420746f205f5f6174206c656173745f5f20606d656d626572736869705f73697a65202d316020746f206b6565702074686520636f6c6c656374697665207365637572652e205768656e2073657420746f20604e602c20697420696e64696361746573206028312f4e295e7460206f66207374616b656420697320646563617965642061742077656967687420696e6372656d656e742073746570206074602e20302077696c6c20726573756c7420696e206e6f20776569676874206265696e6720616464656420617420616c6c20286e6f726d616c20617070726f76616c20766f74696e67292e204120726561736f6e61626c652064656661756c742076616c75652069732032342e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e204120726561736f6e61626c652064656661756c742076616c756520697320313030302e20486f77206d616e7920766f746520696e6469636573206e65656420746f20676f20627920616674657220612074617267657420766f7465722773206c61737420766f7465206265666f726520746865792063616e2062652072656170656420696620746865697220617070726f76616c7320617265206d6f6f742e204120726561736f6e61626c652064656661756c742076616c756520697320312e20486f77206d616e792072756e6e6572732d75702073686f756c64206861766520746865697220617070726f76616c73207065727369737420756e74696c20746865206e65787420766f74652e204120726561736f6e61626c652064656661756c742076616c756520697320322e205468652070756e6973686d656e742c2070657220766f7465722c20696620796f752070726f7669646520616e20696e76616c69642070726573656e746174696f6e2e204120726561736f6e61626c652064656661756c742076616c756520697320312e2054686520616d6f756e74206f662066656520706169642075706f6e206561636820766f7465207375626d697373696f6e2c20756e6c6573732069662074686579207375626d69742061205f686f6c655f20696e64657820616e64207265706c6163652069742e20486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f2062652061626c6520746f207375626d697420766f7465732e20486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f207375626d6974206f6e6527732063616e6469646163792e204120726561736f6e61626c652064656661756c742076616c756520697320392e0000946a11002800000028671000440000000b010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f656c656374696f6e732f7372632f6c69622e727328671000440000000b01000001000000436f756e63696c2050726f787963616e6e6f74207265617020647572696e672070726573656e746174696f6e20706572696f647265706f72746572206d757374206265206120766f746572696e76616c6964207265706f7274657220696e646578766f746520696e646578206e6f742063757272656e7463616e6e6f74207265617020647572696e6720677261636520706572696f6474617267657420666f7220696e616374697669747920636c65616e7570206d75737420626520616374697665626164207265706f7274657220696e6465786261642074617267657420696e646578696e76616c69642074617267657420696e64657872657472616374696f6e20696e646578206d69736d6174636872657472616374696f6e20696e64657820696e76616c696463616e6e6f742072657472616374207768656e2070726573656e74696e6763616e6e6f742072657472616374206e6f6e2d766f7465726475706c69636174652063616e646964617465207375626d697373696f6e696e76616c69642063616e64696461746520736c6f7463616e64696461746520686173206e6f7420656e6f7567682066756e647363616e6e6f742070726573656e74206f757473696465206f662070726573656e746174696f6e20706572696f64696e646578206e6f742063757272656e747374616b65206465706f736974656420746f2070726573656e742077696e6e657220616e6420626520616464656420746f206c6561646572626f6172642073686f756c64206265206e6f6e2d7a65726f6c6561646572626f617264206d757374206578697374207768696c652070726573656e742070686173652061637469766570726573656e746572206d75737420686176652073756666696369656e7420736c61736861626c652066756e647370726573656e7465642063616e646964617465206d7573742062652063757272656e7463616e646964617465206e6f7420776f72746879206f66206c6561646572626f61726463616e646964617465206d757374206e6f7420666f726d2061206475706c696361746564206d656d62657220696620656c65637465646475706c69636174652070726573656e746174696f6e696e636f727265637420746f74616c6e6f20617070726f76616c206368616e67657320647572696e672070726573656e746174696f6e20706572696f64696e636f727265637420766f746520696e646578616d6f756e74206f662063616e6469646174657320746f207265636569766520617070726f76616c20766f7465732073686f756c64206265206e6f6e2d7a65726f616d6f756e74206f662063616e64696461746520766f7465732063616e6e6f742065786365656420616d6f756e74206f662063616e64696461746573696e76616c696420766f74657220696e64657877726f6e6720766f74657220696e6465786e657720766f746572206d75737420686176652073756666696369656e742066756e647320746f207061792074686520626f6e64496d4f6e6c696e6520476f737369704174616c7265616479206d757461626c7920626f72726f776564003200000000000000010000005e0000006772616e62616265696d6f6e306c100033000000636c10004b000000b200000005000000636f6e74726163742073756273797374656d20726573756c74696e6720696e20706f73697469766520696d62616c616e6365212f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f6163636f756e745f64622e7273616c726561647920626f72726f77656400003200000000000000010000005f00000073726d6c2f696d2d6f6e6c696e652d776f726b65722d737461747573006d100048000000900a00000a000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e7273416c69766520636f6e7472616374206f7220746f6d6273746f6e6520616c726561647920657869737473636f6465206973206e6f7420666f756e647072697374696e6520636f6465206973206e6f7420666f756e647468657265206973206e6f7420656e6f7567682067617320666f722073746f72696e672074686520636f64654f757464617465642068656172626561742072656365697665642e496e76616c6964206865617262656174207369676e61747572652e000000000043be100006000000000000006000000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000006200000000000000000000000000000063000000000000000000000000000000d4741000040000000000000064000000000000000000000000000000000000000000000000000000000000006500000000000000000000000200000000000000000000000000000000000000660000000000000000000000000000000ba7100009000000000000006700000000000000000000000000000000000000000000000000000000000000680000000000000000000000020000000000000000000000000000000000000069000000000000000000000000000000458a10000a000000000000006a000000000000000000000000000000000000000000000000000000000000006b000000000000000000000002000000000000000000000000000000000000006300000000000000000000000000000088a3100007000000000000006c00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000006d00000000000000000000000000000063000000000000000000000000000000d874100008000000000000006e000000000000000000000000000000000000000000000000000000000000006f0000000000000000000000000000007000000000000000000000000000000071000000000000000000000000000000410b11000700000000000000720000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000740000000000000000000000000000007500000000000000000000000000000099801000070000000000000076000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000078000000000000000000000000000000790000000000000000000000000000007935110009000000000000007a000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000007c0000000000000000000000000000007d000000000000000000000000000000e074100007000000000000007e000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000008000000000000000000000000000000063000000000000000000000000000000e7741000120000000000000081000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000008000000000000000000000000000000063000000000000000000000000000000f9741000090000000000000082000000000000000000000000000000000000000000000000000000000000008300000000000000000000000000000084000000000000000000000000000000850000000000000000000000000000000275100013000000000000008600000000000000000000000000000000000000000000000000000000000000870000000000000000000000000000008800000000000000000000000000000063000000000000000000000000000000157510000f00000002000000000000000000000000000000000000000000000000000000000000000000000089000000000000000000000002000000000000000000000000000000000000008a0000000000000000000000000000002475100007000000000000008b000000000000000000000000000000000000000000000000000000000000008c0000000000000000000000000000008d000000000000000000000000000000630000000000000000000000000000002b75100008000000000000008e000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000900000000000000000000000000000009100000000000000000000000000000033751000090000000000000092000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000094000000000000000000000000000000950000000000000000000000000000004db71000040000000000000096000000000000000000000000000000000000000000000000000000000000009700000000000000000000000000000098000000000000000000000000000000630000000000000000000000000000003c751000080000000000000099000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000009b0000000000000000000000000000006300000000000000000000004261626542616c616e636573436f756e63696c546563686e6963616c436f6d6d6974746565456c656374696f6e73546563686e6963616c4d656d6265727368697046696e616c697479547261636b65724772616e6470615472656173757279436f6e747261637473496d4f6e6c696e65000000007075100009000000000000007c75100002000000000000000000000048761100000000000000000068656172746265617400000000000000707510000900000000000000ac7510001900000000000000c57510000900000000000000ce751000120000004865617274626561743c543a3a426c6f636b4e756d6265723e7369676e6174757265417574686f726974795369676e617475726500000000e8761000080000000000000000000000923111000e00000000000000000000000000000000000000000000000000000000000000e88c1100f076100000000000000000000077100001000000000000000100000000000000087710000400000000000000000000000c7710001000000000000000000000000000000000000000000000000000000000000000e88c11001c77100000000000000000002c7710000100000000000000010000000000000034771000120000000201010000000000b77011000c0000000000000046771000090000000000000023d110000700000000000000e88c110050771000000000000000000060771000020000000000000001000000476f7373697041743200000000000000010000004900000001781000280000004b6579735665633c417574686f7269747949643e32000000000000000100000042000000cd7710003400000052656365697665644865617274626561747341757468496e646578003200000000000000010000009c000000707710003a000000aa7710002300000020466f7220656163682073657373696f6e20696e646578207765206b6565702061206d617070696e67206f662060417574686f7269747949646020746f20606f6666636861696e3a3a4f70617175654e6574776f726b5374617465602e205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e2054686520626c6f636b206e756d626572207768656e2077652073686f756c6420676f737369702e7375627374726174652d6e6f646500df6acb689907609b0200000037e397fc7c91f5e40100000040fe3ad401f8959a03000000d2bc9897eed08f1501000000f78b278be53f454c01000000ed99c5acb25eedf502000000cbca25e39f1423870100000022f09549cb59f9ff01000000ab3c0572291feb8b010000005365656420697320616e207574663820737472696e6700004f00000008000000040000009d000000517910000d000000367910001b000000108c110002000000f478100042000000d4010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f6e6f64652f72756e74696d652f7372632f6c69622e727342616420696e70757420646174612070726f766964656420746f20657865637574655f626c6f636b00006879100010000000696e697469616c697a655f626c6f636b807910000f0000006170706c795f65787472696e736963009879100013000000696e686572656e745f65787472696e7369637300b47910000f000000636865636b5f696e686572656e747300cc7910001400000076616c69646174655f7472616e73616374696f6ee87910000f0000006f6666636861696e5f776f726b657200007a1000160000006772616e6470615f70656e64696e675f6368616e67650000207a1000150000006772616e6470615f666f726365645f6368616e6765000000407a10001500000067656e65726174655f73657373696f6e5f6b65797366696e616c6e756d46524e4b3a73657373696f6e3a6b657973417574686f727368697020417574686f7253657373696f6e2056616c696461746f72734772616e64706146696e616c697479205374616c6c656453657373696f6e204e6578744b65797300000000e47a10001200000000000000f87a1000010000000000000000000000107b100001000000000000007265706f72745f6d69736265686176696f72000000000000317b1000070000000000000023d1100007000000187b100019000000205265706f727420736f6d65206d69736265686176696f722e5f7265706f72744772616e64706146696e616c6974790000000000007d10000b00000000000000000000000b7d10002300000000000000000000000000000000000000000000000000000000000000e88c1100988310000000000000000000307d100001000000000000000100000000000000387d10000500000000000000000000003d7d10001b00000000000000000000000000000000000000000000000000000000000000e88c1100587d10000000000000000000687d100001000000000000000100000000000000707d10000d00000000000000000000007d7d10002300000000000000000000000000000000000000000000000000000000000000e88c1100b88b10000000000000000000a07d100001000000000000000000000000000000a87d10000a0000000000000000000000923111000e00000000000000000000000000000000000000000000000000000000000000e88c1100b47d10000000000000000000c47d100001000000000000000000000000000000cc7d1000070000000000000000000000d37d10002000000000000000000000000000000000000000000000000000000000000000e88c1100f47d10000000000000000000047e1000010000000000000000000000417574686f7269746965735665633c28417574686f7269747949642c20417574686f72697479576569676874293e0000b47e10001b000000537461746553746f72656453746174653c543a3a426c6f636b4e756d6265723e3200000000000000010000009e000000907e10002400000050656e64696e674368616e676553746f72656450656e64696e674368616e67653c543a3a426c6f636b4e756d6265723e5f7e1000310000004e657874466f72636564000032000000000000000100000040000000307e10002f0000005374616c6c656428543a3a426c6f636b4e756d6265722c20543a3a426c6f636b4e756d6265722900320000000000000001000000550000000c7e10002400000020607472756560206966207765206172652063757272656e746c79207374616c6c65642e206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e2050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e205374617465206f66207468652063757272656e7420617574686f72697479207365742e205468652063757272656e7420617574686f72697479207365742e0000000000fc7e10000800000000000000047f1000020000000000000000000000347f10000a000000000000007365745f6b657973000000004abd100004000000000000008d801000070000000000000094801000050000000000000023d1100007000000847f100039000000bd7f1000480000000580100031000000487611000000000036801000350000004876110000000000c52d11000b0000006b80100022000000f32d110016000000d82d11000c0000002053657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b6579602e20416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722e205468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e20546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e202d204f286c6f67206e2920696e206e756d626572206f66206163636f756e74732e543a3a4b65797370726f6f6653657373696f6e00000000a41311000a0000000000000000000000088310001300000000000000000000000000000000000000000000000000000000000000e88c11009883100000000000000000001c83100001000000000000000100000000000000248310000c0000000000000000000000b77011000c00000000000000000000000000000000000000000000000000000000000000e88c1100308310000000000000000000408310000100000000000000010000000000000048831000070000000000000000000000ff2311000400000000000000000000000000000000000000000000000000000000000000e88c1100dc8b100000000000000000005083100001000000000000000100000000000000588310000d0000000000000000000000ff2311000400000000000000000000000000000000000000000000000000000000000000e88c1100dc8b100000000000000000006883100001000000000000000100000000000000708310000a00000000000000000000007a8310001e00000000000000000000000000000000000000000000000000000000000000e88c1100988310000000000000000000a883100002000000000000000100000000000000b883100008000000020401000000000023d110000700000000000000c08310000e000000000000008d8010000700000000000000e88c1100d08310000000000000000000e0831000040000000000000000000000000000000084100008000000020401000000000023d110000700000000000000088410001400000000000000c08310000e00000000000000e88c1100b88b100000000000000000001c8410000400000000000000000000005665633c543a3a56616c696461746f7249643e00428610001f00000043757272656e74496e64657832000000000000000100000049000000248610001e0000004368616e67656400f68510002e0000005175657565644368616e676564000000e1851000150000005175657565644b6579735665633c28543a3a56616c696461746f7249642c20543a3a4b657973293e320000000000000001000000420000005a8510004f000000a9851000380000004e6578744b657973543a3a56616c696461746f724964000032000000000000000100000040000000338510002700000048761100000000008584100056000000db841000580000004b65794f776e6572284b65795479706549642c205665633c75383e293c8410004900000048761100000000008584100056000000db8410005800000020546865206f776e6572206f662061206b65792e20546865207365636f6e64206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e20546865206669727374206b657920697320616c77617973206044454455505f4b45595f5052454649586020746f206861766520616c6c20746865206461746120696e207468652073616d65206272616e6368206f662074686520747269652e20486176696e6720616c6c206461746120696e207468652073616d65206272616e63682073686f756c642070726576656e7420736c6f77696e6720646f776e206f7468657220717565726965732e20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e2054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b6579732077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e20517565756564206b657973206368616e6765642e205472756520696620616e797468696e6720686173206368616e67656420696e20746869732073657373696f6e2e2043757272656e7420696e646578206f66207468652073657373696f6e2e205468652063757272656e7420736574206f662076616c696461746f72732e000000000000009c8610001000000000000000ac8610000500000000000000e88c1100b48610000000000000000000c4861000020000000000000044454455505f4b45595f505245464958265b75385d0000003200000000000000010000009f000000d4861000590000002d8710000d0000002055736564206173206669727374206b657920666f7220604e6578744b6579736020616e6420604b65794f776e65726020746f2070757420616c6c20746865206461746120696e746f207468652073616d65206272616e6368206f662074686520747269652e4772616e64706146696e616c6974792050656e64696e674368616e67654772616e64706146696e616c69747920537461746553657373696f6e205175657565644b6579734772616e64706146696e616c697479204e657874466f726365644f0000000800000004000000a0000000a10000000000000000000000a200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f0000000800000004000000a0000000a10000000000000000000000a20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000417574686f727368697020556e636c657353657373696f6e204b65794f776e657200000000000000e88910000a00000000000000f48910000100000000000000000000000c8a100001000000000000007365745f756e636c65730000000000002d8a10000a00000000000000378a10000e000000148a1000190000002050726f76696465206120736574206f6620756e636c65732e6e65775f756e636c65735665633c543a3a4865616465723e417574686f72736869700000000000588b10000600000000000000000000005e8b10003a00000000000000000000000000000000000000000000000000000000000000e88c1100988b10000000000000000000a88b100001000000000000000100000000000000b08b10000600000000000000000000000b2e11000c00000000000000000000000000000000000000000000000000000000000000e88c1100b88b10000000000000000000c88b100001000000000000000000000000000000d08b10000c0000000000000000000000ff2311000400000000000000000000000000000000000000000000000000000000000000e88c1100dc8b10000000000000000000ec8b1000010000000000000001000000556e636c65735665633c556e636c65456e7472794974656d3c543a3a426c6f636b4e756d6265722c20543a3a486173682c20543a3a4163636f756e7449643e3e320000000000000001000000420000003c8c100007000000417574686f72000032000000000000000100000040000000238c100019000000446964536574556e636c657332000000000000000100000040000000f48b10002f000000205768657468657220756e636c6573207765726520616c72656164792073657420696e207468697320626c6f636b2e20417574686f72206f662063757272656e7420626c6f636b2e20556e636c6573005c8c10007c000000d88c1000490000007900000006000000657865632e7072656661625f6d6f64756c652e696e697469616c2063616e27742062652067726561746572207468616e20657865632e7072656661625f6d6f64756c652e6d6178696d756d3b0a09090909090974687573204d656d6f72793a3a6e6577206d757374206e6f74206661696c3b0a0909090909097165642f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f7761736d2f6d6f642e72736e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e72656769737465726564206475706c6963617465206b6579556e636c657320616c72656164792073657420696e20626c6f636b2e756e636c6520616c726561647920696e636c75646564756e636c652069732067656e65736973756e636c6520697320746f6f206869676820696e20636861696e756e636c6520706172656e74206e6f7420696e20636861696e756e636c65206e6f7420726563656e7420656e6f75676820746f20626520696e636c75646564756e636c65733030496e686572656e7420776974682073616d65206964656e74696669657220616c726561647920657869737473214e6f206f74686572206572726f72732061726520616363657074656420616674657220616e2068617264206572726f72215468657265206973206f6e6c79206f6e6520666174616c206572726f723b20716564004f000000080000000400000050000000626164207369676e617475726520696e2065787472696e7369630000000000008c8f10000b0000000000000048761100000000000000000000000000988f1000010000000000000000000000a08f10000d0000000000000048761100000000000000000000000000b08f1000010000000000000000000000b88f10000e0000000000000048761100000000000000000000000000c88f1000010000000000000000000000d08f10000c0000000000000048761100000000000000000000000000dc8f1000010000000000000000000000e48f10000500000000000000ec8f1000010000000000000000000000f48f100001000000000000004d656d626572416464656400ff901000390000004d656d62657252656d6f766564000000c49010003b0000004d656d626572735377617070656400008d901000370000004d656d626572735265736574479010004600000044756d6d79000000189010002f000000fc8f10001c000000205068616e746f6d206d656d6265722c206e6576657220757365642e73725f7374643a3a6d61726b65723a3a5068616e746f6d446174613c284163636f756e7449642c204576656e74293e20546865206d656d62657273686970207761732072657365743b2073656520746865207472616e73616374696f6e20666f722077686f20746865206e6577207365742069732e2054776f206d656d62657273207765726520737761707065643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732072656d6f7665643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732061646465643b2073656520746865207472616e73616374696f6e20666f722077686f2e320000000000000001000000a3000000946a110028000000609110004500000061000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f6d656d626572736869702f7372632f6c69622e727373657269616c697a656420617267732073686f756c642062652070726f7669646564206279207468652072756e74696d653b0a090909636f72726563746c792073657269616c697a656420646174612073686f756c6420626520646573657269616c697a61626c653b0a090909716564000000946a110028000000bc6a11005000000037010000090000000000000080d1f00840787d01000000000065cd1d23b4cc3a113b5c2301000000d31b421e4fdcba34836c472001000000c75bbd1e52a1fd2e01b4511d010000005feb3f1f1d03952998c57b1a01000000bdb6ca1fa50181245d60c61701000000abd95e20029dc11fec4f3215010000006fadfd2034d5561b086ec01201000000efdba82133aa4017c3a4711001000000eb7a6222fd1b7f132df1460e01000000c1332d23942a1210ad66410c01000000777f0c2408d6f90c5e33620a01000000a3040525591e360ab7a5aa080100000085311d268803c70760341c070100000097465e279f85ac054289b805010000007346d628a4a4e603ce9181040100000019e89b2abe607502ad987903010000009db7d72c54ba5801bb71a30201000000eb88dd2ff4b29000c5cf0202010000000b8c8d349e412700f8d7a50101000000e59510001c0000007094100044000000bf00000003000000c1951000240000007094100044000000c80000000300000089951000380000007094100044000000060100002a00000061951000280000007094100044000000070100003200000039951000280000007094100044000000090100002c0000000d9510002c0000007094100044000000080100004c000000db9410003200000070941000440000003101000003000000b49410002700000070941000440000003901000004000000489410002800000070941000440000003f0100000300000053746f7261676520726f6f74206d757374206d6174636820746861742063616c63756c617465642e2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f6578656375746976652f7372632f6c69622e7273446967657374206974656d206d757374206d6174636820746861742063616c63756c617465642e4e756d626572206f6620646967657374206974656d73206d757374206d6174636820746861742063616c63756c617465642e416c6c2065787472696e736963732073686f756c6420686176652074686520636f7272656374206e6f6e636545787472696e736963732073686f756c64206e6f742065786365656420626c6f636b206c696d6974416c6c2065787472696e736963732073686f756c642062652070726f7065726c79207369676e6564416c6c2065787472696e736963732073686f756c6420686176652073656e6465722061626c6520746f2070617920746865697220666565735472616e73616374696f6e207472696520726f6f74206d7573742062652076616c69642e506172656e7420686173682073686f756c642062652076616c69642e00000000000000b49610000a00000000000000c0961000010000000000000000000000d8961000030000000000000000000000f09610000d00000000000000c096100001000000000000000000000000971000030000000000000000000000189710000b0000000000000024971000020000000000000000000000549710000300000000000000000000006c9710000d000000000000007c9710000100000000000000000000009497100004000000000000006164645f6d656d6265720000000000006299100003000000000000000b2e11000c000000169910001f0000004876110000000000359910002d00000072656d6f76655f6d656d626572000000c2981000240000004876110000000000e698100030000000737761705f6d656d6265720000000000b998100006000000000000000b2e11000c00000000000000bf98100003000000000000000b2e11000c0000005b9810003000000048761100000000008b9810002e00000072657365745f6d656d6265727300000000000000549810000700000000000000253c110011000000b4971000560000000a9810001b0000004876110000000000259810002f000000204368616e676520746865206d656d6265727368697020746f2061206e6577207365742c20646973726567617264696e6720746865206578697374696e67206d656d626572736869702e204265206e69636520616e64207061737320606d656d6265727360207072652d736f727465642e204d6179206f6e6c792062652063616c6c65642066726f6d206052657365744f726967696e60206f7220726f6f742e6d656d626572732053776170206f7574206f6e65206d656d626572206072656d6f76656020666f7220616e6f746865722060616464602e204d6179206f6e6c792062652063616c6c65642066726f6d2060537761704f726967696e60206f7220726f6f742e72656d6f76656164642052656d6f76652061206d656d626572206077686f602066726f6d20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d206052656d6f76654f726967696e60206f7220726f6f742e204164642061206d656d626572206077686f6020746f20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d20604164644f726967696e60206f7220726f6f742e77686f496e7374616e6365314d656d626572736869700000000058b01000070000000000000000000000253c11001100000000000000000000000000000000000000000000000000000000000000e88c1100d09910000000000000000000e099100001000000000000000100000032000000000000000100000042000000e899100032000000205468652063757272656e74206d656d626572736869702c2073746f72656420617320616e206f726465726564205665632e000060911000450000006100000001000000496e7374616e6365314d656d62657273686970204d656d62657273616c72656164792061206d656d626572626164206f726967696e6e6f742061206d656d626572000000809a100048000000960a00000e0000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000f49a10000f00000000000000049b1000020000000000000000000000149b100004000000000000004e65774163636f756e74496e64657800d823110009000000af9b10000c000000349b1000220000004876110000000000569b100041000000979b1000180000002041206e6577206163636f756e7420696e646578207761732061737369676e65642e2054686973206576656e74206973206e6f7420747269676765726564207768656e20616e206578697374696e6720696e64657820697320726561737369676e656420746f20616e6f7468657220604163636f756e744964602e4163636f756e74496e646578496e76616c6964206f726967696e000000e49b10002b0000000f9c100044000000000100000400000054696d657374616d70206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f74696d657374616d702f7372632f6c69622e7273006c9c1000300000000f9c100044000000f40000000400000054696d657374616d70206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636bb49c10004e0000000f9c100044000000f50000000400000054696d657374616d70206d75737420696e6372656d656e74206279206174206c65617374203c4d696e696d756d506572696f643e206265747765656e2073657175656e7469616c20626c6f636b73000000000000ec22110008000000000000000c9e10000400000000000000000000002c9e10000200000000000000000000003c9e10000500000000000000449e10000500000000000000000000006c9e10000200000000000000000000007c9e1000080000000000000084d01000010000000000000000000000849e10000100000000000000000000008c9e10000b0000000000000084d01000010000000000000000000000989e10000100000000000000000000006e2311000800000000000000a09e1000020000000000000000000000b09e1000010000000000000000000000b89e10000e00000000000000a09e1000020000000000000000000000c89e10000100000000000000d823110009000000b8a010000d000000e1231100040000004aa010000b00000055a0100053000000a8a0100010000000566f746564000000d823110009000000e123110004000000ff231100040000004aa010000b0000004aa010000b000000c29f10004200000004a0100046000000417070726f766564919f100031000000446973617070726f766564005c9f100035000000e123110004000000ff231100040000001b9f1000410000004d656d62657245786563757465640000d09e10004b00000020412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e207761732065786563757465643b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e6720612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e4d656d626572436f756e742041206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e20604d656d626572436f756e7460292e50726f706f73616c496e64657854696d657374616d70204e6f77496e7374616e636532436f6c6c656374697665204d656d62657273496e7374616e636531436f6c6c656374697665204d656d62657273496e646963657320456e756d536574004f000000080000000400000050000000946a11002800000040a110003f0000006a000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7375646f2f7372632f6c69622e727300946a11002800000098a11000420000004a000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f696e64696365732f7372632f6c69622e72730000946a110028000000f4a11000450000008b000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6c6c6563746976652f7372632f6c69622e727300000098a11000420000004a00000001000000696e76616c6964206163636f756e7420696e64657854696d657374616d7020746f6f2066617220696e2066757475726520746f206163636570744765747320616e64206465636f6465732074696d657374616d7020696e686572656e74206461746100000000000008a31000050000000000000010a3100001000000000000000000000018a3100001000000000000000000000020a310000a00000000000000b02311000100000000000000000000002ca3100001000000000000005375646964000000ff2311000400000070a31000180000004b65794368616e676564000034a310003c00000020546865207375646f6572206a757374207377697463686564206964656e746974793b20746865206f6c64206b657920697320737570706c6965642e2041207375646f206a75737420746f6f6b20706c6163652e496e6469636573000000000040a410000b00000000000000000000004ba410000f00000000000000000000000000000000000000000000000000000000000000e88c110028b3100000000000000000005ca410000100000000000000010000000000000064a410000700000001010000000000004ba410000f00000000000000253c11001100000000000000000000000000000000000000e88c110038b3100000000000000000006ca410000100000000000000010000004e657874456e756d536574543a3a4163636f756e74496e64657800008aa410001f000000456e756d5365740074a41000160000002054686520656e756d65726174696f6e20736574732e20546865206e657874206672656520656e756d65726174696f6e207365742e496e7374616e636531436f6c6c6563746976652050726f706f73616c73496e7374616e636531436f6c6c65637469766520566f74696e67496e7374616e636532436f6c6c6563746976652050726f706f73616c73496e7374616e636532436f6c6c65637469766520566f74696e67496e6469636573204e657874456e756d53657400000000000058a5100003000000000000005ca5100001000000000000000000000074a5100009000000000000007365740000000000f6a610000300000000000000f9a6100012000000bca51000160000004876110000000000d2a510005600000028a610003600000048761100000000005ea6100051000000afa61000110000004876110000000000c0a610003600000020536574207468652063757272656e742074696d652e20546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6e2070686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e205468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e742073706563696669656420627920604d696e696d756d506572696f64602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060496e686572656e74602e6e6f77436f6d706163743c543a3a4d6f6d656e743e54696d657374616d7000000000c4a71000030000000000000000000000c7a710000900000000000000000000000000000000000000000000000000000000000000e88c1100d0a710000000000000000000e0a7100001000000000000000100000000000000e8a71000090000000000000000000000ff2311000400000000000000000000000000000000000000000000000000000000000000e88c1100f4a71000000000000000000004a810000100000000000000010000004e6f77543a3a4d6f6d656e743200000000000000010000004600000039a8100024000000446964557064617465000000320000000000000001000000400000000ca810002d00000020446964207468652074696d657374616d7020676574207570646174656420696e207468697320626c6f636b3f2043757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e0000000000000098a810000d00000000000000c7a710000900000000000000e88c1100a8a810000000000000000000b8a8100004000000000000004d696e696d756d506572696f64000000320000000000000001000000a4000000d8a810005a00000032a910005a0000008ca9100059000000e5a910001c00000020546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e204265776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f2064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20652e672e20466f7220417572612c2069742077696c6c20626520646f75626c65207468697320706572696f64206f6e2064656661756c742073657474696e67732e00000000000000b4aa10000b00000000000000c0aa1000010000000000000000000000d8aa1000040000000000000000000000f8aa1000070000000000000000ab100001000000000000000000000018ab1000030000000000000000000000b8281100070000000000000030ab100002000000000000000000000060ab100004000000000000000000000070291100040000000000000080ab1000030000000000000000000000c8ab100004000000000000007365745f6d656d626572730000000000f8ad10000b00000000000000253c11001100000077ad100054000000cbad1000170000004876110000000000e2ad100016000000657865637574650000000000583311000800000000000000f1ac10001e0000000fad10003d00000048761100000000004cad10002b00000000000000d4ac10000900000000000000ddac10001400000000000000583311000800000000000000f1ac10001e000000c52d11000b00000082ac100024000000a6ac10002e000000d82d11000c000000000000005833110008000000000000007c2f1100070000000000000060ac1000050000000000000065ac100016000000000000007bac10000700000000000000ff23110004000000c52d11000b000000e8ab1000230000000bac100055000000d82d11000c000000202d20426f756e6465642073746f72616765207265616420616e64207772697465732e202d2057696c6c20626520736c696768746c792068656176696572206966207468652070726f706f73616c20697320617070726f766564202f20646973617070726f7665642061667465722074686520766f74652e696e646578436f6d706163743c50726f706f73616c496e6465783e617070726f7665202d20426f756e6465642073746f7261676520726561647320616e64207772697465732e202d20417267756d656e7420607468726573686f6c6460206861732062656172696e67206f6e207765696768742e7468726573686f6c64436f6d706163743c4d656d626572436f756e743e426f783c3c542061732054726169743c493e3e3a3a50726f706f73616c3e20446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e204f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e205365742074686520636f6c6c6563746976652773206d656d62657273686970206d616e75616c6c7920746f20606e65775f6d656d62657273602e204265206e69636520746f2074686520636861696e20616e642070726f76696465206974207072652d736f727465642e20526571756972657320726f6f74206f726967696e2e6e65775f6d656d62657273496e7374616e636531436f6c6c656374697665000000000000d0af1000090000000000000000000000d9af10000c00000000000000000000000000000000000000000000000000000000000000e88c110038b310000000000000000000e8af100001000000000000000100000000000000f0af10000a00000001010000000000007c2f11000700000000000000faaf10001900000000000000000000000000000000000000e88c110018b31000000000000000000014b01000010000000000000000000000000000001cb010000600000001010000000000007c2f1100070000000000000022b010001300000000000000000000000000000000000000e88c110018b31000000000000000000038b010000100000000000000000000000000000040b010000d00000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c110028b31000000000000000000050b010000100000000000000010000000000000058b01000070000000000000000000000253c11001100000000000000000000000000000000000000000000000000000000000000e88c110038b31000000000000000000060b0100001000000000000000100000050726f706f73616c735665633c543a3a486173683e00000028b110002400000050726f706f73616c4f663c542061732054726169743c493e3e3a3a50726f706f73616c00f5b0100033000000566f74696e67566f7465733c543a3a4163636f756e7449643e000000c8b010002d00000050726f706f73616c436f756e74000000b6b01000120000004d656d626572730068b010004e000000205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e2050726f706f73616c7320736f206661722e20566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e2054686520686173686573206f6620746865206163746976652070726f706f73616c732e496e7374616e636532436f6c6c6563746976650000000000d0af1000090000000000000000000000d9af10000c00000000000000000000000000000000000000000000000000000000000000e88c110038b310000000000000000000e8af100001000000000000000100000000000000f0af10000a00000001010000000000007c2f11000700000000000000faaf10001900000000000000000000000000000000000000e88c110018b31000000000000000000014b01000010000000000000000000000000000001cb010000600000001010000000000007c2f1100070000000000000022b010001300000000000000000000000000000000000000e88c110018b31000000000000000000038b010000100000000000000000000000000000040b010000d00000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c110028b31000000000000000000050b010000100000000000000010000000000000058b01000070000000000000000000000253c11001100000000000000000000000000000000000000000000000000000000000000e88c110038b31000000000000000000060b0100001000000000000000100000032000000000000000100000040000000320000000000000001000000490000003200000000000000010000004200000040a110003f0000006a000000010000006f6e6c79207468652063757272656e74207375646f206b65792063616e207375646f5375646f204b65796f6e6c79207468652063757272656e74207375646f206b65792063616e206368616e676520746865207375646f206b657900f4a11000450000008b0000000100000070726f706f736572206e6f742061206d656d6265726475706c69636174652070726f706f73616c73206e6f7420616c6c6f776564496e7374616e636531436f6c6c6563746976652050726f706f73616c4f66496e7374616e636531436f6c6c6563746976652050726f706f73616c436f756e7470726f706f73616c206d757374206578697374766f746572206e6f742061206d656d6265726d69736d61746368656420696e6465786475706c696361746520766f74652069676e6f7265640000a0b4100048000000960a00000e0000000000000000000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e7273496e7374616e636532436f6c6c6563746976652050726f706f73616c4f66496e7374616e636532436f6c6c6563746976652050726f706f73616c436f756e74000000000080b510000400000000000000682a110001000000000000000000000084b51000090000000000000000000000ccb510000700000000000000d4b51000010000000000000000000000ecb5100009000000000000007375646fefb610004e000000487611000000000091b61000340000004876110000000000c52d11000b000000d02d110008000000c5b61000190000003db7100010000000d82d11000c0000007365745f6b6579000000000058fe10000300000000000000a7ff10002300000034b610005d000000487611000000000091b61000340000004876110000000000c52d11000b000000d02d110008000000c5b6100019000000deb6100011000000d82d11000c0000002041757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f206b65792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e202d204c696d697465642073746f726167652072656164732e202d204f6e65204442206368616e67652e2041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e202d204e6f204442207772697465732e5375646f00000000000000acb710000300000000000000000000000b2e11000c00000000000000000000000000000000000000000000000000000000000000e88c1100b0b710000000000000000000c0b710000100000000000000010000004b65790032000000000000000100000048000000c8b71000210000002054686520604163636f756e74496460206f6620746865207375646f206b65792e626164206f726967696e3a20657870656374656420746f206265206e6f206f726967696e626164206f726967696e3a20657870656374656420746f206265206120726f6f74206f726967696e626164206f726967696e3a20657870656374656420746f2062652061207369676e6564206f726967696e3a65787472696e7369635f696e64657873746f72616765206973206e6f74206e756c6c2c207468657265666f7265206d75737420626520612076616c696420747970650000c0b8100019000000e0b8100048000000290100000e00000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f6c69622e727340b910000e0000004eb9100048000000280100004a0000006578706c696369742070616e69632f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f6c69622e7273000040b910000e0000004eb9100048000000270100004a00000053797374656d204e756d62657253797374656d2045787472696e73696373526f6f7453797374656d2044696765737453797374656d20426c6f636b4861736853797374656d204163636f756e744e6f6e63650000320000000000000001000000a3000000946a1100280000002cba100041000000e3000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f73797374656d2f7372632f6c69622e72737472616e73616374696f6e20626972746820626c6f636b20616e6369656e7453797374656d20506172656e744861736853797374656d2052616e646f6d4d6174657269616c0000f0ba100048000000960a00000e00000053797374656d204576656e747353797374656d204576656e74546f70696373000000000000000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e72730000000040bc10000a00000000000000487611000000000000000000000000004cbc100001000000000000000000000054bc100006000000000000005cbc100001000000000000000000000074bc10000100000000000000000000007cbc10000e000000000000008cbc1000010000000000000000000000a4bc1000010000000000000000000000acbc10000800000000000000b4bc1000010000000000000000000000ccbc1000010000000000000000000000d4bc10000b00000000000000e0bc1000010000000000000000000000f8bc100001000000000000000000000000bd10000c000000000000000cbd100001000000000000000000000024bd1000010000000000000066696c6c5f626c6f636b0000fbbd10004800000072656d61726b000000000000f4bd1000070000000000000023d1100007000000d9bd10001b0000007365745f686561705f7061676573000000000000d4bd100005000000000000009ae110000300000095bd10003f0000007365745f636f64650000000058fe1000030000000000000023d110000700000083bd1000120000007365745f73746f72616765000000000071bd1000050000000000000076bd10000d00000056bd10001b0000006b696c6c5f73746f72616765000000004abd100004000000000000004ebd1000080000002cbd10001e000000204b696c6c20736f6d65206974656d732066726f6d2073746f726167652e6b6579735665633c4b65793e2053657420736f6d65206974656d73206f662073746f726167652e6974656d735665633c4b657956616c75653e2053657420746865206e657720636f64652e2053657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e7061676573204d616b6520736f6d65206f6e2d636861696e2072656d61726b2e5f72656d61726b20412062696720646973706174636820746861742077696c6c20646973616c6c6f7720616e79206f74686572207472616e73616374696f6e20746f20626520696e636c756465642e53797374656d0000000000000074c310000c00000001010000000000000b2e11000c0000000000000080c310000800000000000000000000000000000000000000e88c110084c51000000000000000000088c310000100000000000000010000000000000090c310000e00000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c1100dcc310000000000000000000a0c3100001000000000000000000000000000000a8c31000130000000000000000000000bbc310000600000000000000000000000000000000000000000000000000000000000000e88c1100dcc310000000000000000000c4c3100001000000000000000000000000000000ccc310001000000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c1100dcc310000000000000000000ecc3100001000000000000000000000000000000f4c3100014000000000000000000000008c410001000000000000000000000000000000000000000000000000000000000000000e88c110018c41000000000000000000028c410000200000000000000010000000000000038c41000090000000101000000000000923111000e000000000000007c2f11000700000000000000000000000000000000000000e88c1100e8c41000000000000000000044c41000010000000000000001000000000000004cc410000d00000001010000000000009ef31000030000000000000023d110000700000000000000000000000000000000000000e88c11005cc4100000000000000000006cc410000100000000000000010000000000000074c410000e000000000000000000000082c410001200000000000000000000000000000000000000000000000000000000000000e88c110094c410000000000000000000a4c4100002000000000000000100000000000000b4c41000060000000000000000000000923111000e00000000000000000000000000000000000000000000000000000000000000e88c110084c510000000000000000000bcc4100001000000000000000100000000000000c4c410000a00000000000000000000007c2f11000700000000000000000000000000000000000000000000000000000000000000e88c1100e8c410000000000000000000d0c4100001000000000000000100000000000000d8c410000e00000000000000000000007c2f11000700000000000000000000000000000000000000000000000000000000000000e88c1100e8c410000000000000000000f8c410000100000000000000010000000000000000c5100006000000000000000000000006c510000b00000000000000000000000000000000000000000000000000000000000000e88c110014c51000000000000000000024c51000010000000000000001000000000000002cc5100006000000000000000000000032c510002300000000000000000000000000000000000000000000000000000000000000e88c110058c51000000000000000000068c510000100000000000000010000000000000070c510000a00000000000000000000007ac510000a00000000000000000000000000000000000000000000000000000000000000e88c110084c51000000000000000000094c51000010000000000000001000000000000009cc510000b0000000201010000000000a7c5100002000000000000007c2f11000700000000000000a9c510002100000000000000e88c1100ccc510000000000000000000dcc510000d00000000000000010000004163636f756e744e6f6e6365543a3a496e64657889cc10001f00000045787472696e736963436f756e7400005bcc10002e000000416c6c45787472696e7369637357656967687457656967687400000016cc100045000000416c6c45787472696e736963734c656e32000000000000000100000040000000c6cb1000500000004e6578745765696768744d756c7469706c6965725765696768744d756c7469706c6965723200000000000000010000004600000052cb100059000000abcb10001b000000426c6f636b486173680000002ccb10002600000045787472696e736963446174610000003200000000000000010000009c000000ddca10004f00000052616e646f6d4d6174657269616c2869382c205665633c543a3a486173683e29320000000000000001000000a500000020ca10006900000089ca1000540000004e756d6265720000dec9100042000000506172656e74486173680000c2c910001c00000045787472696e73696373526f6f740000320000000000000001000000a60000007dc91000450000004469676573744469676573744f663c543e0000003200000000000000010000004200000041c910003c0000004576656e74735665633c4576656e745265636f72643c543a3a4576656e742c20543a3a486173683e3e0000003200000000000000010000004200000019c91000280000004576656e74436f756e744576656e74496e64657832000000000000000100000049000000ebc810002e0000004576656e74546f7069637328295665633c28543a3a426c6f636b4e756d6265722c204576656e74496e646578293e00003200000000000000010000004200000044c61000490000008dc61000250000004876110000000000b2c610004b000000fdc610002a000000487611000000000027c71000540000007bc7100051000000ccc7100039000000487611000000000005c810005300000058c8100053000000abc8100040000000204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e6465786573206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e20546865206669727374206b657920736572766573206e6f20707572706f73652e2054686973206669656c64206973206465636c6172656420617320646f75626c655f6d6170206a75737420666f7220636f6e76656e69656e6365206f66207573696e67206072656d6f76655f707265666978602e20416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e205468697320616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e6420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e205468652076616c756520686173207468652074797065206028543a3a426c6f636b4e756d6265722c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573742074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e20546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e20446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2045787472696e7369637320726f6f74206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2048617368206f66207468652070726576696f757320626c6f636b2e205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e20536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e205468697320697320617272616e67656420617320612072696e6720627566666572207769746820746865206069386020707265666978206265696e672074686520696e64657820696e746f20746865206056656360206f6620746865206f6c6465737420686173682e2045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e20546865206e65787420776569676874206d756c7469706c6965722e20546869732073686f756c6420626520757064617465642061742074686520656e64206f66206561636820626c6f636b206261736564206f6e207468652073617475726174696f6e206c6576656c2028776569676874292e20546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2077656967687420666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e2045787472696e73696373206e6f6e636520666f72206163636f756e74732ec0b8100019000000c0cc100047000000e20000000a0000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7374616b696e672f7372632f70687261676d656e2e72736d656d6f727976616c69646174696f6e3a20696d706f727420656e74727920706f696e747320746f2061206e6f6e2d6578697374656e74207479706543616e6e6f7420696d706f727420676c6f62616c736d6f64756c6520696d706f7274732061206e6f6e2d6578697374656e742066756e6374696f6e6d6f64756c6520696d706f72747320606578745f7072696e746c6e60206275742064656275672066656174757265732064697361626c656443616e6e6f7420696d706f7274207461626c65736d6f64756c652068617320696d706f7274732066726f6d2061206e6f6e2d27656e7627206e616d6573706163654d756c7469706c65206d656d6f727920696d706f72747320646566696e65644d656d6f727920696d706f7274206d757374206861766520746865206669656c64206e616d6520276d656d6f7279274d6178696d756d206e756d626572206f662070616765732073686f756c6420626520616c77617973206465636c617265642e52657175657374656420696e697469616c206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520726571756573746564206d6178696d756d4d6178696d756d206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520636f6e66696775726564206d6178696d756d2e000000f0ba100048000000900a00000a0000002cba100041000000e3000000010000003a6865617070616765733a636f646500000000003cd01000080000000000000044d010000300000000000000000000005cd0100001000000000000000000000064d010000c000000000000009423110002000000000000000000000070d0100001000000000000000000000078d010000a0000000000000084d010000100000000000000000000008cd0100001000000000000000000000094d010000f00000000000000a4d01000010000000000000000000000acd01000010000000000000000000000b4d010000a00000000000000c0d01000020000000000000000000000d0d01000020000000000000000000000e0d010000800000000000000e8d01000020000000000000000000000f8d0100001000000000000005472616e73666572d823110009000000d82311000900000019241100070000002ad2100055000000496e7374616e746961746564f3d1100037000000436f646553746f7265640000e123110004000000c5d110002e0000005363686564756c6555706461746564009ef310000300000095d1100030000000446973706174636865640000d823110009000000ff231100040000002ad110004e00000078d110001d000000436f6e7472616374d82311000900000023d110000700000000d110002300000020416e206576656e742066726f6d20636f6e7472616374206f66206163636f756e742e5665633c75383e20412063616c6c2077617320646973706174636865642066726f6d2074686520676976656e206163636f756e742e2054686520626f6f6c207369676e616c73207768657468657220697420776173207375636365737366756c20657865637574696f6e206f72206e6f742e20547269676765726564207768656e207468652063757272656e74207363686564756c6520697320757064617465642e20436f646520776974682074686520737065636966696564206861736820686173206265656e2073746f7265642e20436f6e7472616374206465706c6f7965642062792061646472657373206174207468652073706563696669656420616464726573732e205472616e736665722068617070656e6564206066726f6d6020746f2060746f60207769746820676976656e206076616c7565602061732070617274206f662061206063616c6c60206f722060637265617465602e64656661756c743a436f6e7472616374205072697374696e65436f6465436f6e747261637420436f646553746f72616765436f6e747261637420436f6e7472616374496e666f4f6600e0d210001900000000d3100048000000bb0100002d000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f6f70732f61726974682e7273707265636f6e646974696f6e3a20616c6c20696d706f7274732073686f756c6420626520636865636b656420616761696e737420746865207369676e617475726573206f6620636f72726573706f6e64696e670a09090909090966756e6374696f6e7320646566696e65642062792060646566696e655f656e762160206d6163726f206279207468652075736572206f6620746865206d6163726f3b0a0909090909097369676e617475726573206f662074686573652066756e6374696f6e7320646566696e6564206279206024706172616d73603b0a09090909090963616c6c7320616c77617973206d616465207769746820617267756d656e7473207479706573206f662077686963682061726520646566696e65642062792074686520636f72726573706f6e64696e6720696d706f7274733b0a09090909090974687573207479706573206f6620617267756d656e74732073686f756c6420626520657175616c20746f2074797065206c69737420696e206024706172616d736020616e640a0909090909096c656e677468206f6620617267756d656e74206c69737420616e642024706172616d732073686f756c6420626520657175616c3b0a0909090909097468757320746869732063616e206e6576657220626520604e6f6e65603b0a0909090909097165643b0a0909090909090000000018d610000f0000000000000028d6100001000000000000000000000040d6100003000000000000000000000058d61000080000000000000060d6100002000000000000000000000090d610000200000000000000000000002d5211000400000000000000a0d6100004000000000000000000000000d7100007000000000000000000000038d71000060000000000000040d71000040000000000000000000000a0d710000a0000000000000000000000f0d710000f0000000000000000d8100002000000000000000000000030d8100005000000000000007570646174655f7363686564756c65000000000076de100008000000000000007ede10000800000006de10002d000000487611000000000033de1000430000007075745f636f646500000000b4db10000900000000000000bddb10000c0000000000000002de1000040000000000000023d110000700000076dd100057000000cddd1000350000000000000072d910000400000000000000a7ff100023000000000000005f3511000500000000000000643511001500000000000000b4db10000900000000000000bddb10000c00000000000000dddb1000040000000000000023d1100007000000e1db100042000000487611000000000023dc10004a0000006ddc10002c00000099dc100046000000dfdc10005200000031dd100045000000637265617465000000000000abdb10000900000000000000643511001500000000000000b4db10000900000000000000bddb10000c00000000000000c9db10000900000000000000d2db10000b00000000000000dddb1000040000000000000023d110000700000094d910006a0000004876110000000000fed910002100000048761100000000001fda1000500000006fda100041000000b0da10005b0000000bdb10005700000062db10002a0000008cdb10001f000000636c61696d5f737572636861726765000000000072d9100004000000000000000b2e11000c0000000000000076d910000a0000000000000080d910001400000058d810005c000000b4d81000450000004876110000000000f9d810004e00000047d910002b00000020416c6c6f777320626c6f636b2070726f64756365727320746f20636c61696d206120736d616c6c2072657761726420666f72206576696374696e67206120636f6e74726163742e204966206120626c6f636b2070726f6475636572206661696c7320746f20646f20736f2c206120726567756c61722075736572732077696c6c20626520616c6c6f77656420746f20636c61696d20746865207265776172642e20496620636f6e7472616374206973206e6f742065766963746564206173206120726573756c74206f6620746869732063616c6c2c206e6f20616374696f6e73206172652074616b656e20616e64207468652073656e646572206973206e6f7420656c696769626c6520666f7220746865207265776172642e646573746175785f73656e6465724f7074696f6e3c543a3a4163636f756e7449643e20437265617465732061206e657720636f6e74726163742066726f6d207468652060636f646568617368602067656e65726174656420627920607075745f636f6465602c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e204372656174696f6e20697320657865637574656420617320666f6c6c6f77733a202d205468652064657374696e6174696f6e206164647265737320697320636f6d7075746564206261736564206f6e207468652073656e64657220616e642068617368206f662074686520636f64652e202d2054686520736d6172742d636f6e7472616374206163636f756e7420697320637265617465642061742074686520636f6d707574656420616464726573732e202d20546865206063746f725f636f64656020697320657865637574656420696e2074686520636f6e74657874206f6620746865206e65776c792d63726561746564206163636f756e742e204275666665722072657475726e656420202061667465722074686520657865637574696f6e206973207361766564206173207468652060636f646560206f6620746865206163636f756e742e205468617420636f64652077696c6c20626520696e766f6b656420202075706f6e20616e792063616c6c2072656365697665642062792074686973206163636f756e742e202d2054686520636f6e747261637420697320696e697469616c697a65642e656e646f776d656e746761735f6c696d6974436f6d706163743c4761733e636f64655f68617368436f6465486173683c543e64617461204d616b657320612063616c6c20746f20616e206163636f756e742c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e202a20496620746865206163636f756e74206973206120736d6172742d636f6e7472616374206163636f756e742c20746865206173736f63696174656420636f64652077696c6c20626520657865637574656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e202a20496620746865206163636f756e74206973206120726567756c6172206163636f756e742c20616e792076616c75652077696c6c206265207472616e736665727265642e202a204966206e6f206163636f756e742065786973747320616e64207468652063616c6c2076616c7565206973206e6f74206c657373207468616e20606578697374656e7469616c5f6465706f736974602c206120726567756c6172206163636f756e742077696c6c206265206372656174656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e2053746f7265732074686520676976656e2062696e617279205761736d20636f646520696e746f2074686520636861696e27732073746f7261676520616e642072657475726e73206974732060636f646568617368602e20596f752063616e20696e7374616e746961746520636f6e747261637473206f6e6c7920776974682073746f72656420636f64652e636f6465205570646174657320746865207363686564756c6520666f72206d65746572696e6720636f6e7472616374732e20546865207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e207468652073746f726564207363686564756c652e7363686564756c655363686564756c65000000000000f0e01000080000000000000000000000f8e010000300000000000000000000000000000000000000000000000000000000000000e88c1100a0e110000000000000000000fce010000100000000000000010000000000000004e110000f00000000000000000000007ede10000800000000000000000000000000000000000000000000000000000000000000e88c110014e11000000000000000000024e11000010000000000000001000000000000002ce110000c0000000101000000000000d2db10000b0000000000000023d110000700000000000000000000000000000000000000e88c110038e11000000000000000000048e110000100000000000000000000000000000050e110000b0000000101000000000000d2db10000b000000000000005be110001600000000000000000000000000000000000000e88c110074e11000000000000000000084e11000010000000000000000000000000000008ce110000e00000000000000000000009ae110000300000000000000000000000000000000000000000000000000000000000000e88c1100a0e110000000000000000000b0e1100001000000000000000100000000000000b8e110000e00000001010000000000000b2e11000c00000000000000c6e110000f00000000000000000000000000000000000000e88c1100d8e110000000000000000000e8e1100001000000000000000000000000000000f0e110000800000000000000000000007a4511000c00000000000000000000000000000000000000000000000000000000000000e88c1100f8e11000000000000000000008e210000100000000000000010000004761735370656e744761730044e310002000000043757272656e745363686564756c6500320000000000000001000000a70000001fe31000250000005072697374696e65436f646532000000000000000100000040000000c6e2100059000000436f646553746f726167657761736d3a3a5072656661625761736d4d6f64756c65000000320000000000000001000000400000006de21000590000004163636f756e74436f756e7465727536340000003200000000000000010000004600000058e2100015000000436f6e7472616374496e666f4f66436f6e7472616374496e666f3c543e000000320000000000000001000000400000002ee210002a0000004761735072696365320000000000000001000000a800000010e210001e00000020546865207072696365206f66206f6e6520756e6974206f66206761732e2054686520636f6465206173736f6369617465642077697468206120676976656e206163636f756e742e20546865207375627472696520636f756e7465722e2041206d617070696e67206265747765656e20616e206f726967696e616c20636f6465206861736820616e6420696e737472756d656e746564207761736d20636f64652c20726561647920666f7220657865637574696f6e2e2041206d617070696e672066726f6d20616e206f726967696e616c20636f6465206861736820746f20746865206f726967696e616c20636f64652c20756e746f756368656420627920696e737472756d656e746174696f6e2e2043757272656e7420636f7374207363686564756c6520666f7220636f6e7472616374732e20476173207370656e7420736f2066617220696e207468697320626c6f636b2e00000000e4e610001300000000000000923111000e00000000000000e88c1100f8e61000000000000000000008e7100004000000000000000000000028e7100010000000000000007a4511000c00000000000000e88c110038e71000000000000000000048e7100001000000000000000000000050e7100011000000000000009ef310000300000000000000e88c110064e71000000000000000000074e7100002000000000000000000000084e710000b000000000000007a4511000c00000000000000e88c110090e710000000000000000000a0e71000010000000000000000000000a8e7100011000000000000007a4511000c00000000000000e88c1100bce710000000000000000000cce7100007000000000000000000000004e810000f000000000000007a4511000c00000000000000e88c110014e81000000000000000000024e8100002000000000000000000000034e810000b000000000000007a4511000c00000000000000e88c1100b0e81000000000000000000040e8100001000000000000000000000048e810000b000000000000007a4511000c00000000000000e88c1100b0e81000000000000000000054e810000100000000000000000000005ce8100012000000000000007a4511000c00000000000000e88c1100b0e81000000000000000000070e8100001000000000000000000000078e8100012000000000000007a4511000c00000000000000e88c11008ce8100000000000000000009ce81000010000000000000000000000a4e810000b000000000000007a4511000c00000000000000e88c1100b0e810000000000000000000c0e81000020000000000000000000000d0e810000b00000000000000f8e010000300000000000000e88c1100fce810000000000000000000dce81000020000000000000000000000ece810000d00000000000000f8e010000300000000000000e88c1100fce8100000000000000000000ce910000200000000000000000000001ce9100008000000000000009ef310000300000000000000e88c110024e91000000000000000000034e9100002000000000000000000000044e910000c000000000000009ef310000300000000000000e88c110050e91000000000000000000060e9100001000000000000000000000068e910000d00000000000000f8e010000300000000000000e88c110078e91000000000000000000088e9100002000000000000005369676e6564436c61696d48616e646963617000320000000000000001000000a900000025ef10003800000048761100000000005def100043000000a0ef10001a000000546f6d6273746f6e654465706f736974320000000000000001000000aa000000f0ee10003500000053746f7261676553697a654f66667365740000003200000000000000010000005d00000077ee10004b000000c2ee10002e00000052656e744279746546656500320000000000000001000000ab0000002aee10004d00000052656e744465706f7369744f6666736574000000320000000000000001000000ac000000b2ec100041000000f3ec100016000000487611000000000009ed10005a00000063ed100056000000b9ed1000530000000cee10001e00000053757263686172676552657761726400320000000000000001000000ad0000005fec10003900000098ec10001a0000005472616e73666572466565003aec1000250000004372656174696f6e4665650013ec1000270000005472616e73616374696f6e426173654665650000dceb1000370000005472616e73616374696f6e4279746546656500003200000000000000010000004500000099eb100043000000436f6e7472616374466565003200000000000000010000004400000047eb10004b00000092eb10000700000043616c6c4261736546656500f2ea10004700000039eb10000e00000043726561746542617365466565000000320000000000000001000000ae000000a1ea100049000000eaea1000080000004d61784465707468320000000000000001000000af0000004cea10004700000093ea10000e0000004d617856616c756553697a65320000000000000001000000b0000000fee910004e000000426c6f636b4761734c696d6974000000320000000000000001000000b100000098e9100049000000e1e910001d00000020546865206d6178696d756d20616d6f756e74206f6620676173207468617420636f756c6420626520657870656e6465642070657220626c6f636b2e204120726561736f6e61626c652064656661756c742076616c75652069732031305f3030305f3030302e20546865206d6178696d756d2073697a65206f6620612073746f726167652076616c756520696e2062797465732e204120726561736f6e61626c652064656661756c74206973203136204b69422e20546865206d6178696d756d206e657374696e67206c6576656c206f6620612063616c6c2f63726561746520737461636b2e204120726561736f6e61626c652064656661756c742076616c7565206973203130302e20546865206261736520666565206368617267656420666f72206372656174696e67206120636f6e74726163742e204120726561736f6e61626c652064656661756c742076616c7565206973203137352e20546865206261736520666565206368617267656420666f722063616c6c696e6720696e746f206120636f6e74726163742e204120726561736f6e61626c652064656661756c742076616c7565206973203133352e205468652066656520726571756972656420746f20637265617465206120636f6e747261637420696e7374616e63652e204120726561736f6e61626c652064656661756c742076616c75652069732032312e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b20746865207065722d6279746520706f7274696f6e2e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b2074686520626173652e205468652066656520726571756972656420746f2063726561746520616e206163636f756e742e205468652066656520726571756972656420746f206d616b652061207472616e736665722e205265776172642074686174206973207265636569766564206279207468652070617274792077686f736520746f75636820686173206c656420746f2072656d6f76616c206f66206120636f6e74726163742e2054686520616d6f756e74206f662066756e6473206120636f6e74726163742073686f756c64206465706f73697420696e206f7264657220746f206f66667365742074686520636f7374206f66206f6e6520627974652e204c6574277320737570706f736520746865206465706f73697420697320312c303030204255202862616c616e636520756e697473292f6279746520616e64207468652072656e7420697320312042552f627974652f6461792c207468656e206120636f6e7472616374207769746820312c3030302c3030302042552074686174207573657320312c303030206279746573206f662073746f7261676520776f756c6420706179206e6f2072656e742e20427574206966207468652062616c616e6365207265647563656420746f203530302c30303020425520616e64207468652073746f7261676520737461796564207468652073616d6520617420312c3030302c207468656e20697420776f756c6420706179203530302042552f6461792e205072696365206f6620612062797465206f662073746f7261676520706572206f6e6520626c6f636b20696e74657276616c2e2053686f756c642062652067726561746572207468616e20302e2053697a65206f66206120636f6e7472616374206174207468652074696d65206f66206372656174696f6e2e205468697320697320612073696d706c652077617920746f20656e73757265207468617420656d70747920636f6e747261637473206576656e7475616c6c7920676574732064656c657465642e20546865206d696e696d756d20616d6f756e7420726571756972656420746f2067656e6572617465206120746f6d6273746f6e652e204e756d626572206f6620626c6f636b2064656c617920616e2065787472696e73696320636c61696d20737572636861726765206861732e205768656e20636c61696d207375726368617267652069732063616c6c656420627920616e2065787472696e736963207468652072656e7420697320636865636b656420666f722063757272656e745f626c6f636b202d2064656c617972657475726e2074797065206572726f7276616c69646174696f6e206572726f72647572696e6720657865637574696f6e70726576696f75732f6e657874206f6e6c7920636f6e7461696e206578697374696e6720656e74697265733b20776520656e756d6572617465207573696e67206e6578743b20656e747279206578697374733b207165640000946a1100280000005cf0100044000000b7010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f6c69622e72735cf0100044000000b7010000010000006e6577207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e2063757272656e74496e76616c69642073757263686172676520636c61696d3a206f726967696e206d757374206265207369676e6564206f7220696e686572656e7420616e6420617578696c696172792073656e646572206f6e6c792070726f7669646564206f6e20696e686572656e7443616e6e6f7420726573746f726520746f20696e6578697374696e67206f7220616c69766520636f6e7472616374436f6e7472616374204761735072696365626c6f636b2073697a65206c696d697420697320726561636865646f766572666c6f77206d756c7469706c79696e6720676173206c696d6974206279207072696365000000000054f2100006000000000000005cf2100001000000000000000000000064f210000100000000000000000000006cf210000e000000000000007cf210000200000000000000000000008cf210000200000000000000000000009cf210000c00000000000000a8f21000020000000000000000000000b8f21000010000000000000052657761726400001924110007000000a1f31000380000004f66666c696e655761726e696e670000d8231100090000009ef310000300000009f31000520000005bf31000430000004f66666c696e65536c617368d8231100090000001924110007000000c0f2100049000000204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20676976656e20616e206f66666c696e652d7761726e696e6720286974206973207374696c6c2077697468696e20697473206772616365292e205468652061636372756564206e756d626572206f6620736c6173686573206973207265636f726465642c20746f6f2e75333220416c6c2076616c696461746f72732068617665206265656e2072657761726465642062792074686520676976656e2062616c616e63652e5374616b696e6720426f6e6465645374616b696e672043757272656e7445726153746172745374616b696e67204e6f6d696e61746f72735374616b696e672056616c696461746f72735374616b696e67205374616b6572735374616b696e67204c65646765725374616b696e672050617965655374616b696e6720536c617368436f756e7468656164206f66205374616b696e67204e6f6d696e61746f727368656164206f66205374616b696e672056616c696461746f72735374616b696e672043757272656e74456c65637465640000000010f71000040000000000000014f710000300000000000000000000005cf710000f0000000000000000000000d4f710000a00000000000000e0f71000010000000000000000000000f8f710000e000000000000000000000068f81000060000000000000070f8100001000000000000000000000088f8100017000000000000000000000040f9100011000000000000004876110000000000000000000000000054f91000100000000000000000000000d4f910000800000000000000dcf91000010000000000000000000000f4f910000b00000000000000000000004cfa1000080000000000000054fa10000100000000000000000000006cfa10000b0000000000000000000000c4fa1000050000000000000048761100000000000000000000000000ccfa10000b000000000000000000000024fb1000090000000000000030fb100001000000000000000000000048fb10000b0000000000000000000000a0fb10000e00000000000000b0fb1000010000000000000000000000c8fb10000b000000000000000000000020fc1000130000000000000034fc10000100000000000000000000004cfc100001000000000000000000000054fc10000d000000000000004876110000000000000000000000000064fc10000500000000000000000000008cfc10000d00000000000000487611000000000000000000000000009cfc1000060000000000000000000000ccfc1000170000000000000034fc1000010000000000000000000000e4fc1000010000000000000000000000ecfc1000110000000000000000fd100001000000000000000000000018fd10000100000000000000626f6e64000000009dff10000a00000000000000a7ff100023000000000000005f35110005000000000000006435110015000000000000004d00110005000000000000005200110011000000370911005900000090091100210000004876110000000000b1091100540000004876110000000000050a1100490000004876110000000000c52d11000b0000004e0a110035000000d02d110008000000830a11001a00000048761100000000009d0a11005b000000f80a110049000000d82d11000c000000626f6e645f6578747261000000000000290911000e00000000000000643511001500000003081100590000005c0811000d00000048761100000000006908110054000000bd0811005900000016091100130000004876110000000000b6fe1000550000004876110000000000c52d11000b0000000bff10003a000000d02d1100080000001d35110010000000d82d11000c000000756e626f6e640000000000005f3511000500000000000000643511001500000024041100550000007904110040000000b90411004d0000004876110000000000060511005200000058051100300000004876110000000000880511004f000000d70511004f000000260611003f0000004876110000000000f8ff100055000000487611000000000065061100260000004876110000000000c52d11000b0000008b0611005000000045ff100026000000db06110059000000340711005c00000090071100690000001d35110010000000f90711000a00000077697468647261775f756e626f6e6465640000001d0211004b0000004876110000000000680211004d000000b5021100130000004876110000000000f8ff1000550000004876110000000000c80211001b0000004876110000000000c52d11000b000000e3021100550000003803110051000000890311003d000000c60311005e0000006bff100032000000d82d11000c00000076616c696461746500000000fc0111000500000000000000010211001c000000c20111003a00000048761100000000007ffe1000370000004876110000000000f8ff1000550000004876110000000000c52d11000b0000000bff10003a00000045ff1000260000006bff100032000000d82d11000c0000006e6f6d696e617465000000009301110007000000000000009a01110028000000aa0011004400000048761100000000007ffe1000370000004876110000000000f8ff1000550000004876110000000000c52d11000b000000ee0011004900000037011100260000005d01110036000000d82d11000c0000006368696c6c000000630011003200000048761100000000007ffe1000370000004876110000000000f8ff1000550000004876110000000000c52d11000b0000000bff10003a00000095001100150000006bff100032000000d82d11000c0000007365745f7061796565000000000000004d00110005000000000000005200110011000000caff10002e00000048761100000000007ffe1000370000004876110000000000f8ff1000550000004876110000000000c52d11000b0000000bff10003a00000045ff1000260000006bff100032000000d82d11000c0000007365745f636f6e74726f6c6c65720000000000009dff10000a00000000000000a7ff1000230000005bfe10002400000048761100000000007ffe1000370000004876110000000000b6fe1000550000004876110000000000c52d11000b0000000bff10003a00000045ff1000260000006bff100032000000d82d11000c0000007365745f76616c696461746f725f636f756e74000000000058fe10000300000000000000fa2e11000c00000038fe100020000000666f7263655f6e6f5f657261730000000cfe10002c0000004876110000000000c52d11000b000000fcfd100010000000d82d11000c000000666f7263655f6e65775f65726100000081fd100053000000d4fd1000280000004876110000000000c52d11000b000000fcfd100010000000d82d11000c0000007365745f6f66666c696e655f736c6173685f6772616365005dfd1000240000007365745f696e76756c6e657261626c65730000000000000053fd10000a00000000000000253c11001100000020fd10003300000020536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e76616c696461746f72732053657420746865206f66666c696e6520736c61736820677261636520706572696f642e20466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c20626520726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e202d204e6f20617267756d656e74732e20466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e2054686520696465616c206e756d626572206f662076616c696461746f72732e6e6577202852652d297365742074686520636f6e74726f6c6c6572206f6620612073746173682e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e202d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732e202d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e636f6e74726f6c6c65723c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f75726365202852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e706179656552657761726444657374696e6174696f6e204465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e202d20436f6e7461696e73206f6e6520726561642e204465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e202d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f66206074617267657473602c2077686963682069732063617070656420617420604d41585f4e4f4d494e4154494f4e53602e202d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e746172676574735665633c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263653e204465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e707265667356616c696461746f7250726566733c42616c616e63654f663c543e3e2052656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e205468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722069742077616e74732e2053656520616c736f205b6043616c6c3a3a756e626f6e64605d2e202d20436f756c6420626520646570656e64656e74206f6e2074686520606f726967696e6020617267756d656e7420616e6420686f77206d7563682060756e6c6f636b696e6760206368756e6b732065786973742e2020497420696d706c6965732060636f6e736f6c69646174655f756e6c6f636b656460207768696368206c6f6f7073206f76657220604c65646765722e756e6c6f636b696e67602c2077686963682069732020696e6469726563746c7920757365722d636f6e74726f6c6c65642e20536565205b60756e626f6e64605d20666f72206d6f72652064657461696c2e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732c20796574207468652073697a65206f6620776869636820636f756c64206265206c61726765206261736564206f6e20606c6564676572602e205363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e6420706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e20543a3a43757272656e63793a3a6578697374656e7469616c5f6465706f73697428292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e204f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665207468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e204e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d41585f554e4c4f434b494e475f4348554e4b5360292063616e20636f2d657869737473206174207468652073616d652074696d652e20496e207468617420636173652c205b6043616c6c3a3a77697468647261775f756e626f6e646564605d206e65656420746f2062652063616c6c656420666972737420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e2053656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204c696d697465642062757420706f74656e7469616c6c79206578706c6f697461626c6520636f6d706c65786974792e202d20456163682063616c6c20287265717569726573207468652072656d61696e646572206f662074686520626f6e6465642062616c616e636520746f2062652061626f766520606d696e696d756d5f62616c616e6365602920202077696c6c2063617573652061206e657720656e74727920746f20626520696e73657274656420696e746f206120766563746f722028604c65646765722e756e6c6f636b696e676029206b65707420696e2073746f726167652e202020546865206f6e6c792077617920746f20636c65616e207468652061666f72656d656e74696f6e65642073746f72616765206974656d20697320616c736f20757365722d636f6e74726f6c6c656420766961206077697468647261775f756e626f6e646564602e203c2f7765696768743e2041646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757020666f72207374616b696e672e20557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e20556e6c696b65205b60626f6e64605d206f72205b60756e626f6e64605d20746869732066756e6374696f6e20646f6573206e6f7420696d706f736520616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e6d61785f6164646974696f6e616c2054616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c20626520746865206163636f756e74207468617420636f6e74726f6c732069742e206076616c756560206d757374206265206d6f7265207468616e2074686520606578697374656e7469616c5f6465706f7369746020646566696e656420696e207468652042616c616e636573206d6f64756c652e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e202d20546872656520657874726120444220656e74726965732e204e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e656420756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20616e6420676574732072656d6f76656420617320647573742e5374616b696e6700000000801211000e00000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c11003815110000000000000000009012110001000000000000000100000000000000981211001500000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c1100b01211000000000000000000c0121100010000000000000001000000000000009cf210000c0000000000000000000000c81211000700000000000000000000000000000000000000000000000000000000000000e88c1100d01211000000000000000000e012110001000000000000000100000000000000e81211001100000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c1100381511000000000000000000fc12110001000000000000000100000000000000041311000d0000000000000000000000253c11001100000000000000000000000000000000000000000000000000000000000000e88c1100f0151100000000000000000014131100030000000000000001000000000000002c1311000600000001010000000000000b2e11000c000000000000000b2e11000c00000000000000000000000000000000000000e88c11006c131100000000000000000034131100010000000000000000000000000000003c1311000600000001010000000000000b2e11000c00000000000000421311002900000000000000000000000000000000000000e88c11006c13110000000000000000007c13110001000000000000000000000000000000841311000500000001010000000000000b2e11000c00000000000000520011001100000000000000000000000000000000000000e88c11008c13110000000000000000009c13110001000000000000000100000000000000a41311000a00000001010100000000000b2e11000c00000000000000010211001c00000000000000000000000000000000000000e88c1100b01311000000000000000000c013110001000000000000000100000000000000c81311000a00000001010100000000000b2e11000c00000000000000253c11001100000000000000000000000000000000000000e88c1100f01511000000000000000000d413110001000000000000000100000000000000dc1311000700000001010000000000000b2e11000c00000000000000e31311002400000000000000000000000000000000000000e88c11000814110000000000000000001814110004000000000000000100000000000000381411000e0000000000000000000000253c11001100000000000000000000000000000000000000000000000000000000000000e88c1100f015110000000000000000004814110001000000000000000100000000000000501411000a00000000000000000000005a1411000800000000000000000000000000000000000000000000000000000000000000e88c110038151100000000000000000064141100010000000000000001000000000000006c1411000f00000000000000000000007b1411000b00000000000000000000000000000000000000000000000000000000000000e88c11008814110000000000000000009814110001000000000000000100000000000000a01411001b0000000000000000000000b77011000c00000000000000000000000000000000000000000000000000000000000000e88c1100381511000000000000000000bc14110001000000000000000100000000000000c4141100110000000000000000000000d51411000a00000000000000000000000000000000000000000000000000000000000000e88c1100e01411000000000000000000f014110001000000000000000100000000000000f81411000900000000000000000000007a4511000c00000000000000000000000000000000000000000000000000000000000000e88c110004151100000000000000000014151100030000000000000001000000000000002c1511000a00000001010000000000000b2e11000c000000000000009ef310000300000000000000000000000000000000000000e88c11003815110000000000000000004815110002000000000000000100000000000000581511000f0000000000000000000000671511002800000000000000000000000000000000000000000000000000000000000000e88c1100f015110000000000000000009015110002000000000000000100000000000000a0151100080000000000000000000000a81511000700000000000000000000000000000000000000000000000000000000000000e88c1100b01511000000000000000000c015110001000000000000000100000000000000c81511000a0000000000000000000000d21511001d00000000000000000000000000000000000000000000000000000000000000e88c1100f015110000000000000000000016110001000000000000000100000056616c696461746f72436f756e740000e61c11002a0000004d696e696d756d56616c696461746f72436f756e74000000320000000000000001000000b2000000961c11005000000050657262696c6c00320000000000000001000000b3000000421c1100540000004f66666c696e65536c6173684772616365000000f41b11004e000000496e76756c6e657261626c6573000000201b110056000000761b110053000000c91b11002b000000426f6e6465640000e01a1100400000004c65646765725374616b696e674c65646765723c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e00320000000000000001000000400000008f1a110051000000506179656500000032000000000000000100000040000000561a11003900000056616c696461746f72730000320000000000000001000000b4000000051a1100510000004e6f6d696e61746f72730000ac191100590000005374616b6572734578706f737572653c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e00320000000000000001000000b5000000ef1811005300000042191100460000004876110000000000881911002400000043757272656e74456c65637465640000b01811003f00000043757272656e74457261457261496e6465780000991811001700000043757272656e7445726153746172744d6f6d656e744f663c543e0000320000000000000001000000460000007b1811001e00000043757272656e74457261537461727453657373696f6e496e64657800471811003400000043757272656e74457261526577617264734572615265776172647300320000000000000001000000b60000000418110043000000536c6f745374616b6500000032000000000000000100000041000000881711004c0000004876110000000000d417110030000000536c617368436f756e7400003200000000000000010000004900000014171100570000006b1711001d000000526563656e746c794f66666c696e655665633c28543a3a4163636f756e7449642c20543a3a426c6f636b4e756d6265722c20753332293e009816110055000000ed16110027000000466f726365457261466f7263696e6700320000000000000001000000400000005116110047000000426f6e646564457261735665633c28457261496e6465782c2053657373696f6e496e646578293e003200000000000000010000004200000008161100490000002041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e205472756520696620746865206e6578742073657373696f6e206368616e67652077696c6c2062652061206e657720657261207265676172646c657373206f6620696e6465782e204d6f737420726563656e742060524543454e545f4f46464c494e455f434f554e546020696e7374616e6365732e202857686f206974207761732c207768656e20697420776173207265706f727465642c20686f77206d616e7920696e7374616e63657320746865792077657265206f66666c696e6520666f72292e20546865206e756d626572206f662074696d6573206120676976656e2076616c696461746f7220686173206265656e207265706f72746564206f66666c696e652e205468697320676574732064656372656d656e746564206279206f6e652065616368206572612074686174207061737365732e2054686520616d6f756e74206f662062616c616e6365206163746976656c79206174207374616b6520666f7220656163682076616c696461746f7220736c6f742c2063757272656e746c792e2054686973206973207573656420746f20646572697665207265776172647320616e642070756e6973686d656e74732e205265776172647320666f72207468652063757272656e74206572612e205573696e6720696e6469636573206f662063757272656e7420656c6563746564207365742e205468652073657373696f6e20696e646578206174207768696368207468652063757272656e742065726120737461727465642e20546865207374617274206f66207468652063757272656e74206572612e205468652063757272656e742065726120696e6465782e205468652063757272656e746c7920656c65637465642076616c696461746f7220736574206b65796564206279207374617368206163636f756e742049442e204e6f6d696e61746f727320666f72206120706172746963756c6172206163636f756e74207468617420697320696e20616374696f6e207269676874206e6f772e20596f752063616e27742069746572617465207468726f7567682076616c696461746f727320686572652c2062757420796f752063616e2066696e64207468656d20696e207468652053657373696f6e206d6f64756c652e2054686973206973206b6579656420627920746865207374617368206163636f756e742e20546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f2074686520736574206f66207374617368206b657973206f6620616c6c2076616c696461746f727320746f206e6f6d696e6174652e20546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e2057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e20416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e63652074686579277265206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f757220696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e204e756d626572206f6620696e7374616e636573206f66206f66666c696e65207265706f727473206265666f726520736c617368696e6720626567696e7320666f722076616c696461746f72732e20536c6173682c207065722076616c696461746f7220746861742069732074616b656e20666f72207468652066697273742074696d6520746865792061726520666f756e6420746f206265206f66666c696e652e204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e2054686520696465616c206e756d626572206f66207374616b696e67207061727469636970616e74732e00000000801d11000e00000000000000b77011000c00000000000000e88c1100901d11000000000000000000a01d1100010000000000000000000000a81d11000f000000000000005a1411000800000000000000e88c1100b81d11000000000000000000c81d1100010000000000000053657373696f6e73506572457261000032000000000000000100000059000000091e11001c000000426f6e64696e674475726174696f6e00320000000000000001000000b7000000d01d110039000000204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e204e756d626572206f662073657373696f6e7320706572206572612e5374616b696e6720536c6f745374616b650000501f110019000000701f110048000000bb0100002d000000b80000002800000004000000b9000000ba0000000000000000000000bb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f6f70732f61726974682e7273946a110028000000d01f110042000000bb020000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7374616b696e672f7372632f6c69622e72730000d01f110042000000bb02000001000000636f6e74726f6c6c657220616c72656164792070616972656463616e206e6f7420626f6e6420776974682076616c7565206c657373207468616e206d696e696d756d2062616c616e6365737461736820616c726561647920626f6e6465646e6f74206120636f6e74726f6c6c65726e6f74206120737461736863616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b73756e7374616b65207468726573686f6c6420746f6f206c61726765746172676574732063616e6e6f7420626520656d7074795374616b696e6720496e76756c6e657261626c65730000000000ec2211000800000000000000f4221100020000000000000000000000487611000000000000000000000000000423110006000000000000000c23110003000000000000000000000048761100000000000000000000000000242311000e0000000000000048761100000000000000000000000000487611000000000000000000000000003223110007000000000000003c231100020000000000000000000000487611000000000000000000000000004c231100060000000000000054231100010000000000000000000000487611000000000000000000000000005c2311000900000000000000542311000100000000000000000000004876110000000000000000000000000065231100090000000000000054231100010000000000000000000000487611000000000000000000000000006e231100080000000000000078231100020000000000000000000000487611000000000000000000000000008823110009000000000000009423110002000000000000000000000048761100000000000000000000000000a42311000b00000000000000b023110001000000000000000000000048761100000000000000000000000000b82311000600000000000000c023110003000000000000000000000048761100000000000000000050726f706f736564102411000900000019241100070000005461626c6564000010241100090000001924110007000000202411000e00000045787465726e616c5461626c656453746172746564000000f02311000f000000032411000d0000005061737365640000f02311000f0000004e6f7450617373656443616e63656c6c656445786563757465640000f02311000f000000ff2311000400000044656c656761746564000000d823110009000000d823110009000000556e64656c65676174656400d8231100090000005665746f65640000d823110009000000e123110004000000e52311000b0000004163636f756e74496448617368426c6f636b4e756d6265725265666572656e64756d496e646578626f6f6c566f74655468726573686f6c6450726f70496e64657842616c616e63655665633c4163636f756e7449643e44656d6f637261637920566f74654f6644656d6f63726163792044656c65676174696f6e7344656d6f6372616379205265666572656e64756d496e666f4f6644656d6f6372616379204465706f7369744f6644656d6f6372616379204469737061746368517565756544656d6f637261637920566f74657273466f7268656164206f662044656d6f63726163792044656c65676174696f6e7344656d6f6372616379205075626c696350726f70735025110048000000960a00000e0000004e6f207075626c69632070726f706f73616c732077616974696e6743616e6e6f7420696e6a6563742061207265666572656e64756d207468617420656e6473206561726c696572207468616e2070726563656564696e67207265666572656e64756d00002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e727344656d6f6372616379204e65787445787465726e616c4e6f2065787465726e616c2070726f706f73616c2077616974696e67000000000000b82811000700000000000000c0281100020000000000000000000000f0281100060000000000000000000000202911000600000000000000282911000100000000000000000000004029110006000000000000000000000070291100040000000000000074291100020000000000000000000000a4291100070000000000000000000000dc2911000a0000000000000074291100020000000000000000000000e8291100070000000000000000000000202a11001000000000000000302a1100010000000000000000000000482a1100020000000000000000000000582a11001000000000000000682a1100010000000000000000000000802a1100020000000000000000000000902a11001900000000000000682a1100010000000000000000000000ac2a1100050000000000000000000000d42a11001800000000000000682a1100010000000000000000000000ec2a1100050000000000000000000000142b11000a00000000000000202b1100030000000000000000000000682b1100080000000000000000000000a82b11000d00000000000000b82b1100010000000000000000000000d02b1100010000000000000000000000d82b11001100000000000000ec2b1100010000000000000000000000042c11000100000000000000000000000c2c11000d000000000000001c2c1100030000000000000000000000642c11000100000000000000000000006c2c11000900000000000000782c1100010000000000000000000000902c1100050000000000000000000000b82c11000c0000000000000048761100000000000000000000000000c42c1100050000000000000000000000ec2c11000c00000000000000782c1100010000000000000000000000f82c1100050000000000000000000000202d11000800000000000000282d1100020000000000000000000000582d1100050000000000000000000000802d11000a00000000000000487611000000000000000000000000008c2d1100050000000000000070726f706f736500000000005833110008000000000000006033110010000000000000005f35110005000000000000006435110015000000f5341100280000004876110000000000c52d11000b000000d02d1100080000003f35110020000000d82d11000c0000007365636f6e640000000000005833110008000000000000002d35110012000000f5341100280000004876110000000000c52d11000b000000d02d1100080000001d35110010000000d82d11000c000000766f746500000000372f110009000000000000000a2f11001800000000000000702911000400000000000000f134110004000000753411004d000000c23411002f0000004876110000000000c52d11000b000000d02d110008000000563411001f000000d82d11000c00000070726f78795f766f74650000c433110054000000183411003e0000004876110000000000c52d11000b000000d02d110008000000563411001f000000d82d11000c000000656d657267656e63795f63616e63656c00000000372f11000900000000000000f02311000f00000070331100540000004c3311000c00000065787465726e616c5f70726f706f7365000000005833110008000000000000006033110010000000003311004c0000004c3311000c00000065787465726e616c5f70726f706f73655f6d616a6f726974790000009232110056000000e832110018000000487611000000000018321100530000006b3211002700000065787465726e616c5f70726f706f73655f64656661756c74a531110052000000f731110021000000487611000000000018321100530000006b32110027000000666173745f747261636b0000000000006f2f11000d000000000000007c2f11000700000000000000853111000d00000000000000923111000e00000000000000a03111000500000000000000923111000e000000832f110054000000d72f110059000000303011003b00000048761100000000006b3011003e000000a93011004b000000f430110055000000493111003c0000007665746f5f65787465726e616c000000000000006f2f11000d000000000000007c2f110007000000402f11002f00000063616e63656c5f7265666572656e64756d00000000000000372f110009000000000000000a2f110018000000222f11001500000063616e63656c5f71756575656400000000000000da2e11000400000000000000de2e11001700000000000000f52e11000500000000000000fa2e11000c00000000000000062f110004000000000000000a2f110018000000b22e1100280000007365745f70726f787900000000000000ad2e110005000000000000000b2e11000c000000872e1100260000004876110000000000c52d11000b000000f32d110016000000d82d11000c00000072657369676e5f70726f7879612e1100260000004876110000000000c52d11000b000000512e110010000000d82d11000c00000072656d6f76655f70726f78792b2e1100260000004876110000000000c52d11000b000000512e110010000000d82d11000c00000064656c656761746500000000092e110002000000000000000b2e11000c00000000000000172e11000a00000000000000212e11000a000000e42d11000f0000004876110000000000c52d11000b000000f32d110016000000d82d11000c000000756e64656c65676174650000b42d1100110000004876110000000000c52d11000b000000d02d110008000000d82d11000c00000020556e64656c656761746520766f74652e2023203c7765696768743e202d204f2831292e2023203c2f7765696768743e2044656c656761746520766f74652e202d204f6e6520657874726120444220656e7472792e746f543a3a4163636f756e744964636f6e76696374696f6e436f6e76696374696f6e20436c656172207468652070726f78792e2043616c6c6564206279207468652073746173682e202d204f6e6520444220636c6561722e20436c656172207468652070726f78792e2043616c6c6564206279207468652070726f78792e205370656369667920612070726f78792e2043616c6c6564206279207468652073746173682e70726f78792043616e63656c20612070726f706f73616c2071756575656420666f7220656e6163746d656e742e7768656e436f6d706163743c543a3a426c6f636b4e756d6265723e7768696368436f6d706163743c7533323e77686174436f6d706163743c5265666572656e64756d496e6465783e2052656d6f76652061207265666572656e64756d2e7265665f696e646578205665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e70726f706f73616c5f68617368543a3a48617368205363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c656420696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e6520627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e202d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e202d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265202020656e61637465642e20496e6372656173656420746f2060456d657267656e6379566f74696e67506572696f646020696620746f6f206c6f772e766f74696e675f706572696f64543a3a426c6f636b4e756d62657264656c6179205363686564756c652061206e656761746976652d7475726e6f75742d62696173207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061207072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e205363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e205363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e70726f706f73616c426f783c543a3a50726f706f73616c3e205363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d6520566f746520696e2061207265666572656e64756d206f6e20626568616c66206f6620612073746173682e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b20206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e202d204f6e65204442206368616e67652c206f6e6520444220656e7472792e20566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e566f74652050726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e202d204f6e6520444220656e7472792e436f6d706163743c50726f70496e6465783e202d2054776f204442206368616e6765732c206f6e6520444220656e7472792e76616c7565436f6d706163743c42616c616e63654f663c543e3e44656d6f6372616379000000000000ac3a11000f0000000000000000000000102411000900000000000000000000000000000000000000000000000000000000000000e88c11006c3b11000000000000000000bc3a110001000000000000000100000000000000c43a11000b0000000000000000000000cf3a11002b00000000000000000000000000000000000000000000000000000000000000e88c1100383c11000000000000000000fc3a110001000000000000000100000000000000043b11000900000001010000000000001024110009000000000000000d3b11002100000000000000000000000000000000000000e88c1100303b11000000000000000000403b110001000000000000000000000000000000483b11000f0000000000000000000000f02311000f00000000000000000000000000000000000000000000000000000000000000e88c11006c3b11000000000000000000583b110001000000000000000100000000000000603b1100090000000000000000000000f02311000f00000000000000000000000000000000000000000000000000000000000000e88c11006c3b110000000000000000007c3b110001000000000000000100000000000000843b1100100000000101000000000000f02311000f00000000000000943b11002d00000000000000000000000000000000000000e88c1100b03c11000000000000000000c43b110001000000000000000000000000000000cc3b11000d0000000101000000000000923111000e00000000000000d93b11002b00000000000000000000000000000000000000e88c1100043c11000000000000000000143c1100010000000000000001000000000000001c3c1100090000000101000000000000f02311000f00000000000000253c11001100000000000000000000000000000000000000e88c1100383c11000000000000000000483c110001000000000000000100000000000000503c1100060000000101000000000000563c11001f00000000000000f13411000400000000000000000000000000000000000000e88c1100783c11000000000000000000883c110004000000000000000100000000000000a83c11000500000001010000000000000b2e11000c000000000000000b2e11000c00000000000000000000000000000000000000e88c1100b03c11000000000000000000c03c110002000000000000000000000000000000d03c11000b00000001010100000000000b2e11000c00000000000000db3c11001a00000000000000000000000000000000000000e88c1100f83c11000000000000000000083d110001000000000000000100000000000000103d1100150000000000000000000000ff2311000400000000000000000000000000000000000000000000000000000000000000e88c1100ec3d11000000000000000000283d110002000000000000000100000000000000383d11000c0000000000000000000000443d11001c00000000000000000000000000000000000000000000000000000000000000e88c1100603d11000000000000000000703d110004000000000000000000000000000000903d11000900000001010000000000007c2f11000700000000000000993d11002300000000000000000000000000000000000000e88c1100bc3d11000000000000000000cc3d110002000000000000000000000000000000dc3d11000d00000001010000000000007c2f11000700000000000000ff2311000400000000000000000000000000000000000000e88c1100ec3d11000000000000000000fc3d11000100000000000000010000005075626c696350726f70436f756e74006c4311003d0000005075626c696350726f70735665633c2850726f70496e6465782c20543a3a50726f706f73616c2c20543a3a4163636f756e744964293e00004c431100200000004465706f7369744f662842616c616e63654f663c543e2c205665633c543a3a4163636f756e7449643e290000320000000000000001000000560000002b431100210000005265666572656e64756d436f756e7400df4211004c0000004e65787454616c6c7900000032000000000000000100000049000000ad421100320000005265666572656e64756d496e666f4f66285265666572656e64756d496e666f3c543a3a426c6f636b4e756d6265722c20543a3a50726f706f73616c3e29000000804211002d000000446973706174636851756575655665633c4f7074696f6e3c28543a3a50726f706f73616c2c205265666572656e64756d496e646578293e3e320000000000000001000000420000005042110030000000566f74657273466f725665633c543a3a4163636f756e7449643e0000320000000000000001000000420000002742110029000000566f74654f66285265666572656e64756d496e6465782c20543a3a4163636f756e7449642900000032000000000000000100000040000000e84011005800000040411100530000009341110057000000ea4111003d00000050726f7879000000320000000000000001000000400000007a4011004c000000c64011002200000044656c65676174696f6e7328543a3a4163636f756e7449642c20436f6e76696374696f6e29000000320000000000000001000000bc0000002a401100500000004c6173745461626c656457617345787465726e616c000000ca3f110056000000204011000a0000004e65787445787465726e616c28543a3a50726f706f73616c2c20566f74655468726573686f6c6429320000000000000001000000bd000000dc3e110056000000323f110055000000873f110029000000b03f11001a000000426c61636b6c69737428543a3a426c6f636b4e756d6265722c205665633c543a3a4163636f756e7449643e29320000000000000001000000560000004e3e110054000000a23e11003a00000043616e63656c6c6174696f6e7300000032000000000000000100000040000000043e11004a000000205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e2041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d6265722028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e20546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e20546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743a202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f72202d20605075626c696350726f70736020697320656d7074792e205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c69632070726f706f73616c2e2047657420746865206163636f756e742028616e64206c6f636b20706572696f64732920746f20776869636820616e6f74686572206163636f756e742069732064656c65676174696e6720766f74652e2057686f2069732061626c6520746f20766f746520666f722077686f6d2e2056616c7565206973207468652066756e642d686f6c64696e67206163636f756e742c206b65792069732074686520766f74652d7472616e73616374696f6e2d73656e64696e67206163636f756e742e204765742074686520766f746520696e206120676976656e207265666572656e64756d206f66206120706172746963756c617220766f7465722e2054686520726573756c74206973206d65616e696e6766756c206f6e6c792069662060766f746572735f666f726020696e636c756465732074686520766f746572207768656e2063616c6c6564207769746820746865207265666572656e64756d2028796f75276c6c20676574207468652064656661756c742060566f7465602076616c7565206f7468657277697365292e20496620796f7520646f6e27742077616e7420746f20636865636b2060766f746572735f666f72602c207468656e20796f752063616e20616c736f20636865636b20666f722073696d706c65206578697374656e636520776974682060566f74654f663a3a657869737473602066697273742e204765742074686520766f7465727320666f72207468652063757272656e742070726f706f73616c2e205175657565206f66207375636365737366756c207265666572656e646120746f20626520646973706174636865642e20496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e20546865206e657874207265666572656e64756d20696e64657820746861742073686f756c642062652074616c6c6965642e20546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e2054686f73652077686f2068617665206c6f636b65642061206465706f7369742e20546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e00000000000000fc4411000f00000000000000923111000e00000000000000e88c11000c45110000000000000000001c451100050000000000000000000000444511000c00000000000000923111000e00000000000000e88c1100e0451100000000000000000050451100010000000000000000000000584511000c00000000000000923111000e00000000000000e88c1100e04511000000000000000000644511000100000000000000000000006c4511000e000000000000007a4511000c00000000000000e88c110088451100000000000000000098451100010000000000000000000000a04511001500000000000000923111000e00000000000000e88c1100b84511000000000000000000c8451100010000000000000000000000d04511000d00000000000000923111000e00000000000000e88c1100e04511000000000000000000f04511000100000000000000456e6163746d656e74506572696f6400320000000000000001000000be0000003f4711005c00000048761100000000009b4711004c000000e74711005a00000041481100270000004c61756e6368506572696f640647110039000000566f74696e67506572696f64d84611002e0000004d696e696d756d4465706f73697442616c616e63654f663c543e0000320000000000000001000000bf0000008b4611004d000000456d657267656e6379566f74696e67506572696f64000000320000000000000001000000c0000000504611003b000000436f6f6c6f6666506572696f64000000320000000000000001000000c1000000f84511005800000020506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f7220616e20656d657267656e6379207265666572656e64756d2e20546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e20486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e20546865206d696e696d756d20706572696f64206f66206c6f636b696e6720616e642074686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e2049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e73757265207468617420766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652e946a110028000000804811004400000054010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f64656d6f63726163792f7372632f6c69622e7273f54b110023000000cb4b11002a0000008048110044000000540100000100000076616c756520746f6f206c6f7770726f706f73657227732062616c616e636520746f6f206c6f7763616e206f6e6c79207365636f6e6420616e206578697374696e672070726f706f73616c7365636f6e64657227732062616c616e636520746f6f206c6f776e6f7420612070726f787944656d6f63726163792043616e63656c6c6174696f6e7370726f706f73616c207374696c6c20626c61636b6c697374656470726f706f73616c20616c7265616479206d616465696e76616c696420686173686e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974796e6f2070726f706f73616c206d61646544656d6f637261637920426c61636b6c6973746e6f2065787465726e616c2070726f706f73616c756e6b6e6f776e2070726f706f73616c6964656e74697479206d6179206e6f74207665746f20612070726f706f73616c20747769636544656d6f63726163792050726f7879616c726561647920612070726f787977726f6e672070726f78790a09090909090909096865616420697320736574207768656e20666972737420656c656d656e7420697320696e73657274656420616e6420756e736574207768656e206c61737420656c656d656e742069732072656d6f7665643b0a09090909090909096966206865616420697320536f6d65207468656e20697420706f696e747320746f206578697374696e67206b65793b207165640a090909090909094c696e6b616765206973207570646174656420696e206361736520656e7472792069732072656d6f7665643b20697420616c7761797320706f696e747320746f206578697374696e67206b6579733b207165646e6f742064656c656761746564756e6b6e6f776e20696e64657863616e6e6f742063616e63656c207468652073616d652070726f706f73616c20747769636570726f706f73616c206e6f7420666f756e64766f746520676976656e20666f7220696e76616c6964207265666572656e64756d2e696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64653a205f5f5068616e746f6d4974656d2073686f756c64206e6576657220626520757365642e54726561737572792050726f706f73616c436f756e74547265617375727920417070726f76616c730000000001000000020000000400000008000000100000002000000044656d6f6372616379205075626c696350726f70436f756e7444656d6f6372616379205265666572656e64756d436f756e7444656d6f6372616379204e65787454616c6c7944656d6f6372616379204c6173745461626c656457617345787465726e616cd04c110048000000960a00000e0000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e72735374616b696e672056616c696461746f72436f756e745374616b696e67204d696e696d756d56616c696461746f72436f756e745374616b696e67204f66666c696e65536c61736847726163655374616b696e672043757272656e744572615374616b696e672043757272656e74457261537461727453657373696f6e496e6465785374616b696e672043757272656e74457261526577617264735374616b696e6720466f7263654572615374616b696e6720426f6e64656445726173417574686f727368697020446964536574556e636c6573746f6f206d616e7920696e737472756374696f6e73184e11002400000065741100170000004402000009000000547269656420746f20736872696e6b20746f2061206c61726765722063617061636974796578745f7365745f73746f726167656578745f6765745f73746f726167656578745f63616c6c6578745f6372656174656578745f72657475726e6578745f63616c6c65726578745f616464726573736578745f6761735f70726963656578745f6761735f6c6566746578745f62616c616e63656578745f76616c75655f7472616e736665727265646578745f72616e646f6d6578745f6e6f776578745f64697370617463685f63616c6c6578745f726573746f72655f746f6578745f736372617463685f73697a656578745f736372617463685f726561646578745f736372617463685f77726974656578745f6465706f7369745f6576656e746578745f7365745f72656e745f616c6c6f77616e63656578745f72656e745f616c6c6f77616e63656578745f7072696e746c6e6578745f626c6f636b5f6e756d6265724e6f6e2d656d7074792066756e6374696f6e20626f64792065787065637465640000005a5011000f00000069501100020000006b50110003000000cc4f110030000000fc4f11005e0000007d00000005000000617373657274696f6e206661696c65643a20636f6e746578742e6672616d655f737461636b2e69735f656d70747928292f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7761736d692d76616c69646174696f6e2d302e312e302f7372632f66756e632e7273417420696e737472756374696f6e202840293a20436f6e7472616374204761735370656e74436f6e74726163742043757272656e745363686564756c65436f6e7472616374204163636f756e74436f756e74657252657475726e207479706573206c656e6774682073686f756c642062652030206f72203143616e2774206465636f6465207761736d20636f64654d6f64756c65206973206e6f742076616c69646d6f64756c65206465636c6172657320696e7465726e616c206d656d6f72796d756c7469706c65207461626c6573206465636c617265647461626c652065786365656473206d6178696d756d2073697a6520616c6c6f776564757365206f6620666c6f6174696e6720706f696e74207479706520696e2066756e6374696f6e20747970657320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e206c6f63616c7320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e20676c6f62616c7320697320666f7262696464656e67617320696e737472756d656e746174696f6e206661696c6564737461636b2068656967687420696e737472756d656e746174696f6e206661696c656463616c6c6465706c6f796465706c6f792066756e6374696f6e2069736e2774206578706f72746564756e6b6e6f776e206578706f72743a20657870656374696e67206f6e6c79206465706c6f7920616e642063616c6c2066756e6374696f6e7366756e6374696f6e206861732061206e6f6e2d6578697374656e7420747970656578706f72742072656665727320746f206e6f6e2d6578697374656e742066756e6374696f6e657870656374656420612066756e6374696f6e656e74727920706f696e7420706f696e747320746f20616e20696d706f727465642066756e6374696f6e656e74727920706f696e74206861732077726f6e67207369676e617475726563616c6c2066756e6374696f6e2069736e2774206578706f727465646572726f722073657269616c697a696e6720696e737472756d656e746564206d6f64756c65285511001e000000465511001f00000066756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2071656466756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2066756e6374696f6e5f73656374696f6e5f6c656e203d3d20636f64655f73656374696f6e5f6c656e3b2071656400000e5511001a000000e95411000a000000f35411001b00000073746172742066756e6374696f6e20657870656374656420746f20686176652074797065205b5d202d3e205b5d000000d854110011000000b854110020000000985411002000000070541100280000007365676d656e74206f66667365742073686f756c642072657475726e20493332746f6f206d616e79206d656d6f727920726567696f6e7320696e20696e6465782073706163653a20746f6f206d616e79207461626c657320696e20696e6465782073706163653a20747279696e6720746f20696d706f7274206d757461626c6520676c6f62616c206475706c6963617465206578706f72742046756e6374696f6e20232072656164696e672f76616c69646174696f6e206572726f723a204d697373696e6720626f647920666f722066756e6374696f6e206c656e677468206f662066756e6374696f6e2073656374696f6e206973202c207768696c65206c656e206f6620636f64652073656374696f6e20697320000000845511001c000000a05511005a0000004d00000028000000ffffffff48617368207461626c65206361706163697479206f766572666c6f772f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6861736862726f776e2d302e312e382f7372632f7261772f6d6f642e72736d616b655f746f705f6672616d655f706f6c796d6f72706869632069732063616c6c6564207769746820656d707479206672616d6520737461636b000000c20000000c00000004000000c3000000746869732066756e6374696f6e2063616e27742062652063616c6c6564207769746820656d707479206672616d6520737461636b4d6973706c6163656420656c736520696e737472756374696f6e0000c05711004700000007581100050000008457110037000000bb57110005000000515711001700000048571100090000009a59110014000000305711001800000048571100090000009a59110014000000005711001d0000001d571100130000003b8c110001000000546f6f206c61726765206d656d6f727920616c69676e6d656e7420325e20286578706563746564206174206d6f737420547279696e6720746f2075706461746520676c6f62616c20206f66207479706520547279696e6720746f20757064617465206c6f63616c20416e79537065636966696300510000000400000004000000c40000004c6162656c7320696e2062725f7461626c6520706f696e747320746f20626c6f636b206f6620646966666572656e742074797065733a2020616e6420496620626c6f636b20776974686f757420656c736520726571756972656420746f2068617665204e6f526573756c7420626c6f636b20747970652e20427574206974206861732020747970651c58110018000000345811000b000000556e657870656374656420737461636b20686569676874202c20657870656374656420547279696e6720746f2061636365737320706172656e74206672616d6520737461636b2076616c7565732e00007c58110017000000935811001600000045787065637465642076616c7565206f66207479706520206f6e20746f70206f6620737461636b2e20476f7420000000b458110007000000537461636b3a2000000001003e5911002400000014591100060000001a5911000e0000002859110016000000f05811002400000014591100060000006d6178696d756d206d656d6f72792073697a65206d757374206265206174206d6f7374202070616765736d6178696d756d206c696d697420206973206c657373207468616e206d696e696d756d20696e697469616c206d656d6f72792073697a65206d757374206265206174206d6f737420000074591100260000009a59110014000000547279696e6720746f20696e697469616c697a65207661726961626c65206f6620747970652020776974682076616c7565206f66207479706520496e69742065787072657373696f6e2073686f756c6420616c776179732062652077697468206c656e67746820324e6f6e20636f6e7374616e74206f70636f646520696e20696e69742065787072455a110007000000575a110022000000455a1100070000004c5a11000b00000045787072657373696f6e20646f65736e277420656e647320776974682060656e6460206f70636f6465476c6f62616c20206973206d757461626c6520646f65736e277420657869737473206f72206e6f742079657420646566696e65640000008c5a1100100000009c5a11000f0000004d656d6f727920617420696e6465782020646f65736e27742065786973747300bc5a11000f0000009c5a11000f0000005461626c6520617420696e646578200069621100120000009c5a11000f000000ec5a11000e0000009c5a11000f0000005479706520617420696e6465782000005a5b1100100000009c5a11000f0000002c5b1100100000004c5b11000e0000002c5b1100100000003c5b110010000000457870656374656420676c6f62616c2020746f20626520696d6d757461626c6520746f206265206d757461626c65476c6f62616c20617420696e646578206e6f6e2d656d70747920737461636b2065787065637465640000945b110020000000b45b110012000000747279696e6720746f206765742076616c756520617420706f736974696f6e20206f6e20737461636b206f662073697a6520636865636b656420636f75706c65206f66206c696e65732061626f766500ec5b110015000000657863656564656420737461636b206c696d697420000000510000000400000004000000c50000004c6f63616c732072616e6765206e6f7420696e2033322d6269742072616e67654c5c1100220000006e5c110015000000835c110007000000547279696e6720746f20616363657373206c6f63616c207769746820696e64657820207768656e20746865726520617265206f6e6c7920206c6f63616c734672616d6569735f706f6c796d6f7270686963000000510000000400000004000000c6000000656e645f6172697479000000510000000400000004000000200000006272616e63685f617269747973746172745f6865696768744e6f2066756e6374696f6e2073656374696f6e4e6f20636f64652073656374696f6e4e6f20747970652073656374696f6e000000046011000a00000046756e6374696f6e206973206e6f7420666f756e6420696e2066756e632073656374696f6e46756e6374696f6e20626f647920666f722074686520696e6465782069736e277420666f756e64f85f11000c000000605f11000b000000737461636b206d757374206265206e6f6e2d656d70747900555f11000b0000000e5f110006000000737461636b206f766572666c6f774172697479206f6620616c6c206a756d702d74617267657473206d75737420626520657175616c54797065206e6f7420666f756e6400075f110007000000005e11006c000000c8000000110000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f737461636b5f6865696768742f6d61785f6865696768742e72736d61785f686569676874707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768742f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f737461636b5f6865696768742f6d61785f6865696768742e72737472756e633a20707573683a20505f110005000000747279696e6720746f20706f70206d6f72652076616c756573207468616e20707573686564737461636b20756e646572666c6f77706f703a20756e726561636861626c65706f705f6672616d653a20636f6e74726f6c20737461636b20697320656d707479636f6e74726f6c20737461636b206f75742d6f662d626f756e6473b05f110048000000900a00000a000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e7273707573685f6672616d653a2066756e635f6964783a2066756e635f737461636b5f636f7374732069736e27742079657420636f6d70757465643b0a0909090944696420796f752063616c6c2060636f6d707574655f737461636b5f636f737473603f546869732073686f756c64206265206120696e646578206f66206120646566696e65642066756e6374696f6e44756520746f2076616c69646174696f6e20636f64652073656374696f6e2073686f756c642065786973747346756e6374696f6e20626f6479206973206f7574206f6620626f756e647310611100650000002301000017000000e86011002500000043616c6c20746f2066756e6374696f6e2074686174206f75742d6f662d626f756e64733a200000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f737461636b5f6865696768742f6d6f642e727366756e6374696f6e20696d706f727420636f756e74206973206e6f74207a65726f3b20696d706f72742073656374696f6e206d757374206578697374733b2071656466756e635f696478206973206c657373207468616e2066756e6374696f6e20696d706f72747320636f756e743b0a090909096e74682066756e6374696f6e20696d706f7274206d7573742062652060536f6d65603b0a0909090971656469621100120000007b6211000f0000003c6211000a00000046621100140000005a6211000f0000005369676e61747572652020287370656369666965642062792066756e6320292069736e277420646566696e656446756e6374696f6e20617420696e64657820206973206e6f7420646566696e6564656e76676173a06211005800000088000000160000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f6761732e72737372632f6c6962616c6c6f632f7665632e727300246311001c000000f862110013000000c704000009000000617373657274696f6e206661696c65643a20656e64203c3d206c656e586311001e000000f862110013000000b403000009000000617373657274696f6e206661696c65643a20696e646578203c3d206c656e0000510000000400000004000000c70000004d641100120000005f6411000c0000006066756e635f696478602073686f756c6420636f6d652066726f6d20606e6565645f7468756e6b73603b0a09090909606e6565645f7468756e6b736020697320706f70756c617465642077697468207468652073616d65206974656d73207468617420696e20607265706c6163656d656e745f6d6170603b0a090909097165644174207468697320706f696e7420616e20696e646578206d7573742062652061737369676e656420746f2065616368207468756e6b66756e6374696f6e207769746820696478202069736e277420666f756e644636345265696e74657270726574493634556e726561636861626c654e6f70426c6f636b00510000000400000004000000c80000004c6f6f704966456c7365456e64427200510000000400000004000000200000004272496642725461626c6500510000000400000004000000c900000052657475726e43616c6c43616c6c496e6469726563740000510000000400000004000000ca00000044726f7053656c6563744765744c6f63616c5365744c6f63616c5465654c6f63616c476574476c6f62616c536574476c6f62616c4933324c6f61644936344c6f61644633324c6f61644636344c6f61644933324c6f616438534933324c6f616438554933324c6f61643136534933324c6f61643136554936344c6f616438534936344c6f616438554936344c6f61643136534936344c6f61643136554936344c6f61643332534936344c6f616433325549333253746f726549363453746f726546333253746f726546363453746f726549333253746f72653849333253746f7265313649363453746f72653849363453746f7265313649363453746f7265333243757272656e744d656d6f727947726f774d656d6f7279493332436f6e737400510000000400000004000000cb000000493634436f6e7374510000000400000004000000cc000000463332436f6e7374463634436f6e73745100000004000000040000001e00000049333245717a49333245714933324e654933324c74534933324c74554933324774534933324774554933324c65534933324c655549333247655349333247655549363445717a49363445714936344e654936344c74534936344c74554936344774534936344774554936344c65534936344c655549363447655349363447655546333245714633324e654633324c7446333247744633324c65463332476546363445714636344e654636344c7446363447744636344c654636344765493332436c7a49333243747a493332506f70636e744933324164644933325375624933324d756c493332446976534933324469765549333252656d5349333252656d55493332416e644933324f72493332586f7249333253686c4933325368725349333253687255493332526f746c493332526f7472493634436c7a49363443747a493634506f70636e744936344164644936345375624936344d756c493634446976534936344469765549363452656d5349363452656d55493634416e644936344f72493634586f7249363453686c4936345368725349363453687255493634526f746c493634526f74724633324162734633324e65674633324365696c463332466c6f6f724633325472756e634633324e656172657374463332537172744633324164644633325375624633324d756c4633324469764633324d696e4633324d6178463332436f70797369676e4636344162734636344e65674636344365696c463634466c6f6f724636345472756e634636344e656172657374463634537172744636344164644636345375624636344d756c4636344469764636344d696e4636344d6178463634436f70797369676e493332577261704936344933325472756e63534633324933325472756e63554633324933325472756e63534636344933325472756e6355463634493634457874656e6453493332493634457874656e64554933324936345472756e63534633324936345472756e63554633324936345472756e63534636344936345472756e6355463634463332436f6e7665727453493332463332436f6e7665727455493332463332436f6e7665727453493634463332436f6e766572745549363446333244656d6f7465463634463634436f6e7665727453493332463634436f6e7665727455493332463634436f6e7665727453493634463634436f6e766572745549363446363450726f6d6f74654633324933325265696e746572707265744633324936345265696e746572707265744636344633325265696e746572707265744933324e6f526573756c7456616c756500510000000400000004000000c4000000463634493332493634463332496e76616c696444617461547261696c696e6744617461556e6578706563746564456f66706a11000b000000492f4f204572726f723a2000946a110028000000bc6a1100500000008700000009000000696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64652f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d73616e64626f782f7372632f2e2e2f776974686f75745f7374642e7273946a110028000000bc6a11005000000090000000090000004f6666636861696e206572726f723a207375626d697474696e67207472616e73616374696f6e206661696c6564214f6666636861696e206572726f723a206465636f64696e6720576f726b6572537461747573206661696c6564214f6666636861696e206572726f723a2065787472696e736963206372656174696f6e206661696c6564214f6666636861696e206572726f723a207369676e696e67206661696c6564214f6666636861696e206572726f723a206665746368696e67206e6574776f726b207374617465206661696c656421000000000000246c11001100000000000000386c1100010000000000000000000000406c110001000000000000004865617274626561745265636569766564000000786c11000b000000486c1100300000002041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f72697479496460417574686f726974794964496d4f6e6c696e65204b657973496d4f6e6c696e6520526563656976656448656172746265617473436f756e63696c20446573697265645365617473436f756e63696c20566f7465436f756e74436f756e63696c204e657874566f746572536574436f756e63696c20566f746572436f756e74436f756e63696c2043616e646964617465436f756e7400000000906d11000e00000000000000a06d1100010000000000000000000000a86d1100010000000000000000000000b06d1100060000000000000048761100000000000000000000000000b86d1100010000000000000000000000c06d1100070000000000000048761100000000000000000000000000c86d110001000000000000004e6577417574686f7269746965730000436e1100170000001f6e1100240000005061757365640000f86d110027000000526573756d656400d06d1100280000002043757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e2043757272656e7420617574686f726974792073657420686173206265656e207061757365642e204e657720617574686f726974792073657420686173206265656e206170706c6965642e5665633c28417574686f7269747949642c20753634293e4772616e64706146696e616c69747920417574686f72697469657354696d657374616d7020496e697469616c697a6564426162652045706f6368496e6465784261626520417574686f726974696573426162652045706f63685374617274536c6f74426162652043757272656e74536c6f7442616265205365636f6e64617279536c6f7473426162652050656e64696e675365636f6e64617279536c6f74734368616e6765426162652052616e646f6d6e65737342616265204e65787452616e646f6d6e65737342616265205365676d656e74496e6465784261626520556e646572436f6e737472756374696f6e4261626520496e697469616c697a656462616265736c6f74436f756c64206e6f74206465636f64652072657175657374656420696e686572656e742074797065214241424520696e686572656e742064617461206e6f7420666f756e6453657373696f6e2053746f72656452616e676553657373696f6e2043757272656e74496e64657853657373696f6e204368616e67656453657373696f6e205175657565644368616e676564000000001c7011000a00000000000000287011000100000000000000000000003070110002000000000000004e657753657373696f6e0000b77011000c00000040701100550000009570110022000000204e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f742074686520626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e53657373696f6e496e64657800320000000000000001000000cd000000ce000000cf000000320000000000000001000000cd000000ce000000cf00000074696d737461703054696d657374616d7020696e686572656e742064617461206973206e6f742070726f76696465642e496e76616c69642074696d657374616d7020696e686572656e74206461746120656e636f64696e672e54696d657374616d702044696455706461746500000000b8711100100000000000000048761100000000000000000000000000c8711100010000000000000000000000d07111000f0000000000000048761100000000000000000000000000e0711100010000000000000045787472696e73696353756363657373fd7111002500000045787472696e7369634661696c656400e87111001500000020416e2065787472696e736963206661696c65642e20416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e53797374656d2045787472696e736963436f756e7453797374656d20416c6c45787472696e7369637357656967687453797374656d20416c6c45787472696e736963734c656e53797374656d204e6578745765696768744d756c7469706c69657253797374656d2045787472696e7369634461746153797374656d204576656e74436f756e7448617368206e6f7420657175616c0000d072110019000000f0721100500000005800000022000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f67656e657269632f6572612e72736578745f6368696c645f73746f726167655f726f6f74206e657665722072657475726e73207533323a3a6d61785f76616c75653b2071656452756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e670000b47311002d000000e17311000c000000ed73110003000000617373657274696f6e206661696c65643a2060286c656674203d3d20726967687429600a20206c6566743a2060602c0a2072696768743a2060603a20f87311003400000064657374696e6174696f6e20616e6420736f7572636520736c69636573206861766520646966666572656e74206c656e6774687374771100180000004d0800000900000054741100110000006574110017000000f0020000050000006361706163697479206f766572666c6f777372632f6c6962616c6c6f632f7261775f7665632e7273f0741100460000006301000013000000510000000400000004000000d0000000d1000000d20000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f7200320000000000000001000000a300000000000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f666d742f6d6f642e727301010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000202020202020202020202020202020202020202020202020202020202020303030303030303030303030303030304040404040000000000000000000000000058761100200000007876110012000000320000000000000001000000d3000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e64657820697320303030313032303330343035303630373038303931303131313231333134313531363137313831393230323132323233323432353236323732383239333033313332333333343335333633373338333934303431343234333434343534363437343834393530353135323533353435353536353735383539363036313632363336343635363636373638363937303731373237333734373537363737373837393830383138323833383438353836383738383839393039313932393339343935393639373938393900008c77110006000000927711002200000074771100180000000c0a0000050000007372632f6c6962636f72652f736c6963652f6d6f642e7273696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e67746820d477110016000000ea7711000d0000007477110018000000120a000005000000736c69636520696e64657820737461727473206174202062757420656e6473206174206030785b2e2e2e5d00be7811000b000000728b110016000000f777110001000000a878110016000000ed07000009000000508b11000e0000005e8b110004000000628b110010000000f777110001000000a878110016000000f107000005000000108b11002b0000003b8b1100150000007a01000015000000be7811000b000000c978110026000000ef78110008000000f778110006000000f777110001000000a878110016000000fe070000050000007372632f6c6962636f72652f7374722f6d6f642e72736279746520696e64657820206973206e6f742061206368617220626f756e646172793b20697420697320696e7369646520202862797465732029206f6620600000004679110002000000307911001600000054040000110000003079110016000000480400002800000000000000000000007372632f6c6962636f72652f666d742f6d6f642e72732e2e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000f8030000000000000000000000000000000000000000000000000000000000000000feffffffffbfb6000000000000000000ff070000000000f8ffff0000010000000000000000000000c09f9f3d0000000002000000ffffff0700000000000000000000c0ff01000000000000f80f20f08411004a0000004087110000020000408911003a00000000010203040506070809080a0b0c0d0e0f10111213140215161718191a1b1c1d1e1f2002020202020202020202210202020202020202020202020202222324252602270228020202292a2b022c2d2e2f300202310202023202020202020202023302023402020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023502360237020202020202020238023902020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023a3b3c020202023d02023e3f4041424344454602020247020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202024802020202020202020202024902020202023b020001020202020302020202040205060202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020207020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200010305050606030706080809110a1c0b190c140d120e0d0f0410031212130916011705180219031a071c021d011f1620032b042c022d0b2e01300331023201a702a902aa04ab08fa02fb05fd04fe03ff09ad78798b8da23057588b8c901c1ddd0e0f4b4cfbfc2e2f3f5c5d5fb5e2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d112945495764658d91a9b4babbc5c9dfe4e5f0040d1145496465808184b2bcbebfd5d7f0f183858ba4a6bebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff800d6d71dedf0e0f1f6e6f1c1d5f7d7eaeafbbbcfa16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f747596972f5f262e2fa7afb7bfc7cfd7df9a409798308f1fc0c1ceff4e4f5a5b07080f10272feeef6e6f373d3f42459091feff536775c8c9d0d1d8d9e7feff00205f2282df048244081b04061181ac0e80ab351e1580e003190801042f043404070301070607110a500f1207550802041c0a090308030703020303030c0405030b06010e15053a0311070605100757070207150d500443032d03010411060f0c3a041d255f206d046a2580c80582b0031a0682fd035907150b1709140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a061f414c042d0374083c030f033c0738082b0582ff1118082f112d032010210f808c048297190b158894052f053b07020e180980b030740c80d61a0c0580ff0580b605240c9bc60ad23010848d033709815c1480b80880c73035040a06380846080c06740b1e035a0459098083181c0a16094808808a06aba40c170431a10481da26070c050580a511816d1078282a064c04808d0480be031b030f0d0006010103010402080809020a050b02100111041205131114021502170219041c051d0824016a036b02bc02d102d40cd509d602d702da01e005e102e802ee20f004f906fa020c273b3e4e4f8f9e9e9f060709363d3e56f3d0d104141836375657bd35cecfe01287898e9e040d0e11122931343a4546494a4e4f64655a5cb6b71b1ca8a9d8d909379091a8070a3b3e66698f926f5feeef5a629a9b2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a22253e3fc5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d00c72a3a4cbcc6e6f5e227b0503042d036504012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b018090813709160a088098390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a81261f808128082a808617094e041e0f430e19070a0647092709750b3f412a063b050a0651060105100305808b602048080a80a65e22450b0a060d1339070a362c041080c03c64530c0180a0451b4808531d398107460a1d03474937030e080a0639070a81361980c7320d839b66750b80c48abc842f8fd18247a1b98239072a040260260a460a28051382b05b654b0439071140041c97f80882f3a50d811f3103110408818c89046b050d03090710936080f60a73086e1746809a140c570919808781470385420f1585502b80d52d031a040281703a0501850080d7294c040a04028311444c3d80c23c06010455051b3402810e2c04640c560a0d035d033d391d0d2c040907020e06809a83d60a0d030b05740c59070c140c0438080a0628081e527703310380a60c14040305030d06856a000000d0841100200000002700000019000000d0841100200000002800000020000000d0841100200000002a00000019000000d0841100200000002b00000018000000d0841100200000002c0000002000000000000000000000007372632f6c6962636f72652f756e69636f64652f626f6f6c5f747269652e72730000c0fbef3e00000000000e0000000000000000000000000000f8fffbffffff0700000000000014fe21fe000c00000002000000000000501e2080000c00004006000000000000108639020000002300be2100000c0000fc02000000000000d01e20c0000c0000000400000000000040012080000000000011000000000000c0c13d60000c0000000200000000000090443060000c00000003000000000000581e2080000c00000000845c8000000000000000000000f207807f000000000000000000000000f21f003f000000000000000000030000a002000000000000fe7fdfe0fffeffffff1f40000000000000000000000000e0fd66000000c301001e006420002000000000000000e00000000000001c0000001c0000000c0000000c00000000000000b03f40fe0f200000000000380000000000006000000000020000000000008701040e00008009000000000000407fe51ff89f000000000000ff7f0f0000000000f0170400000000f80f00030000003c3b00000000000040a303000000000000f0cf000000f7fffd211003fffffffffffffffb00100000000000000000ffffffff01000000000000800300000000000000008000000000ffffffff0000000000fc00000000000600000000000000000080f73f000000c0000000000000000000000300440800006000000030000000ffff038000000000c03f000080ff030000000000070000000000c833000000002000000000000000007e660008100000000000100000000000009dc1020000000030400000000000202100000000004000000000ffff0000ffff00000000000000000001000000020003000000000000000000000000000000000000000000000000000004000005000000000000000006000000000000000007000008090a000b0c0d0e0f000010111200001314151600001718191a1b001c0000001d0000000000001e1f202100000000002200230024252600000000270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002829000000000000000000000000000000002a2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000002d2e00002f0000000000000000000000000000000000000000000000000000000000003031320000000000000000000000000000000000000000003300000029000000000000340000000000000000000000000000000000000000000000350036000000000000000000000000000000000000000000000000000037380000383838390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000001000000000000000000c0076ef0000000000087000000006000000000000000f0000000c0ff01000000000002000000000000ff7f0000000000008003000000000078060700000080ef1f000000000000000800030000000000c07f001e000000000000000000000080d34000000080f8070000030000000000005801008000c01f1f0000000000000000ff5c00004000000000000000000000f9a50d000000000000000000000000803cb00100003000000000000000000000f8a70100000000000000000000000028bf00000000e0bc0f0000000000000080ff060000f00c01000000fe0700000000f87980007e0e0000000000fc7f03000000000000000000007fbf0000fcfffffc6d000000000000007eb4bf000000000000000000a3000000000000000000000018000000000000001f000000000000007f0000800000000000000080070000000000000000600000000000000000a0c307f8e70f0000003c00001c00000000000000ffffffffffff7ff8ffffffffff1f2000100000f8feff00007ffffff9db0700000000000000f0000000007f0000000000f00700000000000000000000ffffffffffffffffffffffffffffffffffff000063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c75657372632f6c6962636f72652f6f7074696f6e2e7273626567696e203c3d20656e642028203c3d2029207768656e20736c6963696e672060206973206f7574206f6620626f756e6473206f66206066616c736574727565426f72726f774572726f72426f72726f774d75744572726f7270616e69636b6564206174200000e18b110001000000e28b1100030000004876110000000000e08b110001000000e08b1100010000003a27272c2000000048761100000000003b8b1100150000008e040000050000004876110000000000108c1100020000003a200000248c1100150000003c040000050000007372632f6c6962636f72652f726573756c742e72735b5d290a000000d40000000c00000004000000d5000000d6000000d70000002c0a2c20510000000400000004000000d8000000d9000000da00000020202020207b20207b0a207d7d28280a2c000000510000000400000004000000db000000510000000400000004000000dc0000004e6f6e65536f6d65557466384572726f7276616c69645f75705f746f6572726f725f6c656e000000510000000400000004000000dd0000004572726f720041e899c6000b08000000000000000000d1a403046e616d6501c8a403ff04000e6578745f626c616b65325f323536011f6578745f6765745f616c6c6f63617465645f6368696c645f73746f7261676502176578745f636c6561725f6368696c645f73746f72616765030c6578745f74776f785f313238040f6578745f7365745f73746f7261676505146578745f6765745f73746f726167655f696e746f06116578745f636c6561725f73746f7261676507166578745f6b696c6c5f6368696c645f73746f7261676508196578745f6765745f616c6c6f63617465645f73746f72616765090e6578745f7072696e745f757466380a166578745f6368696c645f73746f726167655f726f6f740b156578745f7365745f6368696c645f73746f726167650c126578745f737232353531395f7665726966790d0d6578745f7072696e745f6865780e106578745f69735f76616c696461746f720f156578745f6c6f63616c5f73746f726167655f67657410216578745f6c6f63616c5f73746f726167655f636f6d706172655f616e645f73657411176578745f737232353531395f7075626c69635f6b65797312116578745f6e6574776f726b5f737461746513106578745f737232353531395f7369676e14166578745f7375626d69745f7472616e73616374696f6e15156578745f6c6f63616c5f73746f726167655f73657416146578745f656432353531395f67656e657261746517146578745f737232353531395f67656e657261746518106578745f636c6561725f70726566697819166578745f73616e64626f785f6d656d6f72795f6e65771a1b6578745f73616e64626f785f6d656d6f72795f74656172646f776e1b176578745f73616e64626f785f696e7374616e74696174651c126578745f73616e64626f785f696e766f6b651d1d6578745f73616e64626f785f696e7374616e63655f74656172646f776e1e236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f741f106578745f73746f726167655f726f6f7420186578745f73746f726167655f6368616e6765735f726f6f7421126578745f656432353531395f76657269667922166578745f73616e64626f785f6d656d6f72795f67657423166578745f73616e64626f785f6d656d6f72795f736574240b6578745f74776f785f3634250a6578745f6d616c6c6f6326086578745f6672656527693c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a686233613264373361363531643330313428693c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c616c6c6f633a3a7665633a3a496e746f497465723c543e3e3e3a3a737065635f657874656e643a3a6839353139326336653130323738616638290c5f5f727573745f616c6c6f632a0e5f5f727573745f7265616c6c6f632b4b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68383837613138326238666137666366612c08727573745f6f6f6d2d34616c6c6f633a3a7261775f7665633a3a63617061636974795f6f766572666c6f773a3a68326562373664643539623264336265342e0e5f5f727573745f6465616c6c6f632f30636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a683461633562326331643134663633643930543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6861386438343236613162343632653038316b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68366532383865303936326331363036663248616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a6830303735663439666263346466363232337d7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c205230293e3a3a6465636f64653a3a683765306432313465663934363736646134135f5f727573745f616c6c6f635f7a65726f65643536636f72653a3a736c6963653a3a736c6963655f696e6465785f6f726465725f6661696c3a3a6838613764636139656338646233313932362d616c6c6f633a3a7665633a3a5665633c543e3a3a726573697a653a3a6864313234663032323030616464623764372d616c6c6f633a3a7665633a3a5665633c543e3a3a72657461696e3a3a68316138316361326661643163313136613836636f72653a3a70616e69636b696e673a3a70616e69635f626f756e64735f636865636b3a3a686135653366323238656436353166623939443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68303665613630326633653263366337613a4b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68643039383066323966373732663561313b543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68313163383931333362633739643763393c753c73725f7072696d6974697665733a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68323363313238346662306239343163653d543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68366430366636633938313632353435323e543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68383766633464333234656162663437363f543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686531623639643464646330366335626640543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686537386161653739663139396662383441543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686663633936376334616338346238656142513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a683234376431616632323437663235333643513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a683939313139333763616435303563653344513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a686234373062623433636165626133326345723c73725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573744974656d3c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6835663131386236383664333738303838463f7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6838646434653064356163616139303738476c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683030323930663135306234653936343848783c73726d6c5f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6866333466643738386639303838346163497b3c73726d6c5f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68323934613638626137653239326439334a463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68343761333236636537323361633565324b4e73725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573743c486173683e3a3a636f6e766572745f66697273743a3a68333733343832616264373635363237654c7a3c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a7b7b636c6f737572657d7d3a3a68323762383464363361336331316562344d4d73726d6c5f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a696e7374616e74696174653a3a68613433343935613162326233363937624e81013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a68663134376335393033616266303061364f4b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6861333237333735633637383338306265503173726d6c5f636f6e7472616374733a3a657865633a3a7472616e736665723a3a6832343336613236633030393164663866513973726d6c5f636f6e7472616374733a3a7761736d3a3a636f64655f63616368653a3a6c6f61643a3a686662353936636263633431623732653752593c73726d6c5f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732073726d6c5f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a6863393839663736646330636531633538532e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a68653664623630383563633433383962375430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a686438306462613131363363396237326455783c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a6837323735646631646462373635346564568c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a656e737572655f63616e5f77697468647261773a3a6838383139643032303437646533313265574f73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e3a3a7365745f62616c616e63653a3a68336135306239613864636266666263315829636f72653a3a70616e69636b696e673a3a70616e69633a3a68383437343861613365313530303538645930636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68383062346238373239353835363462665a4673726d6c5f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a63616c6c3a3a68306136656366356637646262353833615b4273726d6c5f636f6e7472616374733a3a72656e743a3a7472795f65766963745f6f725f616e645f7061795f72656e743a3a68393531613662346431663131303833625c3c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68396233393231646336386338393434395d2b616c6c6f633a3a736c6963653a3a6d657267655f736f72743a3a68323766613130313034633634613863385e34636f72653a3a736c6963653a3a736c6963655f696e6465785f6c656e5f6661696c3a3a68303636323330386261383262383836375f2d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a68393339343365636337346665373436336034636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6834643538303031323139303934663664612e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6861643261613439303934623963663334623c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6833376135653238316261313630393262632d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6865333035633335633939613563313432646b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6831363061323131393563633731663033656c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683031383665396336343938613431323666713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a686661646564366534366630393035376467713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a686364323238356130613465303136373568443c636f72653a3a666d743a3a417267756d656e747320617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683966656139363163383337616565343169303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68343031313136626439613631373837316a2d636f72653a3a70616e69636b696e673a3a70616e69635f666d743a3a68326131633365306237353630393832396b723c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68636236386434323961396339393730626c303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68633461353138633662636639643863366d89013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6465706f7369745f6372656174696e673a3a68393832333930663535663765663337326e3573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a68393461653532316564326531613362376f8d013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6d616b655f667265655f62616c616e63655f62653a3a6866623835643365313131633264383035703573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a6866643535373663643531646330616334717f3c73726d6c5f696e64696365733a3a4d6f64756c653c543e2061732073726d6c5f73797374656d3a3a4f6e4e65774163636f756e743c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f6e65775f6163636f756e743a3a6863613139653633306131343864396635724073726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6576656e745f696e64657865643a3a6833306164626137303636363031363563733f73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7365745f667265655f62616c616e63653a3a6861396562623938653737656335326336743873726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a6832393234623866333664303461646437753673726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6b696c6c5f73746173683a3a6835376439393863333663306362326637763773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683764623730313338656531343930393477d5013c73726d6c5f73657373696f6e3a3a4e6578744b6579733c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a67656e657261746f723a3a53746f72616765446f75626c654d61703c616c6c6f633a3a7665633a3a5665633c75383e2c3c542061732073726d6c5f73657373696f6e3a3a54726169743e3a3a56616c696461746f7249642c3c542061732073726d6c5f73657373696f6e3a3a54726169743e3a3a4b6579733e3e3a3a6b65795f666f723a3a6836656264623531353334333866306661788d016e6f64655f72756e74696d653a3a5f494d504c5f4445434f44455f464f525f53657373696f6e4b6579733a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a53657373696f6e4b6579733e3a3a6465636f64653a3a683561323332613463366163363431313379f3013c73726d6c5f73657373696f6e3a3a4b65794f776e65723c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a67656e657261746f723a3a53746f72616765446f75626c654d61703c616c6c6f633a3a7665633a3a5665633c75383e2c287375627374726174655f7072696d6974697665733a3a63727970746f3a3a4b65795479706549642c20616c6c6f633a3a7665633a3a5665633c75383e292c3c542061732073726d6c5f73657373696f6e3a3a54726169743e3a3a56616c696461746f7249643e3e3a3a6b65795f666f723a3a68313632656166323566323535313330357a81013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a77697468647261773a3a68393937343763623132396566663633637b3e73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a76657374696e675f62616c616e63653a3a68626135333633393137393139353261377c3473726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6c6f636b733a3a68616564326164626136343730303962367d3573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a68626466616138376439316239343663317e483c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68636239313066666238623665666266387f3673726d6c5f626162653a3a4d6f64756c653c543e3a3a646f5f696e697469616c697a653a3a68613261613737356631363337393135388001d5017375627374726174655f636f6e73656e7375735f626162655f7072696d6974697665733a3a6469676573743a3a5f494d504c5f4445434f44455f464f525f526177426162655072654469676573743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72207375627374726174655f636f6e73656e7375735f626162655f7072696d6974697665733a3a6469676573743a3a526177426162655072654469676573743e3a3a6465636f64653a3a683165383633313231663531373333636181013573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a686134623264616561303834363264313882013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a686234363361376531636539623163366283013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6835303765393466663935386165383035840186013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a746f74616c5f62616c616e63653a3a68356566336637643432396336346530358501653c73726d6c5f62616c616e6365733a3a54616b65466565733c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a683237323639383463613634373132393286013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683532333239356264323838303133626487014b73725f7072696d6974697665733a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3a3a696e746f5f6163636f756e743a3a683464353134633738623636366364396388013573726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a617574686f723a3a686262323839663234366633643538623189013d73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a68316630663962613433636433613737368a013f73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a68346633386537396538316634623832368b016f3c73726d6c5f62616c616e6365733a3a5f5f476574427974655374727563744672656542616c616e63653c542c493e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68386331646135303462653136623834328c014373726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7365745f72657365727665645f62616c616e63653a3a68313131313562353038383462333065358d014873726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68373634656336386538393863626631328e018e013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6465706f7369745f696e746f5f6578697374696e673a3a68653361653433333566633330386231318f018c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a657874656e645f6c6f636b3a3a68356130643538663138373639323133639001483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6832396131323632666462363630623166910189013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7365745f6c6f636b3a3a6866313962383864373035373235333031920191013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a736c6173685f72657365727665643a3a683862666531396563663561303939353993018a013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a726573657276653a3a683538303162336636373431313931613594018c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a756e726573657276653a3a6834353831346134613436316461663664950185013c28412c20422c20432c20442c20452c20462c20472c20482c20492c204a2c204b2c204c2c204d2c204e2c204f2c20502c20512c2052292061732073725f7072696d6974697665733a3a7472616974733a3a4f6e46696e616c697a653c4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a686632353832623439663864373239383596013673726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a70726f706f73616c733a3a683166393933303265646138393366336497013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a686361626666313438336530643334616298013673726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6c6f673a3a683732316430323263613030363533366399013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68396337653466346638313763633235669a013873726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a68333130646536303733613730373564639b012e636f72653a3a6f7074696f6e3a3a6578706563745f6661696c65643a3a68336536643062643066633434316138639c013673726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a74616b653a3a68373965643430653861373130303239309d01703c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a68323061393538343339306430316631629e01303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68346462656130333936616137316335379f013773726d6c5f626162653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6830343636333139393732616235306662a0013973726d6c5f626162653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866323635643031666539653365363837a1016c3c73726d6c5f626162653a3a5f5f476574427974655374727563745365636f6e64617279536c6f74733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836306236326130356662343438356664a2014273726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864336438666230353938383830623432a30197013c73726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4578706563746564426c6f636b54696d6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861393234636630663233333436373565a40193013c73726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45706f63684475726174696f6e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866333562613166356534306239333038a5014473726d6c5f737570706f72743a3a7472616974733a3a5369676e6564496d62616c616e63653c422c503e3a3a6d657267653a3a6836353130623436323432343138393034a6014173726d6c5f737570706f72743a3a7472616974733a3a496d62616c616e63653a3a6d617962655f73756273756d653a3a6832353363313936336130343663323232a7013b73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6866613261633065383362346337623066a8013d73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6863303933316539396261316563326434a9014673726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6836346563366239623637393438383937aa018e013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4275726e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865663930613064323235363663333833ab01870173725f7072696d6974697665733a3a5f494d504c5f454e434f44455f464f525f50657262696c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073725f7072696d6974697665733a3a50657262696c6c3e3a3a656e636f64653a3a6832303537333866626531326339393464ac0195013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5370656e64506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864363365653733343139336537323035ad0196013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726f706f73616c426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833636231353437336665363263393339ae013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862346566346230303163363338363236af01453c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a6765743a3a6864323865646665323862316438626461b001437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6838316138626637386664393238396262b101483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6838643839376466316463383730353034b201303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6864343335386361386131336134613461b301313c73747220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832353334343133333961336462333838b40149636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a6830303232623134376237336161363832b5012f636f72653a3a666d743a3a6e756d3a3a696d703a3a666d745f7536343a3a6835313561363538333432643134653438b60135636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a6864326239326336376133363832663736b7019f013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6837643463383761363231356161613164b8017f6e6f64655f72756e74696d653a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a6465636f64653a3a6834323762633232356334336538343738b901a5013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e2061732073725f7072696d6974697665733a3a7472616974733a3a436865636b61626c653c4c6f6f6b75703e3e3a3a636865636b3a3a6832623933373833616633313036653937ba01b3013c73726d6c5f73797374656d3a3a426c6f636b486173683c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265722c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173683e3e3a3a6765743a3a6836376662386130366633633630306236bb013473726d6c5f696e64696365733a3a4d6f64756c653c543e3a3a656e756d5f7365743a3a6863386132613366373030373061343833bc0182016e6f64655f72756e74696d653a3a5f494d504c5f454e434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a656e636f64655f746f3a3a6832656437646539303161323035633462bd01593c73725f7072696d6974697665733a3a416e795369676e61747572652061732073725f7072696d6974697665733a3a7472616974733a3a5665726966793e3a3a7665726966793a3a6834613134356435376535326338343963be013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6839353062666164353137373934643662bf01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6864363166323962316336666636613036c0013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6835376439383535326565653232646339c1014373726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6863346436656162623065346166643463c2014e73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6865656661363966306265383130353437c3019f013c73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5265706f72744c6174656e637944656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863633261373461633262363466313432c4019c013c73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a57696e646f7753697a6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862643336313466363737666463623930c5014073726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a63616e6469646174655f7265675f696e666f3a3a6836356532366463323666646564326338c6013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830396161353530393261393136306536c7013873726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a616c6c5f766f746572733a3a6835626330333038373734356266626433c801bc013c73726d6c5f656c656374696f6e733a3a566f746572733c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c7533322c616c6c6f633a3a7665633a3a5665633c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3e3a3a6765743a3a6836343530373839643631313335623537c9013a73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a617070726f76616c735f6f663a3a6834636531323262386364616632373164ca01ab023c73726d6c5f656c656374696f6e733a3a566f746572496e666f4f663c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c73726d6c5f656c656374696f6e733a3a566f746572496e666f3c3c3c542061732073726d6c5f656c656374696f6e733a3a54726169743e3a3a43757272656e63792061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e3e3e3a3a6765743a3a6839353435373563623033623266376164cb01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830306266613131376363643966636132cc013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6834663737383166383261323335656539cd013e73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6834323032333065653761646566366563ce01713c73726d6c5f656c656374696f6e733a3a5f5f4765744279746553747275637443616e646964617465436f756e743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832313632376138373035633133303162cf01713c73726d6c5f656c656374696f6e733a3a5f5f476574427974655374727563745265676973746572496e666f4f663c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834323831373366323661626463646162d0014773726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864616130663132633563653965326435d10199013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a564f5445525f5345545f53495a4544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836303730626637383966323937336166d20197013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839353566336533306138393966303763d3019e013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a496e6163746976654772616365506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836356636383762373536303464663736d40195013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4361727279436f756e7444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836376234376230363730366262646464d50194013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e6746656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838306538626439313063303464353137d60195013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863343535613630633138373737646633d70198013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a43616e646964616379426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833643839663436306138616365373238d801493c73726d6c5f656c656374696f6e733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836363738326430343830333932303333d9015d3c73726d6c5f656c656374696f6e733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6865313237343265643436323863313363da01323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6835376666316531393764316133666165db013e73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a646f5f7365745f617070726f76616c733a3a6862393861646234643932613964643436dc013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830613136663763326436636162396437dd013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834303933656263613764633935336334de013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864653433636134386432663839633832df0195013c73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a6862323334656531656565643065363330e0013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830346139336461663937383038353530e1013a73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a72656d6f76655f766f7465723a3a6837333663623433653862356165653863e201483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6835326537643661333538353933376237e3016b3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6831376535333234653963653362376639e4016f3c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830663235353062306664313165336230e501613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6831393036623737303332303538303032e6014b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6838323661353839396163653264643933e701793c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6831633536643839383565616533346136e801793c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a6838323365336331613035316361383235e9017b3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a6837656235376339626262656132613466ea017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a6863363036643063313939636263343237eb0180013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a6836346138616262393064333362666338ec01743c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a6830613039663435383032383038326239ed01723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6833666335383965313231316634363262ee0130636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6864353337376434623436666631393963ef01723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6839653635346335653663363733626330f001483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6830323030313266383334633262363030f1017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6864636131353435636431626232323536f2017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a6865623963366463656435363161666630f3017f3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a6830336532333238633564323665643838f40184013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a6836643561326232386136333236613363f50148616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6831646664313862353264343937383138f601a0013c73726d6c5f696d5f6f6e6c696e653a3a5265636569766564486561727462656174732061732073726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a67656e657261746f723a3a53746f72616765446f75626c654d61703c7533322c7533322c616c6c6f633a3a7665633a3a5665633c75383e3e3e3a3a7072656669785f666f723a3a6835613938623863393466316234356134f7014273726d6c5f636f6e7472616374733a3a7761736d3a3a707265706172653a3a707265706172655f636f6e74726163743a3a6866303437623561343464646262646531f801437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6837323564303066303039383134333333f901860173726d6c5f64656d6f63726163793a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f64656d6f63726163793a3a43616c6c3c543e3e3a3a6465636f64653a3a6834346230653034373133306439393834fa018a0173726d6c5f636f6c6c6563746976653a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a6465636f64653a3a6832616233336636646466353633306434fb018b0173726d6c5f636f6e7472616374733a3a5f494d504c5f4445434f44455f464f525f5363686564756c653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6e7472616374733a3a5363686564756c653e3a3a6465636f64653a3a6861613264383132353633386637633666fc013f7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6833666166363831343034336663383630fd018d0173726d6c5f636f6c6c6563746976653a3a5f494d504c5f454e434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a656e636f64655f746f3a3a6835333135326365646331366166383464fe018e0173726d6c5f636f6e7472616374733a3a5f494d504c5f454e434f44455f464f525f5363686564756c653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6e7472616374733a3a5363686564756c653e3a3a656e636f64655f746f3a3a6864383034666435326663303564373531ff01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68346132326137353166353039353936328002493c73726d6c5f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68313036663538373734343235316465348102673c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a686234353032666435333739313233616382023273726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a626f6e6465643a3a68323633646436393437646235363265358302c9023c73726d6c5f7374616b696e673a3a4c65646765723c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c73726d6c5f7374616b696e673a3a5374616b696e674c65646765723c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c3c542061732073726d6c5f7374616b696e673a3a54726169743e3a3a43757272656e63792061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e3e3e3a3a6765743a3a6833666131383938383333316666383663840284016e6f64655f72756e74696d653a3a5f494d504c5f454e434f44455f464f525f4576656e743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a4576656e743e3a3a656e636f64655f746f3a3a68393762653937383763633865626266318502a20173726d6c5f636f6c6c6563746976653a3a5f494d504c5f454e434f44455f464f525f5261774576656e743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6c6c6563746976653a3a5261774576656e743c486173682c4163636f756e7449642c493e3e3a3a656e636f64655f746f3a3a68303331646338363335326565636231328602406e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73797374656d3a3a68333261646664636161383334393535328702416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696e64696365733a3a68613034396361643731306365653430368802426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f62616c616e6365733a3a68363238613533396333393637636462638902416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7374616b696e673a3a68623337316439313866393336343062358a02416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73657373696f6e3a3a68363832643363396535326631336462668b02436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f64656d6f63726163793a3a68666665633839356537663861633666378c024e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636f6c6c6563746976655f496e7374616e6365313a3a68373063633031333665633365643135358d02436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f656c656374696f6e733a3a68663639336437313461396535656238628e024e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6d656d626572736869705f496e7374616e6365313a3a68366637666234666531326366343937318f02416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6772616e6470613a3a68386566353837313562643065323738669002426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f74726561737572793a3a68633765303238653734336464626362399102436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636f6e7472616374733a3a686261316237366535356436393037303692023e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7375646f3a3a68353863303666626565323936373235629302436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696d5f6f6e6c696e653a3a68643332616335396531626334643066369402653c6e6f64655f72756e74696d653a3a43616c6c2061732073725f7072696d6974697665733a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a68346461636332356639643933386631339502583c6e6f64655f72756e74696d653a3a43616c6c2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68366338306263356133666633323537319602437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a683435303231343364633366333963663397023973726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7265776172645f62795f6964733a3a686263393430313534393466383564636298023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68663832653331633661353963616365319902437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68623639633438353461383832303864389a024a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a68323332343564323130376336323965669b025d3c73726d6c5f636f6e7472616374733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68623238613734653764656536616261629c023573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a7075743a3a68656132383836636363373062353139399d0295013c73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a68666338373537393139636464626330359e024a73726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a7365745f6d656d626572735f736f727465643a3a68373334353435373836393236393136389f02603c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6866663161323763383665616361336235a002603c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6839346636343562633634613438323938a1025d3c73726d6c5f64656d6f63726163793a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6834633966363032616161366635323337a2025b3c73726d6c5f7374616b696e673a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6835306130386461383561623933383337a3025b3c73726d6c5f696e64696365733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6863663263336164363030366362333537a4023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6837636234326363623163646638656430a5023e73726d6c5f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6837336434626463343032333438373839a6023c73726d6c5f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6839653664653439383632343434633638a702753c73726d6c5f696d5f6f6e6c696e653a3a5f5f476574427974655374727563745265636569766564486561727462656174733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861343834393433303832393066623730a8020c436f72655f76657273696f6ea90212436f72655f657865637574655f626c6f636baa02b50173725f7072696d6974697665733a3a67656e657269633a3a626c6f636b3a3a5f494d504c5f4445434f44455f464f525f426c6f636b3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073725f7072696d6974697665733a3a67656e657269633a3a626c6f636b3a3a426c6f636b3c4865616465722c45787472696e7369633e3e3a3a6465636f64653a3a6838366339653938303663353462323361ab027173726d6c5f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a696e697469616c697a655f626c6f636b3a3a6836646364623637373930646561363237ac024173725f7072696d6974697665733a3a67656e657269633a3a656e636f64655f776974685f7665635f7072656669783a3a6830323431303037333433373866356263ad027f3c7375627374726174655f7072696d6974697665733a3a6861736865723a3a626c616b65323a3a426c616b65324861736865722061732073725f696f3a3a696d703a3a6578743a3a45787465726e5472696543727970746f3e3a3a6f7264657265645f747269655f726f6f743a3a6864383135623231376565623662353738ae027973726d6c5f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a6170706c795f65787472696e7369635f776974685f6c656e3a3a6864353937356438633730303938303136af024373726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6e6f74655f66696e69736865645f65787472696e736963733a3a6866613138303832393933316463363535b0023373726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a66696e616c697a653a3a6864336430636135396133636463366566b10215436f72655f696e697469616c697a655f626c6f636bb202114d657461646174615f6d65746164617461b302483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6832636633346366303231366637336539b402683c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6832383038363338326364316363353830b502683c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6864386466343664663832656362323136b6021c426c6f636b4275696c6465725f6170706c795f65787472696e736963b7021b426c6f636b4275696c6465725f66696e616c697a655f626c6f636bb8027c7072696d69746976655f74797065733a3a636f6465633a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72207072696d69746976655f74797065733a3a483235363e3a3a7573696e675f656e636f6465643a3a6831653364343864633134353231656162b90220426c6f636b4275696c6465725f696e686572656e745f65787472696e73696373ba023873726d6c5f74696d657374616d703a3a657874726163745f696e686572656e745f646174613a3a6831356665643666626266303530666134bb021c426c6f636b4275696c6465725f636865636b5f696e686572656e7473bc0218426c6f636b4275696c6465725f72616e646f6d5f73656564bd023173726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a72616e646f6d3a3a6862666535396239643439333736653863be022b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6ebf025673725f7072696d6974697665733a3a7472616e73616374696f6e5f76616c69646974793a3a56616c69645472616e73616374696f6e3a3a636f6d62696e655f776974683a3a6832373835623536643266616336303836c0023573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a6866646234303435383937333161333065c102214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b6572c202214772616e6470614170695f6772616e6470615f70656e64696e675f6368616e6765c302204772616e6470614170695f6772616e6470615f666f726365645f6368616e6765c4021e4772616e6470614170695f6772616e6470615f617574686f726974696573c50214426162654170695f737461727475705f64617461c6020d426162654170695f65706f6368c7023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830643931356335646261613239393435c8023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6866393732346531363966663634633565c9023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836323062323465303635313838313338ca024b3c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6835363136613262363566353139636235cb0218436f6e73656e7375734170695f617574686f726974696573cc022153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b657973cd0227636f72653a3a7374723a3a66726f6d5f757466383a3a6837633338356538383431666465623434ce023a73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6831633336323939633666303661646664cf023c73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6830663633633535633736653431383736d00230636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830306439646362643565373738643963d102663c73726d6c5f6772616e6470613a3a5f5f4765744279746553747275637453746174653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837346563633864653435386537336131d2023a73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6862643337373331386533303265646230d3023c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6838613636306438646635323233653934d402703c73726d6c5f617574686f72736869703a3a5f5f47657442797465537472756374446964536574556e636c65733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864333832663030376230393064666665d5024573726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6830383763353238386134626163663933d60299013c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a44454455505f4b45595f50524546495844656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863336638346135306137323531323930d7028c013c73726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a54776f783634436f6e6361742061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654861736865723e3a3a686173683a3a6832373336666232393066643533613963d802437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6835623264626138643338653935333963d9028a013c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e2061732073725f7072696d6974697665733a3a7472616974733a3a4f6e496e697469616c697a653c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6832633433313034663564613465353663da0286013c73726d6c5f7374616b696e673a3a4d6f64756c653c543e2061732073726d6c5f73657373696f6e3a3a4f6e53657373696f6e456e64696e673c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f73657373696f6e5f656e64696e673a3a6862343239383835633937393431623834db0230636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830346237623962366364623263303261dc02683c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a73697a655f68696e743a3a6837386633396438623462363334636432dd02633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6833636537383730346330633037646361de023e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6830333036613335326664306536333630df023d73726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832353961306464656638323635323030e0023f73726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6835343766383234353438366135306431e102463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6865306265346464323831666130326239e202663c73726d6c5f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732073726d6c5f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a7b7b636c6f737572657d7d3a3a6837376364383239393538633464386562e3027d3c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6761733a3a6865613734653736656339343830643937e40289013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f73746f726167653a3a6832373065316632663362323166333864e50289013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6765745f73746f726167653a3a6864613734663730636531633637336334e60282013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c3a3a6866336337653562636230633739623831e70284013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6372656174653a3a6832383030613732333335366434616137e80284013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72657475726e3a3a6866663931646564376262393861373130e90284013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c65723a3a6866663136383535623636653666356463ea0285013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f616464726573733a3a6865333930333962663230646566366134eb0287013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f70726963653a3a6861333563656361346536663234383134ec0286013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f6c6566743a3a6834636537323964363761346535323461ed0285013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f62616c616e63653a3a6863303765646436626337663437373566ee028f013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f76616c75655f7472616e736665727265643a3a6834363264623564633033333630396438ef0284013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72616e646f6d3a3a6832303863363137636665636665616366f00281013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6e6f773a3a6862393735623466653631383265613236f1028b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f64697370617463685f63616c6c3a3a6864386532323333373533376139663335f20288013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f726573746f72655f746f3a3a6835383732663634316362343037393861f3028a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f73697a653a3a6861363061613366626132613338623862f4028a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f726561643a3a6833353139306435663464393830343263f5028b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f77726974653a3a6838366135616133643265326431343164f6028b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6465706f7369745f6576656e743a3a6833373733363338346330376532343966f70290013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f72656e745f616c6c6f77616e63653a3a6833613231313531363337613832373733f8028c013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72656e745f616c6c6f77616e63653a3a6838303766353562623462333963623034f90285013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7072696e746c6e3a3a6865336537393162303534636336633031fa028a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f626c6f636b5f6e756d6265723a3a6839313435306566323232383662386435fb023273725f73616e64626f783a3a696d703a3a64697370617463685f7468756e6b3a3a6837633036386361393732613463396237fc02ad017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f4445434f44455f464f525f547970656456616c75653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72207375627374726174655f7072696d6974697665733a3a73616e64626f783a3a547970656456616c75653e3a3a6465636f64653a3a6865333930656237616663366662333531fd02b0017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f454e434f44455f464f525f547970656456616c75653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72207375627374726174655f7072696d6974697665733a3a73616e64626f783a3a547970656456616c75653e3a3a656e636f64655f746f3a3a6862316231383534333932323433383632fe023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833616165313362393663313863393332ff023d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f65787465726e616c3a3a686437343534353137316163353764326180033b73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f7075626c69633a3a686631616133393731303637323064333981033d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a7265666572656e64756d5f696e666f3a3a68306262616566353330666666303166348203a9013c73726d6c5f64656d6f63726163793a3a566f74657273466f723c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c7533322c616c6c6f633a3a7665633a3a5665633c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a6765743a3a683333353137323362666365643064373783033573726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a766f74655f6f663a3a683664656235633530333236333330366484033d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a64656c6567617465645f766f7465733a3a683962663262626531393362383839303685033e73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a636c6561725f7265666572656e64756d3a3a68373162616466333130363466343339348603ef013c73726d6c5f64656d6f63726163793a3a446973706174636851756575653c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265722c616c6c6f633a3a7665633a3a5665633c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c283c542061732073726d6c5f64656d6f63726163793a3a54726169743e3a3a50726f706f73616c2c20753332293e3e3e3e3a3a6765743a3a683538333165316536633832386165333987033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683133316361386331656532306636626688033f73726d6c5f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a686532326235316134333034613739386489034173726d6c5f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a68353738613465313834383037306662648a0334636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a636f6e7461696e733a3a68356465363231313533636561333938658b034c3c73726d6c5f6d656d626572736869703a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68333835306563326466346630316331628c033c73726d6c5f696e64696365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68633261643539636165356633343863358d03cc013c73726d6c5f636f6c6c6563746976653a3a566f74696e673c542c493e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173682c73726d6c5f636f6c6c6563746976653a3a566f7465733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a6765743a3a68393461313166376661346261623661638e03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68633039353530386266346434323036348f03920173726d6c5f636f6c6c6563746976653a3a5f494d504c5f4445434f44455f464f525f566f7465733a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6c6c6563746976653a3a566f7465733c4163636f756e7449643e3e3a3a6465636f64653a3a68343065303966363462353731613438669003cc013c73726d6c5f636f6c6c6563746976653a3a566f74696e673c542c493e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173682c73726d6c5f636f6c6c6563746976653a3a566f7465733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a6765743a3a68356363653664343731373534363738329103483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a683061643237616562663031393863623092033c73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683737353062626463643037643137336193033e73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a683138666563333764623561646133373394034773726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6866623061613132383138346263323231950398013c73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686433396465333239346138363534333096033f73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a683030346539366438633238666534386597034173726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a683538383839366339623863323163393398034173726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a68656538353964363531306461366339309903443c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68663764303838373736613431383166629a03463c73726d6c5f73797374656d3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68313765356234643836336365383063619b03473c73726d6c5f696e64696365733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68346139316534306361613562316135399c03473c73726d6c5f7374616b696e673a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68663730346139323533653262356162309d03493c73726d6c5f64656d6f63726163793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68646237653230613337366464653933619e034c3c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68653438666534343361643664613031339f03493c73726d6c5f636f6e7472616374733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6830646261343433363238323631623032a0033773726d6c5f7375646f3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6863306337373939383131646631363134a1033973726d6c5f7375646f3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865383662336537383533633663353534a203613c73726d6c5f7375646f3a3a5f5f476574427974655374727563744b65793c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835663436323933346436393966363339a303497061726974795f7363616c655f636f6465633a3a656e636f64655f617070656e643a3a657874726163745f6c656e6774685f646174613a3a6861363539393739636263333761636634a403930173726d6c5f73797374656d3a3a5f494d504c5f454e434f44455f464f525f4576656e745265636f72643a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f73797374656d3a3a4576656e745265636f72643c452c543e3e3a3a656e636f64655f746f3a3a6835313964643238383166656535656566a50330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830393062643931663636306366616536a6033973726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6864663737666166303565326132626162a7033b73726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866323230343262643939393666376332a803693c73726d6c5f73797374656d3a3a5f5f47657442797465537472756374426c6f636b486173683c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831333062366433643865353165353363a9036e3c73726d6c5f73797374656d3a3a5f5f4765744279746553747275637452616e646f6d4d6174657269616c3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862306164336334656565303334393161aa034473726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6830393337353364656532626235623761ab033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830383732316431613536376564613731ac033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861306461356534326562393764646632ad033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861353133323561323464326335306330ae033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861646534366530356437383864366131af033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861656438316334343038383438626233b0033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864313034346237306363653161393961b1033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865353236613866336534333962366537b2033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865373432653234383330616230386339b3033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865643163396538393738633632633638b4035373725f7072696d6974697665733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a7b7b636c6f737572657d7d3a3a6866323639386362373634336330303133b5035373725f7072696d6974697665733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a7b7b636c6f737572657d7d3a3a6833373266353739373964386264373139b6034573726d6c5f636f6e7472616374733a3a7761736d3a3a707265706172653a3a436f6e74726163744d6f64756c653a3a6e65773a3a6866396465633037636462366163373331b703467061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a436f646553656374696f6e3a3a626f646965733a3a6835653661353535643235383264383234b80348616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6866366138323963323130326432653731b9033c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a66726f6d5f6d6f64756c653a3a6861353632393762323966303433313661ba03537061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a7265736f6c76655f747970655f7265663a3a6861316261313638326630323933646633bb03a9017061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c6553636166666f6c643e20666f72207061726974795f7761736d3a3a656c656d656e74733a3a6d6f64756c653a3a4d6f64756c653e3a3a66726f6d3a3a6861633764383431666461656134386630bc033a707761736d5f7574696c733a3a72756c65733a3a496e737472756374696f6e547970653a3a6f703a3a6837663032626234366239666235643333bd032d616c6c6f633a3a7665633a3a5665633c543e3a3a696e736572743a3a6831653534363162633065353731666435be03507061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a707573685f66756e6374696f6e3a3a6832636136636638623462303866353532bf0330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830663230326262346463356565323434c0033c707761736d5f7574696c733a3a737461636b5f6865696768743a3a696e6a6563745f6c696d697465723a3a6833623232653831666332613762343934c1036b3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6831626432303938386265356364303666c2036a636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653c413e20666f7220266d757420463e3a3a63616c6c5f6f6e63653a3a6832643530343666643364323333393536c3033c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6862653131303735633036636232323830c4033e73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6861343964363337373636636639633361c5036b3c73726d6c5f636f6e7472616374733a3a5f5f4765744279746553747275637447617350726963653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861343038666337613034346331386266c603723c73726d6c5f636f6e7472616374733a3a5f5f4765744279746553747275637443757272656e745363686564756c653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863336262613266313261373761613733c7034773726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6835343436366431356565353932323362c80398013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426c6f636b4761734c696d697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832623861333630363033356638363932c90397013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d617856616c756553697a6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864383632376638633637316661336135ca0393013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178446570746844656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830386531343162656136623036363365cb0396013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a43616c6c4261736546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835346362633237613638373230393939cc0396013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a436f6e747261637446656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864666164343934396165373830323339cd039d013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5472616e73616374696f6e4279746546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837643937363438323333393262653265ce039a013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53757263686172676552657761726444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863633039396430633865643830643162cf039c013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a52656e744465706f7369744f666673657444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861383537303136316138373334663730d00396013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a52656e744279746546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861313161353736306636313237336662d1039c013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53746f7261676553697a654f666673657444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838333835383032363334653562336639d2039b013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a546f6d6273746f6e654465706f73697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832663265363164333630336336326438d3039e013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5369676e6564436c61696d48616e646963617044656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834343564303633636466383337636537d403c40173726d6c5f636f6e7472616374733a3a5f494d504c5f454e434f44455f464f525f526177416c697665436f6e7472616374496e666f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6e7472616374733a3a526177416c697665436f6e7472616374496e666f3c436f6465486173682c42616c616e63652c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6835623566356134666332643133373362d503437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6838313030366432613139363036313139d603f0013c73726d6c5f7374616b696e673a3a5f5f6c696e6b65645f6d61705f64657461696c735f666f725f6e6f6d696e61746f72735f646f5f6e6f745f7573653a3a456e756d657261746f723c532c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c28616c6c6f633a3a7665633a3a5665633c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e2c2054293e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6833636539383438363130643636336233d70380023c73726d6c5f64656d6f63726163793a3a5f5f6c696e6b65645f6d61705f64657461696c735f666f725f64656c65676174696f6e735f646f5f6e6f745f7573653a3a456e756d657261746f723c532c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c28283c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c2073726d6c5f64656d6f63726163793a3a436f6e76696374696f6e292c2054293e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6830643135663934303539353539646135d803d0023c73726d6c5f7374616b696e673a3a5f5f6c696e6b65645f6d61705f64657461696c735f666f725f76616c696461746f72735f646f5f6e6f745f7573653a3a456e756d657261746f723c532c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c2873726d6c5f7374616b696e673a3a56616c696461746f7250726566733c3c3c542061732073726d6c5f7374616b696e673a3a54726169743e3a3a43757272656e63792061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e2c2054293e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6832306238646261393563666665636665d9033973726d6c5f636f6e7472616374733a3a6761733a3a726566756e645f756e757365645f6761733a3a6837383463396263653861336131636533da033873726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a726573746f72655f746f3a3a6833613437626533343536383030323037db03483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a72656d6f76653a3a6865636232646233366531616633623662dc03483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a72656d6f76653a3a6837333534333263363965363563643462dd03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6831356362666331623635363864613733de03bb0173726d6c5f7374616b696e673a3a5f494d504c5f454e434f44455f464f525f5f5f4c696e6b616765466f724e6f6d696e61746f7273446f4e6f745573653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f7374616b696e673a3a5f5f4c696e6b616765466f724e6f6d696e61746f7273446f4e6f745573653c4b65793e3e3a3a656e636f64655f746f3a3a6862646133323037643266613563313166df033a73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6830396333643261353566356661353039e0033c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6832623062636235653736333261646262e103723c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637443757272656e74457261526577617264733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864366332613234346434633966663138e203703c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637443757272656e7445726153746172743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864643834653439643038366232363934e303683c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563745374616b6572733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865643262376437383731633161393565e4036b3c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637456616c696461746f72733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837346364633736306437613030636134e5036d3c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563744f66666c696e65536c6173683c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835366166323535393262343534363135e603763c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563744d696e696d756d56616c696461746f72436f756e743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837306633633862383633383130613363e7034573726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6861626530386438333330393939373438e80398013c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426f6e64696e674475726174696f6e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864373363383237363639306237323061e9033373726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7374616b6572733a3a6863366134663830336364383464653464ea033773726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d616b655f7061796f75743a3a6837643166336137313735306132326561eb0344636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a73697a655f68696e743a3a6833323236316661303831373232356664ec033973726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7570646174655f6c65646765723a3a6831393734376131313534386631663364ed0330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830646434613164636362326132636435ee033e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6837346562656431303134633266303237ef03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6862646432373135396662613161323063f0033f73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a696e6a6563745f7265666572656e64756d3a3a6833633939633739396230386437313534f1033873726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6465706f7369745f6f663a3a6865636565366166353764376161333735f2033c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6835346538643332396139666132663638f3033e73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865383838316637326130373865613135f4036c3c73726d6c5f64656d6f63726163793a3a5f5f47657442797465537472756374426c61636b6c6973743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832333461393665306430323936613335f5036f3c73726d6c5f64656d6f63726163793a3a5f5f476574427974655374727563744e65787445787465726e616c3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832633434636131353831313366373535f6036e3c73726d6c5f64656d6f63726163793a3a5f5f4765744279746553747275637444656c65676174696f6e733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861623538663136633833333338386566f703703c73726d6c5f64656d6f63726163793a3a5f5f47657442797465537472756374446973706174636851756575653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830333933316565633336353634623365f8034773726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864316666666265346438316362363730f90397013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4c61756e6368506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863623434386336653063626433376362fa03a0013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456d657267656e6379566f74696e67506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833363138656437663661343938383130fb0399013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d4465706f73697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861303538613535303838646264386338fc039a013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456e6163746d656e74506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832616561313564356566633462663462fd03443c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6866376430383837373661343138316662fe03483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6834303661636364376534643331336337ff03b5013c73726d6c5f64656d6f63726163793a3a50726f78793c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6765743a3a683265373962366233626364333137303080043573726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a646f5f766f74653a3a68363364356434383233623131646236328104ef013c73726d6c5f64656d6f63726163793a3a426c61636b6c6973743c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173682c283c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265722c20616c6c6f633a3a7665633a3a5665633c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e293e3e3a3a6765743a3a68303239633730396638643037353831318204683c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a683664393335333839373336373638306483046b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a683135313738306562653934363739313384047d3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973745772697465723c492c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a683235323965613062323865376135346485046f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a686135363034363538343563643533643386046f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743634206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a683131636261643839333861393064613187046c3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a686462613634353735316439313963363088046f3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a68353363353465393563396333626233388904443c7061726974795f7761736d3a3a696f3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68333638383133363166623465663263668a0425616c6c6f633a3a666d743a3a666f726d61743a3a68643763346335363338353636616230398b04793c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973743c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a68636139393434653637313333376230368c046b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a68666163323231313639383033366233618d04713c7061726974795f7761736d3a3a656c656d656e74733a3a696e6465785f6d61703a3a496e6465784d61703c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a68646532346562333561666632336562328e04783c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a68633934386234333634396238313339378f047c3c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6831656438636339373431623565656432900482017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a3c696d706c207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a6520666f7220616c6c6f633a3a737472696e673a3a537472696e673e3a3a73657269616c697a653a3a6866383833666364346466363833623162910486017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a3c696d706c207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a6520666f7220616c6c6f633a3a737472696e673a3a537472696e673e3a3a646573657269616c697a653a3a68643263653432376264613631363536349204323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a686663336633643330393833623232353193042c636f72653a3a666d743a3a466f726d61747465723a3a7061643a3a68666631303739666431333639376233339404743c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a56617255696e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a68353938333365346536393239346161629504713c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a437573746f6d53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a686130366134383234373137643166313996046f3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a68646139366130656531653064323239359704457061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e5265616465723a3a6e65773a3a683735643633653437326166306638303998044e636f72653a3a666d743a3a6e756d3a3a696d703a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f72207533323e3a3a666d743a3a68336462646430663735643064303662309904397761736d695f76616c69646174696f6e3a3a76616c69646174655f6d656d6f72795f747970653a3a68666335353931663238353066326239659a04347761736d695f76616c69646174696f6e3a3a657870725f636f6e73745f747970653a3a68656264643462326433366132343830369b04553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68656561373932353138616238356639359c044a7761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a737465703a3a68613231623430373966613366656436619d04473c7761736d695f76616c69646174696f6e3a3a4572726f7220617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68386330313739343335383463306566339e04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68313865633037343436346561303864659f04416861736862726f776e3a3a7261773a3a5261775461626c653c543e3a3a7472795f776974685f63617061636974793a3a6866613764663139356631353039326230a0043e6861736862726f776e3a3a7261773a3a5261775461626c653c543e3a3a726573657276655f7265686173683a3a6833333462393935646661383539626134a104457061726974795f7761736d3a3a656c656d656e74733a3a7365676d656e743a3a446174615365676d656e743a3a76616c75653a3a6836666366336139336337363466663239a20437616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6831306437636466366264353063306138a3043b636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a636f70795f66726f6d5f736c6963653a3a6838666665333530336630333966653637a404347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f76616c75653a3a6862636432636433643664313539313131a504347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f6c6162656c3a3a6862353864373362326236303263356338a604407761736d695f76616c69646174696f6e3a3a7574696c3a3a4c6f63616c733a3a747970655f6f665f6c6f63616c3a3a6835336638303133346430396365353338a704543c7761736d695f76616c69646174696f6e3a3a66756e633a3a537461636b56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6834323630393137373566353065373335a804537761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f6c6f61643a3a6830666530353637646634313565303830a904547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f73746f72653a3a6836343831366461313832353161393364aa04557761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f746573746f703a3a6837633361336566656463343337383266ab04547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f72656c6f703a3a6866303134313436626433316534313762ac04537761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f756e6f703a3a6834333861323731306431663330313066ad04547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f62696e6f703a3a6830383964643835663232356431343336ae04547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f6376746f703a3a6833643162643361393839356261366533af04553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a426c6f636b5479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6865306333623161386665303165633866b00439636f72653a3a666d743a3a6275696c646572733a3a44656275675475706c653a3a6669656c643a3a6836656537346534333039366131376439b10430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830366266386636353839656239343162b20430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6836303864393331383235343033383132b304303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6834383234393832626634393662336162b404453c616c6c6f633a3a737472696e673a3a537472696e6720617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6832646462323137376530333166613835b50423636f72653a3a666d743a3a77726974653a3a6839333633326337643033326561343638b6044c3c7761736d695f76616c69646174696f6e3a3a737461636b3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6865663033363161663731346134643663b704553c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832303633366265663837633738363461b804303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832313765353138386132346630616461b9043a636f72653a3a666d743a3a6275696c646572733a3a44656275675374727563743a3a6669656c643a3a6865383864336131323366383730373832ba0441707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a636f6d707574653a3a6836326566306165663138633338326661bb045a3c707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a4672616d6520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6831366461373838396539666336323662bc0446707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a6672616d653a3a6839393266666465383836333563613535bd04453c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c543e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832313263393630353433363939303161be044b707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a706f705f76616c7565733a3a6831653832313935383362613030623863bf043f707761736d5f7574696c733a3a737461636b5f6865696768743a3a7265736f6c76655f66756e635f747970653a3a6836633834316630393864653935396264c00433636f72653a3a6f7074696f6e3a3a4f7074696f6e3c26543e3a3a636c6f6e65643a3a6838633139376264356561643438643933c104533c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a6834386138633063333762343963626631c204323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6835333231663034383064306266653134c304613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6832336564346436386530313364323065c404303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6836346562613066656334653933386232c504303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6831353430356262616337383538393663c604303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838663462376362383535333861663138c704303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862363063396333663532656166646538c804463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6834353238333930656664323762613338c904303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830346163346666393137356464653030ca04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839313138306134663333666366303034cb04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6863613534626362393066363435393237cc04383c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a6834333134336430636534313465386633cd04343c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a6861636432356666393666663062343134ce04363c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a666c7573683a3a6865653936353737386662623832643737cf04323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6836313738613030333334663561373330d004323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6839616566383235616539653730303930d104323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6830666531623664623462663262636638d20411727573745f626567696e5f756e77696e64d3044e73725f696f3a3a696d703a3a6578743a3a65787465726e5f66756e6374696f6e735f686f73745f696d706c3a3a6578745f7072696e745f757466383a3a6839656666356362333033373663303437d40430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6862316238333037353039303066353931d5040a5f5f72675f616c6c6f63d6040c5f5f72675f6465616c6c6f63d7040c5f5f72675f7265616c6c6f63d804115f5f72675f616c6c6f635f7a65726f6564d9043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6836323130386463346536396162356461da043b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6839326334633164656235383732383039db043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a6831383737376664373066636134616436dc04313c5420617320636f72653a3a616e793a3a416e793e3a3a747970655f69643a3a6863376539376432336334343031616461dd0443636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a77726974655f7072656669783a3a6866353739323864636432363165643336de042e636f72653a3a7374723a3a736c6963655f6572726f725f6661696c3a3a6831363365316338303737343135326331df044a3c636f72653a3a6f70733a3a72616e67653a3a52616e67653c4964783e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832386561383230636339623134613633e004323c6368617220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6833363436396430663335626433316330e1043d636f72653a3a756e69636f64653a3a626f6f6c5f747269653a3a426f6f6c547269653a3a6c6f6f6b75703a3a6837383739366463316163303430646364e2044e636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a68303032326231343762373361613638322e32383133e30434636f72653a3a666d743a3a417267756d656e7456313a3a73686f775f7573697a653a3a6864383031626235373566376562393161e404453c636f72653a3a63656c6c3a3a426f72726f774572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838333264636132343436363033363537e504483c636f72653a3a63656c6c3a3a426f72726f774d75744572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6865666438626331333133666237396165e604303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6833303638343935663833376230316464e7042e636f72653a3a736c6963653a3a6d656d6368723a3a6d656d6368723a3a6861303831383836616536616630613231e8048001636f72653a3a7374723a3a7472616974733a3a3c696d706c20636f72653a3a736c6963653a3a536c696365496e6465783c7374723e20666f7220636f72653a3a6f70733a3a72616e67653a3a52616e67653c7573697a653e3e3a3a696e6465783a3a7b7b636c6f737572657d7d3a3a6833316463643933376162353865333164e90430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830633265616634383732313435613930ea04533c636f72653a3a666d743a3a6275696c646572733a3a5061644164617074657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6839376430303239666633316637396366eb042f636f72653a3a666d743a3a57726974653a3a77726974655f636861723a3a6839623134626561303263303534316330ec042e636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a6836396661333266396337306532303163ed043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6834316530363363373237653132323935ee043b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6838396661663833336237616264326133ef043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a6838303733616330326435373331613136f004303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832373333653662396330656136666132f104303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832663435616232666237326439623730f204423c636f72653a3a7374723a3a557466384572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832633861613936646264306262346130f304303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838366434386330303335636663343265f4043e3c636f72653a3a666d743a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6861383238366138363432326238666461f504066d656d736574f604066d656d637079f704076d656d6d6f7665f804066d656d636d70f904095f5f6173686c746933fa04095f5f6c736872746933fb04085f5f6d756c746933fc04095f5f75646976746933fd04095f5f756d6f64746933fe040c5f5f756469766d6f6474693400550970726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d62790105727573746325312e33382e302d6e696768746c79202832643161353531653120323031392d30382d303829", + "0xd368b9d9bb1cc910c9a2b8e5d0f5f2fc": "0xf6ffc06ff28623000000000000000000", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579731143fa96e07eb73af3db3a1b057d18899f864e6fc5d2f905f9296ca641565564": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797397dddc7aba561f16ac00da4bae75ab812aa7b81418bebdab74425f0d6aa31cee": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", "0xbde3e43a2a348359d103d64bc95928146bdd9ae3490e26da38d2e4d19c137507": "0x0000a0dec5adc9353600000000000000", - "0x040ff70c23416b89ce6afb75ee0d362e": "0x00000000", - "0xfff675c76ad8a5dfbd7db9a4e80f7c0ece595ad1878d2b6fca6086b2483a055b": "0x0000c16ff28623000000000000000000", - "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b657973e54094c2d5af8ae10b91e1288f4f59f2946d7738f2c509b7effd909e5e9ba0ad": "0x5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a", - "0x78f4ad73d6b7279f8d06f359e363c829": "0x0000a49d8fc957363600000000000000", - "0x52b963fbdb3d6e1b03808fc20071f07f": "0x00270600", - "0x4664fb5d4e16f894df23cadb3faaa9a6": "0x04000000", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797301dd273832961ca94116fd224019ea1370c0e3d27bebb1041b35651146d17832": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", - "0x4ac2684a5a20e7a5adf17ed7aa792a3f6334a0505f02b2a44c3934d36cc4ee0a": "0xc8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e", - "0x633daafcb669e97549c1b9d65660881016f969040bc16171709159437c31294a": "0x0f0000c16ff286230f0000c16ff2862300", - "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b6579737f325c981c2b001f5fe8c51cc7b89e50ebb1f60feb7ab3fa3bc79d6ab71d45cb": "0x9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", - "0x72143961950b9317e15506626c4524c4": "0x1000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", - "0x8cb577756012d928f17362e0741f9f2c": "0x01000000", - "0x7eb7a404bf7e3466c3f6c5914e25edfaab48b1e24fd29ea5a94deaaa1aba80e6": "0x0c0001547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65019c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0xdfaac108e0d4bc78fc9419a7fcfa84dc": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d6568655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde789c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0xfacbe054606f2488121046f9c5539d98": "0x00", - "0x3ae31af9a378162eb2736f26855c9ad8": "0x4545454545454545454545454545454545454545454545454545454545454545", + "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", - "0x26ac4a74e1ba94e0e7dbfc3b2aea083cf3c0f0d80eb999c7cebb340ee8934da9": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde780f0000c16ff286230f0000c16ff2862300", - "0xccea67b51b4fa33ecbff70a8977ad91d9c60d620f3ab5ac9626dea15cde023b7": "0x0f0000c16ff286230f0000c16ff2862300", - "0xe026dd082e3158e72eb7c985fc8bac4f": "0x40380000", - "0xbf18c0c65fb39f32ee7c8016685c0a6056f8f924192efb2655be9a692d0b03b6": "0x00", - "0x7c79972b34b7e51bdd5f168ba3accd35fbec396be75dfad19dd1121327f1a1ad": "0x0c000168655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde7800", + "0xeecb67c20ca6cc8ba4d4434687f61309": "0x103919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef01000000000000005633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce44001000000000000007932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f01000000000000009becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993320100000000000000", + "0x154ebcb2c318b2e1c23e43e65aea27cd1348c4c5157502d7669a31c7635019cc": "0x9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526", + "0x633daafcb669e97549c1b9d65660881016f969040bc16171709159437c31294a": "0x0ff6ffc06ff286230ff6ffc06ff2862300", + "0xfacbe054606f2488121046f9c5539d98": "0x00", + "0x0c41b62474c49057a4476d0b96853c6d44e9c86c5fa130b0da3831c5eef546a0": "0x00", "0xc1bc13c775b3406279618b05c28523cb": "0x00", - "0xf186665804ca50670311307912458ce448d82cb96e7e4fe71df38c283a8720f4": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d120f0000c16ff286230f0000c16ff2862300", - "0x686f6c72b7b80bad8dba022335cb7c9e4556ac7ea200008da8046e3178eb89c1": "0x0f0000c16ff286230f0000c16ff2862300", - "0x71020fee971bd00e8248d1830b8cffbe5b9cf4de1ea2911a1665c44fd70ab6f3": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26630f0000c16ff286230f0000c16ff2862300", - "0x90e2849b965314409e8bc00011f3004f": "0x04000000", - "0x1ba14d232d3c301a93e35f55e3d7aef2d98dbb9cc0ce48f457b81b421e0f704d": "0x0000c16ff28623000000000000000000", - "0xb49a6659ec27619e87dd18e11b6838c0": "0x00", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797340944475c781bbdc9726766a78b1964888e039600b1c865c62586ab8f98c171e": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", - "0x125dc846383907f5846f72ce53ca0e4b": "0x00ca9a3b000000000000000000000000", - "0xb2029f8665aac509629f2d28cea790a3": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26633919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d655633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde787932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d129becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", + "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b657973711590f60a214f6f06502eb29dd14f55aa04e72e2fa12c098ba4fa5a00c57fa9": "0x7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e", + "0x75f6361fd25fec35714be80f2d9870af8c92e73cb6d299ba4774f5b0ad842275": "0x00", + "0x579ab55d37b1220812be3c3df29d4858": "0x00000000", + "0x4e62513de81454ce76df887573f7f98b101eb4585b1485a222b7db599f4e93e2": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0f", "0xa902f1f0ef97177b8df9f9fd413768e7": "0x00000000", - "0xc63b8a0db7e72fd87c88d8dcf4777b883f86728613c57148c4e5cdceb05b7a1a": "0x0c0001f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26630168655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973be035f25cd43adc80f1dcf505f5ffd158d1592ab3719f354a256a4c3b7571934": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", - "0xc98362e2ca21b342cc749022ed9b560e4d29ec9862a960c2538c314f1d279635": "0x149ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e3180973474718099c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d1268655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0x68c8d2f39c4605e65218c22c5664917047e4900c797b7dd33999d94213c75049": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0e", - "0x46cef122497fefa60faf6c66d3ef05caf9870446796ae11f0a4f734fee993d8b": "0x00", - "0x886726f904d8372fdabb7707870c2fad": "0x1000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f43780100000000000000482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a0100000000000000482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e01000000000000006e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91060100000000000000", - "0xd368b9d9bb1cc910c9a2b8e5d0f5f2fc": "0x0000c16ff28623000000000000000000", - "0xfd0cbba69a04d769ddcdbb15f5123c98041978f5241f33f78f62b48e3a02b740": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0e", - "0x2b334d6ac6698775ed17edf8cd3cbd9dae56cead0d69cb54f6af6aaecba544d8": "0x0f0000c16ff286230f0000c16ff2862300", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797397dddc7aba561f16ac00da4bae75ab812aa7b81418bebdab74425f0d6aa31cee": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579731143fa96e07eb73af3db3a1b057d18899f864e6fc5d2f905f9296ca641565564": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0x6e4ab2ac5a7cf9b1829eacc84a75bde0804be01fc31c9419ea72407f50a33384": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0x92f53c21a80e624b3c606bc8ec0ce2a3003c4fe385bed33998bf4dc79b8970f2": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d650f0000c16ff286230f0000c16ff2862300", - "0x0c41b62474c49057a4476d0b96853c6d44e9c86c5fa130b0da3831c5eef546a0": "0x00", - "0x87e6cbd186029472cea8c1748f99126b": "0x00000000", - "0xc1fdc3d212357bc2fa98f2a77b941f0c": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d6568655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde789c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0x2d5205eddfc20f1a616c0391abb78a3920e823abe7ed33cfd7945dd1a1bf8651": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0e", - "0xdfa1667c116b77971ada377f9bd9c485a0566b8e477ae01969120423f2f124ea": "0x4545454545454545454545454545454545454545454545454545454545454545", - "0x637414312dac3b280120bf15b4f66cee": "0x00000000", - "0xf14d23a9d4492a1efc9194e257b3c3d9": "0x00000000", + "0x1ba14d232d3c301a93e35f55e3d7aef2d98dbb9cc0ce48f457b81b421e0f704d": "0x0000c16ff28623000000000000000000", "0x2dce29f1a768624dc5343063cb77f77d": "0x07000000", - "0x154ebcb2c318b2e1c23e43e65aea27cd1348c4c5157502d7669a31c7635019cc": "0x9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526", - "0xbc3717660105a864bd63dcd430de64128d58bd0917fa8dd75aee827cf086e19c": "0x0000c16ff28623000000000000000000", + "0xa978690c6b811e943721dbb6cb9b6246": "0x0000000000000000", + "0x8b4621d5f16433d6024b5a31547c59ee24e749e051dbb4bc7e64502f2a4f62fb": "0x66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f", + "0x8cb577756012d928f17362e0741f9f2c": "0x01000000", + "0xc63b8a0db7e72fd87c88d8dcf4777b883f86728613c57148c4e5cdceb05b7a1a": "0x0001f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26630168655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0x637414312dac3b280120bf15b4f66cee": "0x00000000", + "0xbf18c0c65fb39f32ee7c8016685c0a6056f8f924192efb2655be9a692d0b03b6": "0x00", + "0x3a636f6465": "0x0061736d01000000019f022660037f7f7f017f60027f7f017f60027f7f0060017f0060057f7f7f7f7f0060037f7f7f0060047f7f7f7f0060017f017e60057f7f7f7f7f017f60067f7f7f7f7f7f0060047f7f7f7f017f60017e0060067f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f6000017f60077f7f7f7f7f7f7f017f60017f017f60027f7f017e60000060037e7f7f017f60047f7f7e7e0060077f7f7e7e7f7f7f0060087f7f7f7f7f7e7e7f0060057f7f7f7e7e0060077f7f7f7e7e7f7f0060037f7e7e0060057f7f7e7e7f0060077f7e7e7f7f7f7f0060067f7f7e7e7f7f0060077f7f7f7f7f7e7e0060047f7f7f7f017e6000017e60077f7f7f7e7e7e7f0060067f7f7f7e7e7f0060037f7e7f0060047f7e7e7f0060057f7e7e7e7e0060067f7e7e7e7e7f0002af082803656e760e6578745f626c616b65325f323536000503656e761f6578745f6765745f616c6c6f63617465645f6368696c645f73746f72616765000803656e76176578745f636c6561725f6368696c645f73746f72616765000603656e76146578745f6765745f73746f726167655f696e746f000803656e76166578745f6b696c6c5f6368696c645f73746f72616765000203656e76156578745f7365745f6368696c645f73746f72616765000903656e76196578745f6765745f616c6c6f63617465645f73746f72616765000003656e760f6578745f7365745f73746f72616765000603656e760c6578745f74776f785f313238000503656e76116578745f636c6561725f73746f72616765000203656e76126578745f737232353531395f766572696679000a03656e760e6578745f7072696e745f75746638000203656e760d6578745f7072696e745f6e756d000b03656e76166578745f6368696c645f73746f726167655f726f6f74000003656e76106578745f636c6561725f707265666978000203656e76166578745f73616e64626f785f6d656d6f72795f6e6577000103656e761b6578745f73616e64626f785f6d656d6f72795f74656172646f776e000303656e76176578745f73616e64626f785f696e7374616e7469617465000c03656e76126578745f73616e64626f785f696e766f6b65000d03656e761d6578745f73616e64626f785f696e7374616e63655f74656172646f776e000303656e76106578745f73746f726167655f726f6f74000303656e76186578745f73746f726167655f6368616e6765735f726f6f74000003656e76126578745f656432353531395f766572696679000a03656e76166578745f73616e64626f785f6d656d6f72795f676574000a03656e76166578745f73616e64626f785f6d656d6f72795f736574000a03656e760d6578745f7072696e745f686578000203656e76106578745f69735f76616c696461746f72000e03656e76156578745f6c6f63616c5f73746f726167655f676574000a03656e76216578745f6c6f63616c5f73746f726167655f636f6d706172655f616e645f736574000f03656e76116578745f6e6574776f726b5f7374617465001003656e76106578745f737232353531395f7369676e000803656e76166578745f7375626d69745f7472616e73616374696f6e000103656e76156578745f6c6f63616c5f73746f726167655f736574000403656e76146578745f656432353531395f67656e6572617465000603656e76146578745f737232353531395f67656e6572617465000603656e76236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f74000603656e760a6578745f6d616c6c6f63001003656e76086578745f66726565000303656e76176578745f737232353531395f7075626c69635f6b657973000103656e760b6578745f74776f785f3634000503fd04fb0410100303000010101112030205001202060001010201021303070c0a0200060101011001010101010201060305030001010001010800010001010101010102030203030202020202020203020202020202020202020202020202020502020202050304050205010205020202140303020e02020303030202020201020102020405020202020202020202030202150101160509021706030505180602030202020205050505000314141212030212120501030303030303030303030303030303020202020202020502020202051202020303120e050502020502141406060505050502020205171919120503020302031a02020202021b020303030203140303051c1905050202020502050201010303020202020503020203020202060605030302020302020202020202021d0206030302020303030205020503030302020202020312020206020202030202050205060202051206090606060606060606060606060606060606060606060606061e02020203030203021f1203020302020505020203030302020203030202030303050510120202020202120202030202031010020202040302060202020303030203030202010a020202020202030b03030202030202020202020202020220030321060202020102010602030505020202030302021111021111050202111111021111110511031111111111111111030303030202020202020202030214020204020303020202020302020202020a0101010101010102010101010102010105020102050503050202010101050501010205050405220202020505040202050303030302020204020201050102060501050606050501040405050505060303010101000000002323242424250407017001de01de0105030100120619037f01418080c0000b7f004188b1c6000b7f004188b1c6000b078d0518066d656d6f72790200195f5f696e6469726563745f66756e6374696f6e5f7461626c6501000a5f5f646174615f656e6403010b5f5f686561705f62617365030209686173685f7465737400300c436f72655f76657273696f6e008c0412436f72655f657865637574655f626c6f636b008d0415436f72655f696e697469616c697a655f626c6f636b008f04114d657461646174615f6d657461646174610090041c426c6f636b4275696c6465725f6170706c795f65787472696e7369630094041b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b00950420426c6f636b4275696c6465725f696e686572656e745f65787472696e736963730096041c426c6f636b4275696c6465725f636865636b5f696e686572656e747300980418426c6f636b4275696c6465725f72616e646f6d5f736565640099042b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e009a04214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b6572009c041e4772616e6470614170695f6772616e6470615f617574686f726974696573009e0415426162654170695f636f6e66696775726174696f6e009f0421417574686f72697479446973636f766572794170695f617574686f72697469657300a0041a417574686f72697479446973636f766572794170695f7369676e00a1041c417574686f72697479446973636f766572794170695f76657269667900a2041d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e636500a30411436f6e7472616374734170695f63616c6c00a4042153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b65797300a50409a403010041010bdd013d4c5147e50448495ea201a401fd02ff0280038103820383038403850386038703880389038a038b038c038d038e038f0390039103920393039403950396039703d801ca04d0048605d2048205e604d804e204d4044f8c05d10497059405393a3b8901644155565758595a5b6160636566678a018b018d018e01900192014e4d9d03be04b301be01a701bf01a801b601c001bb01f20262ad03ac03d901b103a203a403d503d403d6039c039b03c403da01a202a002db01a402a904a804dc01b204dc02db02dd01dd02ba04b904de01bf04b603b503df01b703c802c702e001cb02d903d803e101b602b702d802d702e201e302e202e301e402e703e603e401ea0389048804e501a702a602e601b201e701a302cd02ef03f003c902b402b502b902b802ca02bb04d202d102d002cf02ce02cc02f303d902ac04de02e802e702e502f602f402f702f302f502a303a603a503b003af03ae03d703e903e803f403f203f103ee03ed03ec03eb038a04af04ae04ad04ab04aa04b304bd04bc04c304c204c104c004cc04ce04cb04c904c704c804cf04e104d5049505980596050ac3c540fb040600200010290b0600200010240b06002000102b0b0600200010250b0a00200020012002102d0b2801017f0240200210242203450d002003200020022001200120024b1b109a051a200010250b20030b06002000102f0b1c01017f0240200010242201450d002001410020001099051a0b20010bfa0202017f037e230041206b220224002001ad42adfed5e4d485fda8d8007e42c3007c210302400240024002400240200141084b0d00200141014b0d0120010d02420021040c030b0240200141104b0d00200241106a2000290000200385420042adfed5e4d485fda8d8004200109f05200241186a29030020022903107c200120006a41786a2900008521040c040b200120006a41786a2900002105200321040340200029000020048542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e2003852103200041086a2100200442cf829ebbefefde82147c2104200141786a220141084b0d000b200320058521040c030b0240200141034b0d00200120006a417e6a33000042108620003300008420038521040c030b200120006a417c6a35000042208620003500008420038521040c020b200031000021040b200420038521040b20022004420042adfed5e4d485fda8d8004200109f05200241086a290300210420022903002103200241206a2400200420037c0b0a00418080c0001032000b5b02017f037e230041306b220124002000290208210220002902102103200029020021042001420437031020014201370204200120043703182001200141186a36020020012003370328200120023703202001200141206a103e000b870301067f230041306b2202240020012802002103024002402001280204220441037422050d00410021060c010b200341046a2107410021060340200728020020066a2106200741086a2107200541786a22050d000b0b024002400240024002400240200141146a2802000d00200621070c010b024020040d0041ac80c000410041001034000b024002402006410f4b0d002003280204450d010b200620066a220720064f0d010b4101210541002107200241086a21060c010b2007417f4c0d01200241086a2106024020070d0041012105410021070c010b200710282205450d020b200241003602102002200736020c200220053602082002200241086a360214200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318200241146a41bc80c000200241186a10350d0220002006290200370200200041086a200641086a280200360200200241306a24000f0b1036000b200741011037000b41d480c0004133200241186a418881c0001038000b6c01017f230041306b2203240020032002360204200320013602002003411c6a41023602002003412c6a41013602002003420237020c200341e883c000360208200341013602242003200341206a360218200320033602282003200341046a360220200341086a2000103e000bbd0801087f230041c0006b22032400200341246a2001360200200341346a200241146a2802002204360200200341033a00382003412c6a2002280210220520044103746a36020020034280808080800437030820032000360220410021062003410036021820034100360210200320053602302003200536022802400240024002400240200228020822070d0020022802002108200228020422092004200420094b1b220a450d0141012104200020082802002008280204200128020c1100000d04200841086a210241012106034002402005280200200341086a200541046a280200110100450d00410121040c060b2006200a4f0d02200241046a210020022802002101200541086a2105200241086a210241012104200641016a2106200328022020012000280200200328022428020c110000450d000c050b0b20022802002108200228020422092002410c6a2802002205200520094b1b220a450d0041012104200020082802002008280204200128020c1100000d03200741106a2105200841086a21024101210603402003200541786a28020036020c2003200541106a2d00003a003820032005417c6a28020036020841002101410021040240024002400240200541086a2802000e0400010203000b2005410c6a2802002100410121040c020b02402005410c6a2802002207200328023422044f0d0041002104200328023020074103746a22072802044102470d0220072802002802002100410121040c020b41a089c000200720041034000b4100210420032802282207200328022c460d002003200741086a3602284100210420072802044102470d0020072802002802002100410121040b2003200036021420032004360210024002400240024002400240024020052802000e0404010006040b20032802282200200328022c470d010c050b200541046a2802002200200328023422044f0d01200328023020004103746a22002802044102470d04200028020028020021040c030b2003200041086a36022820002802044102470d03200028020028020021040c020b41a089c000200020041034000b200541046a28020021040b410121010b2003200436021c2003200136021802400240200541706a2802004101460d0020032802282204200328022c460d042003200441086a3602280c010b200541746a2802002204200328023422004f0d04200328023020044103746a21040b02402004280200200341086a200441046a280200110100450d00410121040c050b2006200a4f0d01200241046a210020022802002101200541246a2105200241086a210241012104200641016a2106200328022020012000280200200328022428020c110000450d000c040b0b0240200920064d0d00410121042003280220200820064103746a22052802002005280204200328022428020c1100000d030b410021040c020b41f087c0001032000b41b089c000200420001034000b200341c0006a240020040b05001031000b0e0041a6f4c500412210e70400000b810101017f230041c0006b220424002004200136020c2004200036020820042003360214200420023602102004412c6a41023602002004413c6a41033602002004420237021c200441b8c2c200360218200441043602342004200441306a3602282004200441106a3602382004200441086a360230200441186a4188afc000103e000bb10101037f0240024002400240200028020022002802042203200028020822046b2002490d00200028020021030c010b200420026a22052004490d02200341017422042005200420054b1b22044100480d020240024020030d002004102821030c010b200028020020032004102c21030b2003450d012000200436020420002003360200200028020821040b2000200420026a360208200320046a20012002109a051a41000f0b200441011037000b1031000ba70401047f230041106b220224002000280200210002400240024002400240024002402001418001490d002002410036020c2001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c040b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c030b0240200028020822032000280204470d00200341016a22042003490d06200341017422052004200520044b1b22044100480d060240024020030d002004102821030c010b200028020020032004102c21030b2003450d022000200436020420002003360200200028020821030b200028020020036a20013a00002000200028020841016a3602080c030b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b200441011037000b0240024020002802042204200028020822036b2001490d00200028020021040c010b200320016a22052003490d03200441017422032005200320054b1b22034100480d030240024020040d002003102821040c010b200028020020042003102c21040b2004450d022000200336020420002004360200200028020821030b2000200320016a360208200420036a2002410c6a2001109a051a0b200241106a240041000f0b200341011037000b1031000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41bc80c000200241086a10352101200241206a240020010b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420237020c2002418486c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a419486c000103e000b0d00200035020041012001103f0b4702017f017e230041206b2202240020012902002103200241146a20012902083702002002200337020c20022000360208200241f883c0003602042002410136020020021040000bd40203027f017e037f230041306b22032400412721040240024020004290ce005a0d00200021050c010b412721040340200341096a20046a2206417c6a200020004290ce0080220542f0b17f7e7ca7220741ffff037141e4006e220841017441ba84c0006a2f00003b00002006417e6a2008419c7f6c20076a41ffff037141017441ba84c0006a2f00003b00002004417c6a2104200042ffc1d72f5621062005210020060d000b0b02402005a7220641e3004c0d00200341096a2004417e6a22046a2005a7220741ffff037141e4006e2206419c7f6c20076a41ffff037141017441ba84c0006a2f00003b00000b024002402006410a480d00200341096a2004417e6a22046a200641017441ba84c0006a2f00003b00000c010b200341096a2004417f6a22046a200641306a3a00000b2002200141b8aec6004100200341096a20046a412720046b10422104200341306a240020040b6601017f230041c0006b220124002001200036020c200141346a410136020020014201370224200141b0aec6003602202001410536023c2001200141386a36023020012001410c6a360238200141106a200141206a10332001280210200128021810e70400000b0d0042c8dfc497e99ce988eb000be00501057f024002402001450d00412b418080c4002000280200220641017122011b2107200120056a21080c010b200541016a210820002802002106412d21070b0240024020064104710d00410021020c010b4100210902402003450d002003210a200221010340200920012d000041c00171418001466a2109200141016a2101200a417f6a220a0d000b0b200820036a20096b21080b410121010240024020002802084101460d00200020072002200310430d012000280218200420052000411c6a28020028020c1100000f0b02402000410c6a280200220920084b0d00200020072002200310430d012000280218200420052000411c6a28020028020c1100000f0b0240024020064108710d00200920086b210941002101024002400240410120002d0030220a200a4103461b0e0402000100020b20092101410021090c010b20094101762101200941016a41017621090b200141016a210103402001417f6a2201450d0220002802182000280204200028021c280210110100450d000b41010f0b41012101200041013a003020004130360204200020072002200310430d01200920086b210941002101024002400240410120002d0030220a200a4103461b0e0402000100020b20092101410021090c010b20094101762101200941016a41017621090b200141016a2101024003402001417f6a2201450d0120002802182000280204200028021c280210110100450d000b41010f0b2000280204210a41012101200028021820042005200028021c28020c1100000d01200941016a2109200028021c210320002802182100034002402009417f6a22090d0041000f0b410121012000200a2003280210110100450d000c020b0b2000280204210a41012101200020072002200310430d00200028021820042005200028021c28020c1100000d00200941016a2109200028021c210320002802182100034002402009417f6a22090d0041000f0b410121012000200a2003280210110100450d000b0b20010b5401017f024002402001418080c400460d0041012104200028021820012000411c6a2802002802101101000d010b024020020d0041000f0b2000280218200220032000411c6a28020028020c11000021040b20040b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420237020c200241cc86c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41dc86c000103e000b8307010c7f200028021021030240024002400240200028020822044101460d0020030d012000280218200120022000411c6a28020028020c11000021030c030b2003450d010b0240024020020d00410021020c010b200120026a2105200041146a28020041016a21064100210720012103200121080340200341016a210902400240024020032c0000220a417f4a0d000240024020092005470d004100210b200521030c010b20032d0001413f71210b200341026a220921030b200a411f71210c0240200a41ff0171220a41df014b0d00200b200c41067472210a0c020b0240024020032005470d004100210d2005210e0c010b20032d0000413f71210d200341016a2209210e0b200d200b41067472210b0240200a41f0014f0d00200b200c410c7472210a0c020b02400240200e2005470d004100210a200921030c010b200e41016a2103200e2d0000413f71210a0b200b410674200c411274418080f0007172200a72220a418080c400470d020c040b200a41ff0171210a0b200921030b02402006417f6a2206450d00200720086b20036a21072003210820052003470d010c020b0b200a418080c400460d00024002402007450d0020072002460d0041002103200720024f0d01200120076a2c00004140480d010b200121030b2007200220031b21022003200120031b21010b20040d002000280218200120022000411c6a28020028020c1100000f0b4100210902402002450d002002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b0240200220096b200028020c2206490d002000280218200120022000411c6a28020028020c1100000f0b410021074100210902402002450d00410021092002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b200920026b20066a210a024002400240410020002d0030220320034103461b0e0402000100020b200a21074100210a0c010b200a4101762107200a41016a410176210a0b200741016a2103024003402003417f6a2203450d0120002802182000280204200028021c280210110100450d000b41010f0b2000280204210941012103200028021820012002200028021c28020c1100000d00200a41016a2103200028021c210a20002802182100034002402003417f6a22030d0041000f0b20002009200a280210110100450d000b41010f0b20030bcd0801067f230041f0006b220424002004200336020c20042002360208410121052001210602402001418102490d00410020016b2107418002210803400240200820014f0d00200020086a2c000041bf7f4c0d0041002105200821060c020b2008417f6a21064100210520084101460d01200720086a21092006210820094101470d000b0b200420063602142004200036021020044100410520051b36021c200441b8aec600419287c00020051b3602180240024002400240200220014b22080d00200320014b0d00200220034b0d01024002402002450d0020012002460d00200120024d0d01200020026a2c00004140480d010b200321020b200420023602202002450d0220022001460d02200141016a210903400240200220014f0d00200020026a2c000041404e0d040b2002417f6a210820024101460d0420092002462106200821022006450d000c040b0b20042002200320081b360228200441306a41146a4103360200200441c8006a41146a4104360200200441d4006a4104360200200442033702342004419887c0003602302004410136024c2004200441c8006a3602402004200441186a3602582004200441106a3602502004200441286a360248200441306a41b087c000103e000b200441e4006a4104360200200441c8006a41146a4104360200200441d4006a4101360200200441306a41146a410436020020044204370234200441c087c0003602302004410136024c2004200441c8006a3602402004200441186a3602602004200441106a36025820042004410c6a3602502004200441086a360248200441306a41e087c000103e000b200221080b024020082001460d00410121060240024002400240200020086a22092c00002202417f4a0d0041002105200020016a220621010240200941016a2006460d00200941026a210120092d0001413f7121050b2002411f712109200241ff017141df014b0d01200520094106747221010c020b2004200241ff0171360224200441286a21020c020b4100210020062107024020012006460d00200141016a210720012d0000413f7121000b200020054106747221010240200241ff017141f0014f0d0020012009410c747221010c010b41002102024020072006460d0020072d0000413f7121020b20014106742009411274418080f00071722002722201418080c400460d020b2004200136022441012106200441286a21022001418001490d00410221062001418010490d0041034104200141808004491b21060b200420083602282004200620086a36022c200441306a41146a4105360200200441ec006a4104360200200441e4006a4104360200200441c8006a41146a4106360200200441d4006a4107360200200442053702342004418888c000360230200420023602582004410136024c2004200441c8006a3602402004200441186a3602682004200441106a3602602004200441246a3602502004200441206a360248200441306a41b088c000103e000b41f087c0001032000b100020012000280200200028020410450b6c01037f230041206b22022400024020002001104b0d002001411c6a280200210320012802182104200242043703182002420137020c2002419889c00036020820042003200241086a10350d00200041046a2001104b2101200241206a240020010f0b200241206a240041010bd90a02077f017e410121020240200128021841272001411c6a2802002802101101000d0041022103024002400240024002402000280200220241776a2200411e4d0d00200241dc00470d010c020b41f40021040240024020000e1f05010202000202020202020202020202020202020202020202030202020203050b41f20021040c040b41ee0021040c030b02400240024002400240024002402002104a0d00024002400240024002400240200241808004490d00200241808008490d0120024190fc476a4190fc0b490d0a200241e28b746a41e28d2c490d0a2002419fa8746a419f18490d0a200241dee2746a410e490d0a200241feffff0071419ef00a460d0a200241a9b2756a4129490d0a200241cb91756a410a4d0d0a410121030c0e0b20024180fe0371410876210541d095c000210041002106200241ff017121040340200041026a2107200620002d000122036a2108024020002d000022002005460d00200020054b0d092008210620072100200741a296c000470d010c090b20082006490d02200841a5024b0d03200641a296c0006a2100024003402003450d012003417f6a210320002d00002106200041016a210020062004470d000c0c0b0b2008210620072100200741a296c000470d000c080b0b20024180fe0371410876210541819bc000210041002106200241ff017121040340200041026a2107200620002d000122036a2108024020002d000022002005460d00200020054b0d072008210620072100200741c79bc000470d010c070b20082006490d03200841a6014b0d04200641c79bc0006a2100024003402003450d012003417f6a210320002d00002106200041016a210020062004470d000c0b0b0b2008210620072100200741c79bc000470d000c060b0b200620081044000b200841a502103c000b200620081044000b200841a601103c000b200241017267410276410773ad4280808080d0008421090c040b200241ffff0371210441ed9cc00021034101210002400340200341016a21080240024020032d0000220641187441187522074100480d00200821030c010b20084185a0c000460d02200741ff007141087420032d0001722106200341026a21030b200420066b22044100480d032000410173210020034185a0c000470d000c030b0b41f087c0001032000b200241ffff0371210441c798c0002103410121000340200341016a21080240024020032d0000220641187441187522074100480d00200821030c010b200841819bc000460d05200741ff007141087420032d0001722106200341026a21030b200420066b22044100480d0120004101732100200341819bc000470d000b0b4101210320004101710d030b200241017267410276410773ad4280808080d0008421090b410321030c020b41f087c0001032000b0b200221040b03402003210641dc0021004101210241012103024002400240024020060e0401020300010b024002400240024002402009422088a741ff01710e06050403020100050b200942ffffffff8f60834280808080c000842109410321030c060b200942ffffffff8f608342808080803084210941f5002100410321030c050b200942ffffffff8f608342808080802084210941fb002100410321030c040b20042009a72206410274411c7176410f712203413072200341d7006a2003410a491b210002402006450d002009427f7c42ffffffff0f83200942808080807083842109410321030c040b200942ffffffff8f6083428080808010842109410321030c030b200942ffffffff8f6083210941fd002100410321030c020b20012802184127200128021c2802101101000f0b41002103200421000b20012802182000200128021c280210110100450d000b0b20020b950201017f024002402000418010490d00024002400240024002400240200041808004490d002000410c7641706a2201418002490d0141a8a0c00020014180021034000b200041067641606a220141df074b0d01200141f08bc0006a2d0000220141c9004b0d0220014103744180a1c0006a21010c060b200141d093c0006a2d00004106742000410676413f7172220141ff034b0d02200141d0a5c0006a2d0000220141394b0d03200141037441d0a9c0006a21010c050b4188a0c000200141e0071034000b4198a0c000200141ca001034000b41b8a0c00020014180041034000b41c8a0c0002001413a1034000b200041037641f8ffffff017141d889c0006a21010b200129030042012000413f71ad86834200520baf0201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad41012001103f21000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000b20024180016a240020000f0b20044180011044000b20044180011044000b0d00200035020041012001103f0b1c00200128021841a1aec000410b2001411c6a28020028020c1100000b1c00200128021841acaec000410e2001411c6a28020028020c1100000b6901037f230041206b220224002001411c6a280200210320012802182104200241086a41106a2000280200220141106a290200370300200241086a41086a200141086a2902003703002002200129020037030820042003200241086a10352101200241206a240020010b5e01017f230041306b220224002002200136020c20022000360208200241246a410136020020024201370214200241b0aec6003602102002410436022c2002200241286a3602202002200241086a360228200241106a41f8aec000103e000b140020002802002001200028020428020c1101000bc30501077f410021040240024020024103712205450d00410420056b2205450d00200220032005200520034b1b22046a210641002105200141ff017121072004210820022109024003400240200620096b41034b0d0041002107200141ff0171210603402008450d04200920076a210a2008417f6a2108200741016a2107200a2d0000220a2006470d000b2005200a200141ff01714641016a4101716a20076a417f6a21050c020b200520092d0000220a2007476a2105200a2007460d012005200941016a2d0000220a2007476a2105200a2007460d012005200941026a2d0000220a2007476a2105200a2007460d012005200941036a2d0000220a2007476a21052008417c6a2108200941046a2109200a2007470d000b0b410121090c010b200141ff017121070240024020034108490d002004200341786a220a4b0d00200741818284086c210502400340200220046a220941046a2802002005732208417f73200841fffdfb776a7120092802002005732209417f73200941fffdfb776a7172418081828478710d01200441086a2204200a4d0d000b0b200420034b0d010b200220046a2109200220036a2102200320046b2108410021050240024003400240200220096b41034b0d0041002107200141ff0171210203402008450d04200920076a210a2008417f6a2108200741016a2107200a2d0000220a2002470d000b200a200141ff01714641016a41017120056a20076a417f6a21050c020b200520092d0000220a2007476a2105200a2007460d012005200941016a2d0000220a2007476a2105200a2007460d012005200941026a2d0000220a2007476a2105200a2007460d012005200941036a2d0000220a2007476a21052008417c6a2108200941046a2109200a2007470d000b0b41012109200520046a21050c020b41002109200520076a20046a21050c010b200420031044000b20002005360204200020093602000b2601017f200028020022012802002001280204200028020428020020002802082802001046000b850804057f017e017f017e02400240024002402002450d00410020016b410020014103711b2103200241796a4100200241074b1b210441002105034002400240200120056a2d000022064118744118752207417f4a0d0042808080801021080240200641e681c0006a2d0000417e6a220941024d0d0042808080808020210a0c070b0240024002400240024020090e03000102000b200541016a22062002490d024200210a0c090b4200210a200541016a220920024f0d08200120096a2d0000210902400240200641a07e6a2206410d4b0d000240024020060e0e0002020202020202020202020201000b200941e0017141a001460d0242808080808020210a0c0c0b02402009411874411875417f4c0d0042808080808020210a0c0c0b200941ff017141a001490d0142808080808020210a0c0b0b02402007411f6a41ff0171410b4b0d0002402009411874411875417f4c0d0042808080808020210a0c0c0b200941ff017141c001490d0142808080808020210a0c0b0b0240200941ff017141bf014d0d0042808080808020210a0c0b0b0240200741fe017141ee01460d0042808080808020210a0c0b0b2009411874411875417f4c0d0042808080808020210a0c0a0b42002108200541026a220620024f0d09200120066a2d000041c00171418001460d020c070b4200210a200541016a220920024f0d07200120096a2d0000210902400240200641907e6a220641044b0d000240024020060e050002020201000b200941f0006a41ff01714130490d0242808080808020210a0c0b0b02402009411874411875417f4c0d0042808080808020210a0c0b0b200941ff0171419001490d0142808080808020210a0c0a0b0240200941ff017141bf014d0d0042808080808020210a0c0a0b02402007410f6a41ff017141024d0d0042808080808020210a0c0a0b2009411874411875417f4c0d0042808080808020210a0c090b200541026a220620024f0d07200120066a2d000041c00171418001470d0642002108200541036a220620024f0d08200120066a2d000041c00171418001460d01428080808080e000210a42808080801021080c080b42808080808020210a4280808080102108200120066a2d000041c00171418001470d070b200641016a21050c010b0240200320056b4103710d000240200520044f0d000340200120056a220641046a280200200628020072418081828478710d01200541086a22052004490d000b0b200520024f0d010340200120056a2c00004100480d022002200541016a2205470d000c040b0b200541016a21050b20052002490d000b0b20002001360204200041086a2002360200200041003602000f0b428080808080c000210a42808080801021080c010b420021080b2000200a2008842005ad84370204200041013602000b02000ba20401077f230041306b220324000240024020020d00410021040c010b200341286a210502400240024002400340024020002802082d0000450d00200028020041e4afc0004104200028020428020c1100000d050b2003410a3602282003428a808080103703202003200236021c200341003602182003200236021420032001360210200341086a410a200120021052024002400240024020032802084101470d00200328020c210403402003200420032802186a41016a2204360218024002402004200328022422064f0d00200328021421070c010b200328021422072004490d00200641054f0d072003280210200420066b22086a22092005460d04200920052006109c05450d040b200328021c22092004490d0220072009490d0220032006200341106a6a41176a2d0000200328021020046a200920046b10522003280204210420032802004101460d000b0b2003200328021c3602180b200028020841003a0000200221040c010b200028020841013a0000200841016a21040b2000280204210920002802002106024020044520022004467222070d00200220044d0d03200120046a2c000041bf7f4c0d030b200620012004200928020c1100000d04024020070d00200220044d0d04200120046a2c000041bf7f4c0d040b200120046a2101200220046b22020d000b410021040c040b20064104103c000b20012002410020041046000b20012002200420021046000b410121040b200341306a240020040bf90101017f230041106b220224002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b20002002410c6a200110562101200241106a240020010b6001017f230041206b2202240020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41ccafc000200241086a10352101200241206a240020010b0d0020002802002001200210560b800201017f230041106b22022400200028020021002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b20002002410c6a200110562101200241106a240020010b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41ccafc000200241086a10352101200241206a240020010bdb0302047f057e230041d0006b2205240041012106024020002d00040d0020002d000521070240200028020022082d00004104710d0041012106200828021841caafc00041e8afc000200741ff017122071b4102410320071b2008411c6a28020028020c1100000d014101210620002802002208280218200120022008411c6a28020028020c1100000d01410121062000280200220828021841b9a8c40041022008411c6a28020028020c1100000d0120032000280200200428020c11010021060c010b0240200741ff01710d0041012106200828021841ebafc00041032008411c6a28020028020c1100000d01200028020021080b41012106200541013a00172005200541176a360210200829020821092008290210210a200541346a41b0afc000360200200520082902183703082008290220210b2008290228210c200520082d00303a00482008290200210d2005200c3703402005200b3703382005200a370328200520093703202005200d3703182005200541086a360230200541086a2001200210560d00200541086a41b9a8c400410210560d002003200541186a200428020c1101000d00200528023041c8afc0004102200528023428020c11000021060b200041013a0005200020063a0004200541d0006a240020000bf30202047f057e230041d0006b2203240041012104024020002d00080d00200028020421050240200028020022062d00004104710d0041012104200628021841caafc00041f1afc00020051b4102410120051b2006411c6a28020028020c1100000d0120012000280200200228020c11010021040c010b024020050d0041012104200628021841f2afc00041022006411c6a28020028020c1100000d01200028020021060b41012104200341013a00172003200341176a3602102006290208210720062902102108200341346a41b0afc00036020020032006290218370308200629022021092006290228210a200320062d00303a00482006290200210b2003200a3703402003200937033820032008370328200320073703202003200b3703182003200341086a3602302001200341186a200228020c1101000d00200328023041c8afc0004102200328023428020c11000021040b200020043a00082000200028020441016a360204200341d0006a240020000b6401027f230041206b220224002001411c6a280200210320012802182101200241086a41106a200041106a290200370300200241086a41086a200041086a2902003703002002200029020037030820012003200241086a10352100200241206a240020000bb50f020d7f017e230041206b220324004101210402400240200228021841222002411c6a2802002802101101000d000240024020010d00410021050c010b200020016a21062000210741002105410021080240034020072109200741016a210a02400240024020072c0000220b417f4a0d0002400240200a2006470d004100210c200621070c010b20072d0001413f71210c200741026a220a21070b200b411f7121040240200b41ff0171220b41df014b0d00200c200441067472210b0c020b0240024020072006470d004100210d2006210e0c010b20072d0000413f71210d200741016a220a210e0b200d200c41067472210c0240200b41f0014f0d00200c2004410c7472210b0c020b02400240200e2006470d004100210b200a21070c010b200e41016a2107200e2d0000413f71210b0b200c4106742004411274418080f0007172200b72220b418080c400470d020c040b200b41ff0171210b0b200a21070b4102210a024002400240024002400240200b41776a220c411e4d0d00200b41dc00470d010c020b41f400210e02400240200c0e1f05010202000202020202020202020202020202020202020202030202020203050b41f200210e0c040b41ee00210e0c030b02400240200b104a0d00024002400240024002400240024002400240200b41808004490d00200b41808008490d01200b4190fc476a4190fc0b490d09200b41e28b746a41e28d2c490d09200b419fa8746a419f18490d09200b41dee2746a410e490d09200b41feffff0071419ef00a460d09200b41a9b2756a4129490d09200b41cb91756a410a4d0d090c0e0b200b4180fe0371410876210f41d095c000210c410021040340200c41026a210d2004200c2d0001220a6a210e0240200c2d0000220c200f460d00200c200f4b0d08200e2104200d210c200d41a296c000470d010c080b200e2004490d02200e41a5024b0d03200441a296c0006a210c02400340200a450d01200a417f6a210a200c2d00002104200c41016a210c2004200b41ff0171470d000c0b0b0b200e2104200d210c200d41a296c000470d000c070b0b200b4180fe0371410876210f41819bc000210c410021040340200c41026a210d2004200c2d0001220a6a210e0240200c2d0000220c200f460d00200c200f4b0d06200e2104200d210c200d41c79bc000470d010c060b200e2004490d03200e41a6014b0d04200441c79bc0006a210c02400340200a450d01200a417f6a210a200c2d00002104200c41016a210c2004200b41ff0171470d000c0a0b0b200e2104200d210c200d41c79bc000470d000c050b0b2004200e1044000b200e41a502103c000b2004200e1044000b200e41a601103c000b200b41ffff0371210e41ed9cc000210a4101210c02400340200a41016a210d02400240200a2d00002204411874411875220f4100480d00200d210a0c010b200d4185a0c000460d02200f41ff0071410874200a2d0001722104200a41026a210a0b200e20046b220e4100480d03200c410173210c200a4185a0c000470d000c030b0b41f087c0001032000b200b41ffff0371210e41c798c000210a4101210c0340200a41016a210d02400240200a2d00002204411874411875220f4100480d00200d210a0c010b200d41819bc000460d04200f41ff0071410874200a2d0001722104200a41026a210a0b200e20046b220e4100480d01200c410173210c200a41819bc000470d000b0b200c4101710d050b200b41017267410276410773ad4280808080d0008421104103210a0c020b41f087c0001032000b0b200b210e0b2003200136020420032000360200200320053602082003200836020c0240024020082005490d0002402005450d0020052001460d00200520014f0d01200020056a2c000041bf7f4c0d010b02402008450d0020082001460d00200820014f0d01200020086a2c000041bf7f4c0d010b2002280218200020056a200820056b200228021c28020c110000450d01410121040c060b20032003410c6a3602182003200341086a36021420032003360210200341106a1053000b0340200a210c4101210441dc0021054101210a024002400240024002400240200c0e0402010500020b02400240024002402010422088a741ff01710e06050302010006050b201042ffffffff8f60834280808080308421104103210a41f50021050c070b201042ffffffff8f60834280808080208421104103210a41fb0021050c060b200e2010a7220c410274411c7176410f71220a413072200a41d7006a200a410a491b21050240200c450d002010427f7c42ffffffff0f832010428080808070838421100c050b201042ffffffff8f60834280808080108421100c040b201042ffffffff8f608321104103210a41fd0021050c040b4100210a200e21050c030b4101210a0240200b418001490d004102210a200b418010490d0041034104200b41808004491b210a0b200a20086a21050c040b201042ffffffff8f60834280808080c0008421100b4103210a0b20022802182005200228021c2802101101000d050c000b0b200820096b20076a210820062007470d000b0b2005450d0020052001460d00200520014f0d02200020056a2c000041bf7f4c0d020b410121042002280218200020056a200120056b200228021c28020c1100000d0020022802184122200228021c28021011010021040b200341206a240020040f0b20002001200520011046000bc00201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff018341012001103f21000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000b20024180016a240020000f0b20044180011044000b20044180011044000b0b0020002802002001104b0b800201027f230041106b2202240020012802184198b0c00041092001411c6a28020028020c1100002103200241003a0005200220033a0004200220013602002002200036020c200241a1b0c000410b2002410c6a41f8afc000105c21012002200041046a36020c200141acb0c00041092002410c6a41b8b0c000105c1a20022d00042101024020022d0005450d00200141ff0171210041012101024020000d0020022802002201411c6a28020028020c210020012802182103024020012d00004104710d00200341eeafc0004102200011000021010c010b200341f0afc0004101200011000021010b200220013a00040b200241106a2400200141ff01714100470bb50201027f230041106b2202240002400240200028020022002d00004101460d00200128021841e0e2c50041042001411c6a28020028020c11000021010c010b2002200128021841e4e2c50041042001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200041016a36020c20022002410c6a4188b0c000105d1a20022d00082101024020022802042203450d00200141ff0171210041012101024020000d00024020034101470d0020022d000941ff0171450d00200228020022002d00004104710d0041012101200028021841f4afc00041012000411c6a28020028020c1100000d010b2002280200220128021841c8a4c60041012001411c6a28020028020c11000021010b200220013a00080b200141ff017141004721010b200241106a240020010b1c00200128021841b8aec60041052001411c6a28020028020c1100000b040041000b02000b02000b9e10020a7f017e23004180016b2202240002400240024020012802042203200128020022046b41e100490d000240024003402001200441206a3602002001280208220341186a280200210520032802102106200241e0006a41186a22034200370300200241e0006a41106a22074200370300200241e0006a41086a220842003703002002420037036020044120200241e0006a1000200241106a41186a22092003290300370300200241106a41106a220a2007290300370300200241106a41086a220b2008290300370300200220022903603703102002410036026020062005200241106a4120200241e0006a10012106024020022802602205417f460d0020022005360258200220053602542002200636025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c050b20012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037036020044120200241e0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903603703102002410036026020052006200241106a4120200241e0006a10012106024020022802602205417f470d0020012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037036020044120200241e0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903603703102002410036026020052006200241106a4120200241e0006a1001210620022802602205417f470d0320012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037036020044120200241e0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903603703102002410036026020052006200241106a4120200241e0006a1001210720022802602203417f470d0220012802042203200128020022046b41e0004b0d010c040b0b20022005360258200220053602542002200636025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c030b20022003360258200220033602542002200736025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c020b20022005360258200220053602542002200636025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c010b024020042003460d0003402001200441206a3602002001280208220341186a280200210720032802102103200241e0006a41186a22084200370300200241e0006a41106a22094200370300200241e0006a41086a220a42003703002002420037036020044120200241e0006a1000200241106a41186a2008290300370300200241106a41106a2009290300370300200241106a41086a200a290300370300200220022903603703102002410036026020032007200241106a4120200241e0006a10012107024020022802602203417f460d0020022003360258200220033602542002200736025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c030b200128020022042001280204470d000b0b200041003602000c010b200241e0006a41086a2002220141086a280200220336020020022001290200220c370360200020043602002000200c3702042000410c6a20033602000b20024180016a24000b950201057f230041e0026b22012400024020002802082202200028020c460d00200141b0016a4101722103200141d8016a210403402000200241b0016a36020820022d00002105200141b0016a200241016a41af01109a051a20054103460d01200141016a200141b0016a41af01109a051a200120053a00b0012003200141016a41af01109a051a02400240200541014b0d000240024020050e020001000b024020012802b801450d0020012802b401102a0b20012d00c0014105490d0220012802e801450d0220012802e401102a0c020b2004106a0c010b200128029802450d00200128029402102a0b20002802082202200028020c470d000b0b02402000280204450d002000280200102a0b200141e0026a24000baa0b01057f02402000280200220141124b0d00024002400240024002400240024002400240024002400240024020010e13000d0d010d0d020304050607080d090d0a0b0c000b0240200041086a280200220141054b0d0002400240024020010e06101000100102100b200041106a280200450d0f2000410c6a280200102a0f0b200041106a280200450d0e2000410c6a280200102a0f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141186a2101200241686a22020d000b0b200041106a280200450d0d200028020c102a0f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d002001280200102a0b2001410c6a2101200241746a22020d000b0b200041106a280200450d0c200028020c102a0f0b02402000410c6a2802002201450d0020002802042203200141f0006c6a2104034002402003410c6a2802002202450d0020032802042101200241246c210203400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012002415c6a22020d000b0b200341f0006a21010240200341086a280200450d002003280204102a0b2001210320012004470d000b0b200041086a280200450d0b2000280204102a0f0b0240200041086a2d00002201410c4b0d0020014106470d0b200041106a280200450d0b2000410c6a280200102a0f0b200041106a280200450d0a2000410c6a280200102a0f0b200041086a280200450d092000280204102a0f0b200041086a2d0000417f6a220141074b0d08024002400240024020010e08000c0c0c0c010203000b2000410c6a2201280200106a2001280200102a0f0b2000410c6a2201280200106a2001280200102a0f0b2000410c6a2201280200106a2001280200102a0f0b2000410c6a2201280200106a2001280200102a0f0b20002d0004417f6a220141024b0d0702400240024020010e03000102000b2000410c6a280200450d09200041086a280200102a0f0b200041086a2201280200106a2001280200102a0f0b2000410c6a2201280200106a2001280200102a0f0b20002d0004417f6a220141024b0d0602400240024020010e03000102000b2000410c6a280200450d08200041086a280200102a0f0b200041086a2201280200106a2001280200102a0f0b2000410c6a2201280200106a2001280200102a0f0b200041086a280200417f6a220141014b0d050240024020010e020001000b200041106a280200450d062000410c6a280200102a0f0b200041106a280200450d052000410c6a280200102a0f0b20002d00044104490d042000410c6a280200450d04200041086a280200102a0c040b200041086a280200450d032000280204102a0f0b200041086a2d0000417e6a220141024b0d0202400240024020010e03000102000b200041106a280200450d042000410c6a280200102a0f0b200041346a280200450d03200041306a280200102a0f0b200041306a280200450d022000412c6a280200102a0f0b02402000280204220141024b0d00024020010e03030003030b200041086a2201280200106a2001280200102a0f0b2000412c6a2201280200106a2001280200102a0f0b02402000410c6a280200450d00200041086a280200102a0b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d002001280200102a0b2001410c6a2101200241746a22020d000b0b200041186a280200450d002000280214102a0f0b0b960301097f230041106b2202240002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002006450d0020042d0001210720012003417e6a22063602042001200441026a3602002006450d0020042d0002210820012003417d6a22063602042001200441036a3602002006450d0020042d0003210620012003417c6a3602042001200441046a360200200241086a2001106c20022802080d022001280204200228020c2204490d022004417f4c0d0302400240024020040d004101210341010d010c050b2004102e2203450d0120012802042004490d03200320012802002004109a0521092001280204220a2004490d062001200a20046b3602042001200128020020046a3602002009450d040b20002004360208200020033602042000410c6a2004360200200020074108742005722008411074722006411874723602000c060b200441011037000b200041003602040c040b2003102a0b200041003602040c020b1036000b2004200a1044000b200241106a24000bcf0201067f0240024020012802042202450d00200128020022032d0000210420012002417f6a2205360204410121062001200341016a3602000240200441037122074103460d0002400240024020070e03000102000b20044102762107410021060c040b41012106024020050d000c040b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d03200141fcff03714102762107410021060c030b20054103490d01200341036a2d0000210620032f0001210720012002417c6a3602042001200341046a3602002007200641107472410874200472220141027621072001418080044921060c020b0240200441034d0d000c020b20054104490d012003280001210720012002417b6a3602042001200341056a36020020074180808080044921060c010b410121060b20002007360204200020063602000baf04010a7f230041d0006b2202240020022001106c0240024002400240024020022802000d00200128020422034160712204417f4c0d022002280204210502400240200341057622060d00410121070c010b200410282207450d040b02402005450d00410021080340200241003a00482008220941016a21082001280204417f6a21034100210402400240024003402003417f460d01200241286a20046a2001280200220a2d00003a0000200120033602042001200a41016a3602002002200441016a220a3a00482003417f6a2103200a2104200a4120470d000b200241086a41186a2204200241286a41186a290300370300200241086a41106a220a200241286a41106a290300370300200241086a41086a220b200241286a41086a2903003703002002200229032837030820062009470d020240200941017422032008200320084b1b220641ffffff3f712006470d002006410574220341004e0d020b1031000b0240200441ff0171450d00200241003a00480b200041003602002006450d052007102a0c050b0240024020090d002003102821070c010b200720094105742003102c21070b2007450d070b200720094105746a22032002290308370000200341186a2004290300370000200341106a200a290300370000200341086a200b29030037000020082005470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241d0006a24000f0b1036000b200441011037000b200341011037000b9203010a7f200041086a220228020021034100210420024100360200024002402003450d004100210541002106410021044100210702400340024002402004450d00200741057421080340200720034f0d062001200028020022096b2008460d02200920086a220a20014120109c05450d020240200620076a220b20034f0d00200920056a20086a2209200a290000370000200941186a200a41186a290000370000200941106a200a41106a290000370000200941086a200a41086a290000370000200841206a2108200741016a22072003490d010c050b0b41c4b2c000200b20031034000b200028020020074105746a21080340200720034f0d0520012008460d01200820014120109c05450d01200841206a2108200741016a22072003490d000b410021040c030b200541606a21052006417f6a2106200441016a2104200741016a22072003490d000b0b2004450d00200320074d0d00200028020020074105746a220820044105746b2008200320076b410574109b051a0b2002200320046b3602000f0b41e8b1c000200720031034000bfe0203017f017e0b7f024002400240024020012802082202ad42187e2203422088a70d002003a72204417f4c0d00200128020021050240024020040d00410421060c010b200410282206450d020b0240024020020d00410021070c010b2005200241186c6a210841002107200621010340200541086a2802002204417f4c0d02200528020021090240024020040d004101210a4100210b0c010b2004210b20041028220a450d050b200a20092004109a05210a200541146a2802002209417f4c0d022005410c6a280200210c0240024020090d004100210d4101210e0c010b2009210d20091028220e450d060b200e200c2009109a05210c200141146a2009360200200141106a200d3602002001410c6a200c360200200141086a2004360200200141046a200b3602002001200a360200200141186a2101200741016a2107200541186a22052008470d000b0b2000200736020820002002360204200020063602000f0b1036000b200441041037000b200441011037000b200941011037000bc90a03027f017e1c7f230041f0006b22022400024002400240024002400240024020012802082203ad42f0007e2204422088a70d002004a72205417f4c0d00200128020021060240024020050d00410421070c010b200510282207450d020b0240024020030d00410021080c010b2006200341f0006c6a2109410021082007210a0340200241c0006a41086a220b200641186a290000370300200241c0006a41106a220c200641206a290000370300200241c0006a41186a220d200641286a290000370300200241206a41086a220e200641386a29000037030020062900102104200241206a41106a220f200641c0006a290000370300200241206a41186a2210200641c8006a290000370300200241186a2211200641e8006a290000370300200241106a2212200641e0006a290000370300200241086a2213200641d8006a290000370300200220043703402002200629003037032020022006290050370300200628020c2214ad42247e2204422088a70d022004a72201417f4c0d0220062802002115200628020421160240024020010d00410421170c010b200110282217450d050b0240024020140d00410021180c010b201441246c211941002105410021180340024002400240024002400240201620056a22012d00000e050001020304000b2002200141146a2900003703602002200141196a290000370065200141056a2f0000200141076a2d000041107472211a200141106a280000211b2001410c6a280000211c200141086a280000211d200141016a280000211e4100211f0c040b200141106a280200221b417f4c0d08200141086a2802002120200141016a280000211e4101211f0240201b0d004100211c4101211d41012020201b109a051a0c040b201b211c201b1028221d450d0b201d2020201b109a051a0c030b200141106a280200221b417f4c0d07200141086a280200211f200141016a280000211e02400240201b0d004100211c4101211d0c010b201b211c201b1028221d450d0c0b201d201f201b109a051a4102211f0c020b200141106a280200221b417f4c0d06200141086a280200211f200141016a280000211e02400240201b0d004100211c4101211d0c010b201b211c201b1028221d450d0c0b201d201f201b109a051a4103211f0c010b2001410c6a280200221c417f4c0d05200141046a280200210102400240201c0d004101211a4100211d0c010b201c211d201c1028221a450d0c0b201a2001201c109a052201411874211e2001410876211a4104211f0b201720056a2201201f3a0000200141076a201a4110763a0000200141056a201a3b0000200141106a201b3600002001410c6a201c360000200141086a201d360000200141016a201e360000200141146a20022903603702002001411c6a200241e0006a41086a290300370200201841016a21182019200541246a2205470d000b0b200a2017360204200a410c6a2018360200200a41086a2014360200200a2002290340370210200a41186a200b290300370200200a2015360200200a2002290320370230200a41206a200c290300370200200a41286a200d290300370200200a41386a200e290300370200200a41c0006a200f290300370200200a41c8006a2010290300370200200a41e8006a2011290300370200200a41e0006a2012290300370200200a41d8006a2013290300370200200a2002290300370250200841016a2108200a41f0006a210a200641f0006a22062009470d000b0b200020083602082000200336020420002007360200200241f0006a24000f0b1036000b200541041037000b200141041037000b201b41011037000b201b41011037000b201b41011037000b201c41011037000b890203017f017e077f02400240024020012802082202ad420c7e2203422088a70d002003a72204417f4c0d00200128020021050240024020040d00410421060c010b200410282206450d020b0240024020020d00410021070c010b20052002410c6c6a210841002107200621040340200541086a2802002201417f4c0d02200528020021090240024020010d004101210a0c010b20011028220a450d050b200a20092001109a052109200441086a2001360200200441046a2001360200200420093602002004410c6a2104200741016a21072005410c6a22052008470d000b0b2000200736020820002002360204200020063602000f0b1036000b200441041037000b200141011037000bd70201037f024020002802082201450d002000280200220020014188016c6a2102200041f8006a2100034002400240200041887f6a22012d00002203410e4b0d00024002400240024020030e0f050505050500050501050205030505050b200041907f6a2d00004101470d042000419c7f6a280200450d04200041987f6a280200102a0c040b2000418c7f6a2d00004103470d030240200041947f6a280200450d00200041907f6a280200102a0b200041a07f6a280200450d032000419c7f6a280200102a0c030b2000418c7f6a2802000d02200041947f6a280200450d02200041907f6a280200102a0c020b200041907f6a2d00004105490d01200041b87f6a280200450d01200041b47f6a280200102a0c010b200041907f6a280200450d002000418c7f6a280200102a0b0240200141fc006a280200450d002000280200102a0b20004188016a210020014188016a2002470d000b0b0baf04010a7f230041d0006b2202240020022001106c0240024002400240024020022802000d00200128020422034160712204417f4c0d022002280204210502400240200341057622060d00410121070c010b200410282207450d040b02402005450d00410021080340200241003a00482008220941016a21082001280204417f6a21034100210402400240024003402003417f460d01200241286a20046a2001280200220a2d00003a0000200120033602042001200a41016a3602002002200441016a220a3a00482003417f6a2103200a2104200a4120470d000b200241086a41186a2204200241286a41186a290300370300200241086a41106a220a200241286a41106a290300370300200241086a41086a220b200241286a41086a2903003703002002200229032837030820062009470d020240200941017422032008200320084b1b220641ffffff3f712006470d002006410574220341004e0d020b1031000b0240200441ff0171450d00200241003a00480b200041003602002006450d052007102a0c050b0240024020090d002003102821070c010b200720094105742003102c21070b2007450d070b200720094105746a22032002290308370000200341186a2004290300370000200341106a200a290300370000200341086a200b29030037000020082005470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241d0006a24000f0b1036000b200441011037000b200341011037000b8a06030a7f037e017f23004190016b2202240020022001106c0240024002400240024020022802000d00200128020441216e220341216c2204417f4c0d01200228020421050240024020040d00410121060c010b200410282206450d030b02402005450d0041002107034020012802042208450d05200128020022092d0000210420012008417f6a220a3602042001200941016a360200200441014b0d054100210b0240024020040e020100010b41002104200241003a0088012008417e6a210803400240200a2004470d00200441ff0171450d08200241003a0088010c080b200241e8006a20046a200920046a220b41016a2d00003a0000200120083602042001200b41026a3602002002200441016a220b3a0088012008417f6a2108200b2104200b4120470d000b200241c8006a41186a200241e8006a41186a290300370300200241c8006a41106a200241e8006a41106a290300370300200241c8006a41086a200241e8006a41086a290300370300200220022903683703484101210b0b200741016a2108200241286a41186a200241c8006a41186a290300220c370300200241286a41106a200241c8006a41106a290300220d370300200241286a41086a200241c8006a41086a290300220e370300200241086a41086a2209200e370300200241086a41106a220a200d370300200241086a41186a220f200c37030020022002290348220c3703282002200c370308024020032007470d000240200741017422042008200420084b1b2203ad42217e220c422088a70d00200ca722044100480d000240024020070d002004102821060c010b2006200741216c2004102c21060b20060d01200441011037000b1031000b2006200741216c6a2204200b3a000020042002290308370001200441096a2009290300370000200441116a200a290300370000200441196a200f2903003700002008210720082005470d000b0b2000200336020420002006360200200041086a20053602000c040b200041003602000c030b1036000b200441011037000b200041003602002003450d002006102a0b20024190016a24000bc902010a7f230041106b22022400200241086a2001106c0240024020022802080d00024020012802042203417f4c0d00200228020c210402400240024020030d00410121050c010b200310282205450d010b02402004450d004100210641002107034002400240024020012802042208450d00200741016a21092001280200220a2d0000210b20012008417f6a3602042001200a41016a36020020072003460d010c020b200041003602002003450d072005102a0c070b024020062009200620094b1b22034100480d000240024020070d002003102821050c010b200520072003102c21050b20050d01200341011037000b1031000b200520076a200b3a0000200641026a21062009210720042009470d000b0b2000200336020420002005360200200041086a20043602000c030b200341011037000b1036000b200041003602000b200241106a24000b990a02137f017e230041e0006b22022400200241086a2001106c0240024020022802080d000240200128020441246e220341246c2204417f4c0d00200228020c210502400240024020040d00410421060c010b200410282206450d010b02400240024020050d00410021040c010b2002412d6a2107200241cb006a220841056a21094100210a4100210b0340024002402001280204220c450d002001280200220d2d000021042001200c417f6a220e3602042001200d41016a360200200441064b0d00024002400240024002400240024020040e0700070107030402000b20022001106c20022802000d0620012802042002280204220c490d06200c417f4c0d0c024002400240200c0d004101210441010d010c090b200c102e2204450d012001280204200c490d0620042001280200200c109a05210f2001280204220d200c490d072001200d200c6b36020420012001280200200c6a360200200f450d080b200241206a41086a200241386a41086a290200370300200220022902383703202004410876210f4104210d200c210e201041ffffff0771200441187472221021110c080b200c41011037000b41002104200241003a0058200c417e6a210c03400240200e2004470d00200441ff0171450d07200241003a00580c070b200241386a20046a200d20046a220f41016a2d00003a00002001200c3602042001200f41026a3602002002200441016a220f3a0058200c417f6a210c200f2104200f4120470d000b2002200829000037032020022009290000370025200228004721122002280043210e200228003f210c2002280238211120022f013c210420022d003e210f200741026a200241356a41026a2d00003a0000200720022f00353b00002004200f41107472210f4100210d0c060b200241386a2001106b200228023c220c450d04200228024421122002280240210e200228023821114101210d0c050b200241386a2001106b200228023c220c450d03200228024421122002280240210e200228023821114102210d0c040b200241386a2001106b200228023c220c450d02200228024421122002280240210e200228023821114103210d0c030b2004102a0c010b200c200d1044000b200041003602000240200b450d002006210403400240024020042d0000220141034b0d0002400240024020010e0404000102040b2004410c6a280200450d03200441086a280200102a0c030b2004410c6a280200450d02200441086a280200102a0c020b2004410c6a280200450d01200441086a280200102a0c010b200441086a280200450d00200441046a280200102a0b200441246a2104200a415c6a220a0d000b0b2003450d072006102a0c070b200241106a41086a2213200241206a41086a290300370300200220022903203703100240200b2003470d0002400240200341016a22042003490d00200341017422142004201420044b1b2204ad42247e2215422088a70d002015a7221441004e0d010b1031000b0240024020030d002014102821060c010b2006200341246c2014102c21060b2006450d03200421030b2006200b41246c6a220420123600102004200e36000c2004200c3600082004200f3b0005200420113600012004200d3a0000200441076a200f4110763a0000200420022903103700142004411c6a2013290300370000200a41246a210a200b41016a2204210b20042005470d000b0b2000200336020420002006360200200041086a20043602000c040b201441041037000b200441041037000b1036000b200041003602000b200241e0006a24000bb906020c7f047e230041b0016b2202240020022001106c02400240024002400240024020022802000d00200128020441286e220341286c2204417f4c0d02200228020421050240024020040d00410821060c010b200410282206450d040b02402005450d00410021070340200241003a00a8012007220841016a210720012802042109417f210a4100210402400240024002400240034020092004460d0120024188016a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a00a801200a417f6a210a200c2104200c4120470d000b200241e8006a41186a220420024188016a41186a290300370300200241e8006a41106a220a20024188016a41106a290300370300200241e8006a41086a220d20024188016a41086a29030037030020022002290388013703682009200c6b220c41074d0d01200b290001210e2001200b41096a3602002001200c41786a360204200241286a41086a200d290300220f370300200241286a41106a200a2903002210370300200241286a41186a20042903002211370300200241086a41086a220a200f370300200241086a41106a220c2010370300200241086a41186a2209201137030020022002290368220f3703282002200f37030820032008470d04200841017422042007200420074b1b2203ad42287e220f422088a70d0c200fa722044100480d0c20080d022004102821060c030b200441ff0171450d00200241003a00a8010b200241286a41186a200241c8006a41186a290300370300200241286a41106a200241c8006a41106a290300370300200241286a41086a200241c8006a41086a29030037030020022002290348370328200041003602002003450d062006102a0c060b2006200841286c2004102c21060b2006450d070b2006200841286c6a22042002290308370300200a290300210f200c2903002110200929030021112004200e370320200441186a2011370300200441106a2010370300200441086a200f37030020072005470d000b0b2000200336020420002006360200200041086a20053602000c010b200041003602000b200241b0016a24000f0b1036000b200441081037000b200441081037000b1031000bf80404097f027e027f017e230041d0006b2202240020022001106c024002400240024002400240024020022802000d00200128020441306e220341306c2204417f4c0d01200228020421050240024020040d00410821060c010b200410282206450d030b02402005450d00410021070340200128020422084110490d07200741016a21092001280200220a41086a290000210b200a290000210c2001200a41106a3602002001200841706a220d36020441002104200241003a00482008416f6a210803400240200d2004470d00200441ff0171450d09200241003a00480c090b200241286a20046a200a20046a220e41106a2d00003a0000200120083602042001200e41116a3602002002200441016a220e3a00482008417f6a2108200e2104200e4120470d000b200241086a41186a2208200241286a41186a290300370300200241086a41106a220e200241286a41106a290300370300200241086a41086a220a200241286a41086a29030037030020022002290328370308024020032007470d00200741017422042009200420094b1b2203ad42307e220f422088a70d07200fa722044100480d070240024020070d002004102821060c010b2006200741306c2004102c21060b2006450d060b2006200741306c6a2204200b3703082004200c37030020042002290308370310200441186a200a290300370300200441206a200e290300370300200441286a20082903003703002009210720092005470d000b0b2000200336020420002006360200200041086a20053602000c060b200041003602000c050b1036000b200441081037000b200441081037000b1031000b200041003602002003450d002006102a0b200241d0006a24000ba40303087f017e017f230041d0046b22022400200241086a2001106c02400240024002400240024020022802080d00200128020441a0026e220341a0026c2204417f4c0d02200228020c21050240024020040d00410821060c010b200410282206450d040b024002402005450d004100210741002104410021080340200241b0026a2001107a2002290398034203510d02200841016a2109200241106a200241b0026a41a002109a051a024020082003470d0020072009200720094b1b2203ad42a0027e220a422088a70d09200aa7220b4100480d090240024020080d00200b102821060c010b20062004200b102c21060b2006450d080b200620046a200241106a41a002109a051a200741026a2107200441a0026a21042009210820052009470d000b0b2000200336020420002006360200200041086a20053602000c020b2000410036020002402008450d0020064198016a210903402009106a200941a0026a2109200441e07d6a22040d000b0b2003450d012006102a0c010b200041003602000b200241d0046a24000f0b1036000b200441081037000b200b41081037000b1031000bae0c04047f017e097f067e23004180066b22022400200241286a2001106c02400240024002400240024020022802280d000240200228022c2203450d0003402003417f6a22030d000b0b20012802042203450d01200128020022042d0000210520012003417f6a3602042001200441016a36020002400240200541ff00714103470d0020054118744118754100480d01420221060c060b200042033703680c060b20024198046a200110a50120022d0098044102460d02200241f0036a41206a20024198046a41206a280200360200200241f0036a41186a20024198046a41186a290300370300200241f0036a41106a20024198046a41106a290300370300200241f0036a41086a20024198046a41086a29030037030020022002290398043703f00341002103200241003a00c00220012802042107417f2105024002400240034020072003460d0120024180026a20036a200128020022082d00003a00002001200720056a3602042001200841016a3602002002200341016a22043a00c0022005417f6a210520042103200441c000470d000b200241c0056a41386a220320024180026a41386a290300370300200241c0056a41306a220920024180026a41306a290300370300200241c0056a41286a220a20024180026a41286a290300370300200241c0056a41206a220b20024180026a41206a290300370300200241c0056a41186a220c20024180026a41186a290300370300200241c0056a41106a220d20024180026a41106a290300370300200241c0056a41086a220e20024180026a41086a29030037030020022002290380023703c005200441ff017141c000490d0520024180056a41386a220f200329030037030020024180056a41306a2009290300220637030020024180056a41286a200a290300221037030020024180056a41206a200b290300221137030020024180056a41186a200c290300221237030020024180056a41106a200d290300221337030020024180056a41086a200e2903002214370300200220022903c005221537038005200241c0046a41306a2006370300200241c0046a41286a2010370300200241c0046a41206a2011370300200241c0046a41186a2012370300200241c0046a41106a2013370300200241c0046a41086a2014370300200241c0046a41386a200f290300370300200220153703c00420072004460d05200831000121112001200720056a3602042001200841026a360200201150450d01420021060c020b200341ff0171450d04200241003a00c0020c040b2007417f6a2004460d03200831000221122001200841036a3602002001200720046b417e6a36020442022011420f838622104204540d034201210620124208862011844204882010420c882211420120114201561b7e221120105a0d030b200241206a2001106c20022802200d0220022802242105200241086a2001109f012002290308a70d02200241086a41106a290300211320022903102112200241e8026a41206a200241f0036a41206a280200360200200241e8026a41186a200241f0036a41186a290300370300200241e8026a41106a200241f0036a41106a290300370300200241e8026a41086a200241f0036a41086a29030037030020024194036a200241c0046a41086a2903003702002002419c036a200241c0046a41106a290300370200200241a4036a200241c0046a41186a290300370200200241ac036a200241c0046a41206a290300370200200241b4036a200241e8046a290300370200200241bc036a200241f0046a290300370200200241c4036a200241f8046a290300370200200220022903f0033703e802200220022903c00437028c0320024180026a200241e8026a41e800109a051a0c030b200042033703680c040b200042033703680c030b420221060b20024198016a20024180026a41e800109a051a024020064202520d00200042033703680c020b200241306a20024198016a41e800109a051a0b200241e8026a2001108101024020022802e8024113460d002000200241306a41e800109a0522034188016a201337030020034180016a201237030020034190016a2005360200200341f8006a2011370300200320103703702003200637036820034198016a200241e8026a418801109a051a0c010b200042033703680b20024180066a24000bfb1002147f037e230041c0026b22022400200241086a2001106c0240024020022802080d000240200128020441c4006e220341c4006c2204417f4c0d00200228020c210502400240024020040d00410421060c010b200410282206450d010b024002402005450d0020024198026a410772210741002108034002400240024002400240024020012802042209450d002001280200220a2d0000210420012009417f6a220b3602042001200a41016a360200200441014b0d000240024020040e020001000b200b41034d0d01200a280001210c20012009417b6a3602042001200a41056a360200200241d4016a41026a200241d8016a41026a2d00003a0000200241b8016a41086a200241f8016a41086a290200370300200241b8016a41106a200241f8016a41106a290200370300200241b8016a41186a200241f8016a41186a2d00003a000020024198016a41086a20024198026a41086a29010037030020024198016a41106a20024198026a41106a29010037030020024198016a41186a20024198026a41186a290100370300200220022f00d8013b01d401200220022902f8013703b801200220022901980237039801200220022f01f4013b0196014100210d0c030b4100210e200241003a00b8022009417e6a210d03400240200b200e2204470d000240200441ff0171450d00200241003a00b8020b4102210d0c040b20024198026a20046a200a20046a220e41016a2d00003a00002001200d3602042001200e41026a3602002002200441016a220e3a00b802200d417f6a210d200e4120470d000b200241f4016a41026a220f20022d009a023a0000200241d8016a41086a2210200741086a290000370300200241d8016a41106a2211200741106a290000370300200241d8016a41186a2212200741186a2d00003a0000200220022f0198023b01f401200220072900003703d801200b200e460d01200228009b022113200a200e6a220a41016a2d0000210b2001200d3602042001200a41026a360200200b41014b0d014100211402400240200b0e020100010b4100210d200241003a00b802200e20096b41026a210b200920046b417c6a210403400240200b200d6a0d00200d41ff0171450d04200241003a00b8020c040b20024198026a200d6a200a200d6a220e41026a2d00003a0000200120043602042001200e41036a3602002002200d41016a220e3a00b8022004417f6a2104200e210d200e4120470d000b200241f8016a41186a20024198026a41186a290300370300200241f8016a41106a20024198026a41106a290300370300200241f8016a41086a20024198026a41086a29030037030020022002290398023703f801410121140b20024198016a41186a200241f8016a41186a29030037030020024198016a41106a200241f8016a41106a29030037030020024198016a41086a200241f8016a41086a290300370300200241d4016a41026a200f2d00003a0000200241b8016a41086a2010290300370300200241b8016a41106a2011290300370300200241b8016a41186a20122d00003a0000200220022903f80137039801200220022f01f4013b01d401200220022903d8013703b8014101210d201421152013210c0c020b20024192016a41026a200241d4016a41026a2d00003a0000200241f8006a41086a200241b8016a41086a290300370300200241f8006a41106a200241b8016a41106a290300370300200241f8006a41186a200241b8016a41186a2d00003a0000200241d8006a41086a20024198016a41086a290300370300200241d8006a41106a20024198016a41106a290300370300200241d8006a41186a20024198016a41186a290300370300200220022f01d4013b019201200220022903b8013703782002200229039801370358200220022f0196013b01560c020b4102210d0b20024192016a41026a2204200241d4016a41026a2d00003a0000200241f8006a41086a220a200241b8016a41086a290300370300200241f8006a41106a220b200241b8016a41106a290300370300200241f8006a41186a2209200241b8016a41186a2d00003a0000200241d8006a41086a220f20024198016a41086a290300370300200241d8006a41106a221020024198016a41106a290300370300200241d8006a41186a221120024198016a41186a290300370300200220022f01d4013b019201200220022903b8013703782002200229039801370358200220022f0196013b0156200d4102460d00200841016a210e200241d2006a41026a221220042d00003a0000200241386a41086a2213200a290300370300200241386a41106a220a200b290300370300200241386a41186a220b20092d00003a0000200241186a41086a2209200f290300370300200241186a41106a220f2010290300370300200241186a41186a22102011290300370300200220022f0192013b01522002200229037837033820022002290358370318200220022f01563b011620032008470d02024020084101742204200e2004200e4b1b2203ad42c4007e2216422088a70d002016a7220441004e0d020b1031000b200041003602002003450d082006102a0c080b0240024020080d002004102821060c010b2006200841c4006c2004102c21060b2006450d030b2006200841c4006c6a2204200d3a00002004200c360004200441036a20122d00003a0000200420022f01523b0001200b2d0000210d200a29030021162013290300211720022903382118200420153a002120042018370008200441106a2017370000200441186a2016370000200441206a200d3a00002004413a6a2010290300370000200441326a200f2903003700002004412a6a200929030037000020042002290318370022200420022f01163b0042200e2108200e2005470d000b0b2000200336020420002006360200200041086a20053602000c040b200441041037000b200441041037000b1036000b200041003602000b200241c0026a24000baf04010a7f230041d0006b2202240020022001106c0240024002400240024020022802000d00200128020422034160712204417f4c0d022002280204210502400240200341057622060d00410121070c010b200410282207450d040b02402005450d00410021080340200241003a00482008220941016a21082001280204417f6a21034100210402400240024003402003417f460d01200241286a20046a2001280200220a2d00003a0000200120033602042001200a41016a3602002002200441016a220a3a00482003417f6a2103200a2104200a4120470d000b200241086a41186a2204200241286a41186a290300370300200241086a41106a220a200241286a41106a290300370300200241086a41086a220b200241286a41086a2903003703002002200229032837030820062009470d020240200941017422032008200320084b1b220641ffffff3f712006470d002006410574220341004e0d020b1031000b0240200441ff0171450d00200241003a00480b200041003602002006450d052007102a0c050b0240024020090d002003102821070c010b200720094105742003102c21070b2007450d070b200720094105746a22032002290308370000200341186a2004290300370000200341106a200a290300370000200341086a200b29030037000020082005470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241d0006a24000f0b1036000b200441011037000b200341011037000bb005020c7f037e230041f0006b2202240020022001106c0240024002400240024020022802000d00200128020441246e220341246c2204417f4c0d02200228020421050240024020040d00410421060c010b200410282206450d040b02402005450d00410021070340200241003a00682007220841016a210720012802042109417f210a410021040240024002400240034020092004460d01200241c8006a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a0068200a417f6a210a200c2104200c4120470d000b200241286a41186a2204200241c8006a41186a290300370300200241286a41106a220a200241c8006a41106a290300370300200241286a41086a220d200241c8006a41086a290300370300200220022903483703282009200c6b220c4104490d01200b28000121092001200b41056a3602002001200c417c6a360204200241086a41086a220c200d290300370300200241086a41106a220b200a290300370300200241086a41186a220a20042903003703002002200229032837030820032008470d030240200841017422042007200420074b1b2203ad42247e220e422088a70d00200ea7220441004e0d030b1031000b200441ff0171450d00200241003a00680b200041003602002003450d052006102a0c050b0240024020080d002004102821060c010b2006200841246c2004102c21060b2006450d070b2006200841246c6a22042002290308370200200c290300210e200b290300210f200a290300211020042009360220200441186a2010370200200441106a200f370200200441086a200e37020020072005470d000b0b2000200336020420002006360200200041086a20053602000c010b200041003602000b200241f0006a24000f0b1036000b200441041037000b200441041037000be60403087f017e017f230041f0016b22022400200241086a2001106c02400240024002400240024020022802080d00200128020441f0006e220341f0006c2204417f4c0d02200228020c21050240024020040d00410421060c010b200410282206450d040b024002402005450d00410021074100210841002109034020024180016a2001107f200228028401450d02200941016a2104200241106a20024180016a41f000109a051a024020092003470d0020072004200720044b1b2203ad42f0007e220a422088a70d09200aa7220b4100480d090240024020090d00200b102821060c010b20062008200b102c21060b2006450d080b200620086a200241106a41f000109a051a200741026a2107200841f0006a21082004210920052004470d000b0b2000200336020420002006360200200041086a20053602000c020b2000410036020002402009450d00200620086a210120062107034002402007410c6a2802002209450d0020072802042104200941246c210903400240024020042d0000220841034b0d0002400240024020080e0404000102040b2004410c6a280200450d03200441086a280200102a0c030b2004410c6a280200450d02200441086a280200102a0c020b2004410c6a280200450d01200441086a280200102a0c010b200441086a280200450d00200441046a280200102a0b200441246a21042009415c6a22090d000b0b200741f0006a21040240200741086a280200450d002007280204102a0b2004210720012004470d000b0b2003450d012006102a0c010b200041003602000b200241f0016a24000f0b1036000b200441041037000b200b41041037000b1031000b9f0a03077f037e057f230041d0026b2202240041002103200241003a00c8022001280204417f6a210402400240024003402004417f460d01200241a8026a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c8022004417f6a21042005210320054120470d000b200241e8006a41086a200241a8026a41086a290300370300200241e8006a41106a200241a8026a41106a290300370300200241e8006a41186a200241a8026a41186a290300370300200220022903a80237036820022001106c2002280200450d01200041003602040c020b0240200341ff0171450d00200241003a00c8020b200041003602040c010b2002280204210641002104200241003a00c80220012802042107417f21030240034020072004460d01200241a8026a20046a200128020022082d00003a00002001200720036a3602042001200841016a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241a8016a41086a200241a8026a41086a2903002209370300200241a8016a41106a200241a8026a41106a290300220a370300200241a8016a41186a200241a8026a41186a290300220b37030020024188016a41086a200937030020024188016a41106a200a37030020024188016a41186a200b370300200220022903a80222093703a801200220093703880141002104200241003a00c802200720056b210c200720036a210303400240200c2004470d000240200441ff0171450d00200241003a00c8020b200041003602040c030b200241a8026a20046a200820046a220541016a2d00003a0000200120033602042001200541026a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241e8016a41086a200241a8026a41086a2903002209370300200241e8016a41106a200241a8026a41106a290300220a370300200241e8016a41186a200241a8026a41186a290300220b370300200241c8016a41086a22042009370300200241c8016a41106a2203200a370300200241c8016a41186a2205200b370300200220022903a80222093703e801200220093703c801200241a8026a20011076024020022802a8022201450d00200241c8006a41086a2208200241e8006a41086a290300370300200241c8006a41106a2207200241e8006a41106a290300370300200241c8006a41186a220c200241e8006a41186a290300370300200241286a41086a220d20024188016a41086a290300370300200241286a41106a220e20024188016a41106a290300370300200241286a41186a220f20024188016a41186a29030037030020022002290368370348200220022903880137032820022902ac022109200241086a41186a22102005290300370300200241086a41106a22052003290300370300200241086a41086a22032004290300370300200220022903c801370308200020093702082000200136020420002006360200200041106a2002290348370200200041186a2008290300370200200041206a2007290300370200200041286a200c290300370200200041306a2002290328370200200041386a200d290300370200200041c0006a200e290300370200200041c8006a200f290300370200200041e8006a2010290300370200200041e0006a2005290300370200200041d8006a2003290300370200200041d0006a20022903083702000c020b200041003602040c010b0240200441ff0171450d00200241003a00c8020b200041003602040b200241d0026a24000b9505020c7f017e230041b0056b22022400200241086a2001106c0240024002400240024020022802080d0020012802044190016e22034190016c2204417f4c0d02200228020c21050240024020040d00410821060c010b200410282206450d040b02402005450d00200241a0036a410472210741002108410021044100210903400240024002402001280204220a450d002001280200220b2d0000210c2001200a417f6a3602042001200b41016a360200200c41014b0d004113210a024002400240200c0e020100010b200241a8046a200110810120022802a8044113460d02200241a0036a200241a8046a418801109a051a2001280204220c4104490d012001280200220a280000210d2001200c417c6a3602042001200a41046a36020020022802a003210a2002419c026a2007418401109a051a200a4113460d0220024198016a2002419c026a418401109a051a200a4114460d020b200941016a210c200241146a20024198016a418401109a051a20092003470d0302402008200c2008200c4b1b2203ad4290017e220e422088a70d00200ea7220b41004e0d030b1031000b200241a0036a106a0b2000410036020002402009450d00200621010340024020012802004113460d002001106a0b20014190016a2101200441f07e6a22040d000b0b2003450d052006102a0c050b0240024020090d00200b102821060c010b20062004200b102c21060b2006450d070b200620046a2209200a360200200941046a200241146a418401109a051a20094188016a200d360200200841026a210820044190016a2104200c21092005200c470d000b0b2000200336020420002006360200200041086a20053602000c010b200041003602000b200241b0056a24000f0b1036000b200441081037000b200b41081037000bf3910107087f017e067f087e087f017e017f230041f0096b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541144b0d16200141046a210720050e150102030405060708090a0b0c0d0e0f101112131415010b200041133602000c4c0b02402006450d0020042d0001210620012003417e6a22083602042001200441026a360200200641054b0d004101210902400240024002400240024020060e06510001020304510b20022001106c20022802000d05200128020420022802042204490d052004417f4c0d1e02400240024020040d00410121050c010b2004102e2205450d0120072802002004490d06200520012802002004109a051a200128020422032004490d212001200320046b3602042001200128020020046a3602000b2005450d062004ad220a422086200a84210a410221090c510b200441011037000b20084108490d042004290002210a2001200341766a36020420012004410a6a360200410321090c4f0b200241086a2001106c20022802080d032001280204200228020c2204490d032004417f4c0d1c02400240024020040d00410121050c010b2004102e2205450d0120072802002004490d04200520012802002004109a051a200128020422032004490d202001200320046b3602042001200128020020046a3602000b2005450d042004ad220a422086200a84210a410421090c4f0b200441011037000b200241206a2001106c20022802200d02200728020041186e220b41186c2204417f4c0d1b2002280224210c0240024020040d00410421050c010b200410282205450d1f0b0240200c450d004100210d41002106410021080340200241186a2001106c02400240024020022802180d002001280204200228021c2204490d002004417f4c0d2002400240024020040d004101210e0c010b2004102e220e450d3920072802002004490d01200e20012802002004109a051a200128020422032004490d262001200320046b3602042001200128020020046a3602000b200241106a2001106c024020022802100d00200128020420022802142203490d002003417f4c0d22024002400240024020030d004101210f0c010b2003102e220f450d0120072802002003490d02200f20012802002003109a051a200128020422092003490d2a2001200920036b3602042001200128020020036a3602000b200841016a21092008200b470d06200d2009200d20094b1b220bad42187e220a422088a70d55200aa7221041004e0d050c550b200341011037000b200f102a0b2004450d010b200e102a0b02402008450d002005210103400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141186a2101200641686a22060d000b0b200b0d050c060b0240024020080d002010102821050c010b200520062010102c21050b2005450d240b200520066a2208200e360200200841146a2003ad220a3e02002008410c6a200a422086200fad84370200200841046a2004ad220a422086200a84370200200d41026a210d200641186a210620092108200c2009470d000b0b2005450d02200cad422086200bad84210a410521090c4d0b200241306a2001106c20022802300d012007280200410c6e220e410c6c2204417f4c0d1a2002280234210f0240024020040d00410421050c010b200410282205450d220b024002400240200f450d004100210841002103410021090340200241286a2001106c20022802280d032001280204200228022c2204490d032004417f4c0d1e0240024020040d004101210d0c010b2004102e220d450d3720072802002004490d03200d20012802002004109a051a200128020422062004490d272001200620046b3602042001200128020020046a3602000b200941016a210602402009200e470d0020082006200820064b1b220ead420c7e220a422088a70d50200aa7220b4100480d500240024020090d00200b102821050c010b20052003200b102c21050b2005450d280b200520036a2209200d360200200941086a2004360200200941046a2004360200200841026a21082003410c6a210320062109200f2006470d000b0b2005450d03200fad422086200ead84210a410621090c4e0b200d102a0b02402009450d002005210103400240200141046a280200450d002001280200102a0b2001410c6a2101200341746a22030d000b0b200e450d010b2005102a0b200041133602000c4b0b02402006450d0020012003417e6a3602042001200441026a3602000b200041133602000c4a0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241386a2001109e012002290338a70d002002290340210a20004102360200200041086a200a370300200041106a200241e8086a41f800109a051a0c4a0b200041133602000c490b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241e0076a2001107e20022802e00722010d130b200041133602000c480b02402006450d0020012003417e6a3602042001200441026a3602000b200041133602000c470b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541024b0d00024002400240024020050e03000102000b200241e8086a200110a50120022d00e8084102460d0320024184096a290200210a200241fc086a2902002111200241e8086a41106a2802002107200241f4086a2802002104200241f0086a280200210320022802ec08210520022802e8082106200241c8006a2001109f0120022802480d03200241c8006a41106a290300211241012101200229035021130c020b200241e8086a200110a50120022d00e8084102460d02200241e0076a41086a20024180096a290300370300200241e0076a41106a20024188096a2802003602002002200241e8086a41106a2903003703e007200241f4086a2802002104200241e8086a41086a280200210320022802ec08210520022802e8082106200241f8006a2001109f012002290378a70d02200241f8006a41106a29030021122002290380012113200241e0006a2001109f012002290360a70d02200241e0006a41106a290300211420022903682115200241a8056a41106a200241e0076a41106a280200360200200241a8056a41086a200241e0076a41086a290300370300200220022903e00722163703a805200241b4056a290200210a20022902ac0521112016a7210741022101420021160c010b200241e8086a200110a50120022d00e8084102460d0120024184096a290200210a200241fc086a2902002111200241e8086a41106a22092802002107200241f4086a2802002104200241e8086a41086a2208280200210320022802ec08210520022802e8082106200241e8086a200110a50120022d00e8084102460d01200241e0076a41206a220d200241e8086a41206a280200360200200241e0076a41186a220e200241e8086a41186a290300370300200241e0076a41106a2009290300370300200241e0076a41086a2008290300370300200220022903e8083703e00720024190016a2001109f01200229039001a70d0120024190016a41106a29030021172002290398012118200241e8076a2903002112200241f0076a2903002115200e2903002114200d350200211620022903e0072113410321010b20004105360200200041e0006a2017370200200041d8006a2018370200200041c8006a2014370200200041c0006a2015370200200041386a2012370200200041306a2013370200200041286a200a370200200041206a2011370200200041d0006a20163702002000411c6a2007360200200041186a2004360200200041146a2003360200200041106a20053602002000410c6a2006360200200041086a2001360200200041e8006a200229038806370300200041f0006a20024188066a41086a290300370300200041f8006a20024188066a41106a29030037030020004180016a20024188066a41186a2903003703000c470b200041133602000c460b2006450d4120042d0001210520012003417e6a22193602042001200441026a3602002005410c4b0d41410421104100211a4100211b02400240024002400240024002400240024002400240024020050e0d0001024e030405060708090a0b000b200241e0076a200110a50120022d00e0074102460d4c200241ec076a290200211120024180086a280200210b200241ff076a2d00002108200241fe076a2d0000210d200241fd076a2d0000210c200241f9076a2800002104200241f5076a280000210f200241f4076a2d0000210e20022902e407210a20022802e0072106200241a8016a2001109f0120022903a801a70d4c20072802002203450d4c200241b8016a290300211320022903b0012112200128020022052d0000210920012003417f6a360204410121102001200541016a36020020094103492201450d4c200441807e71410020011b211b2004410020011b211a0c4d0b200241c0016a2001109f0120022903c001a70d4b200241d0016a290300211120022903c801210a410221104100211b0c4c0b200241d8016a2001109f0120022903d801a70d4a200241e8016a290300211120022903e001210a410321104100210c4100211a4100211b0c4b0b200241f0016a2001109f0120022903f001a70d4920024180026a290300211120022903f801210a410521104100211b0c4a0b20024188026a2001106c2002280288020d48200728020041246e221c41246c2204417f4c0d19200228028c02211d0240024020040d00410421060c010b200410282206450d240b0240201d450d0041232105200241f0076a211e41002107410021040340200241e0076a200110a501024020022d00e00722094102470d00201c450d4b2006102a0c4b0b200441016a2103201e290300210a20022903e807211120022d008308210820022d008208210d20022d008108210e20022800fd07210f20022800f907210b20022d00f807210c20022802e407211020022d00e307211b20022d00e207211920022d00e107211f02402004201c470d0020072003200720034b1b221cad42247e2212422088a70d4d2012a722204100480d4d0240024020040d002020102821060c010b20062005415d6a2020102c21060b2006450d270b200620056a220420083a0000200441656a2208200a370008200820113700002004417f6a200d3a00002004417e6a200e3a00002004417a6a200f360000200441766a200b360000200441756a200c3a0000200441616a2010360000200441606a201b3a00002004415f6a20193a00002004415e6a201f3a00002004415d6a20093a0000200741026a2107200541246a210520032104201d2003470d000b0b2006450d48201dad422086201cad84210a42002111410621104100211b0c490b410721104100211b0c480b2019450d4620042d0002210920012003417d6a3602042001200441036a360200200941034f0d46410821104100211b0c470b200241e0076a200110a50120022d00e0074102460d45200241f9076a280000221a41807e71211b200241ec076a290200211120024180086a280200210b200241ff076a2d00002108200241fe076a2d0000210d200241fd076a2d0000210c200241f5076a280000210f200241f4076a2d0000210e20022902e407210a20022802e0072106410921100c460b20024190026a2001106c2002280290020d442002280294022106410a21104100211b0c450b410b21104100211b0c440b410c21104100211b0c430b200241e0076a2001106d20022802e0072206450d4120022902e407210a42002111410d21104100211b0c420b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241e8086a200110e80120022d00e8084101460d00200241e0076a200241e8086a41017241e000109a051a20024198026a2001106c2002280298020d002001280204200228029c022204490d002004417f4c0d12024002400240024020040d004101210341010d010c040b2004102e2203450d0120072802002004490d02200320012802002004109a052105200128020422062004490d212001200620046b3602042001200128020020046a3602002005450d030b20024188066a200241e0076a41e000109a051a200241a8056a20024188066a41e000109a051a2000410c6a2004360200200041086a20043602002000200336020420004107360200200041106a200241a8056a41e000109a051a20004180016a20024188076a41106a290300370300200041f8006a20024188076a41086a290300370300200041f0006a2002290388073703000c470b200441011037000b2003102a0b200041133602000c440b2006450d3e20042d0001210520012003417e6a221d3602042001200441026a360200200541104b0d3e410e211a4100211c024002400240024002400240024002400240024002400240024002400240024020050e11000102030405060708090a0b0c4d0d0e0f000b200241e0076a200110810120022802e0074113460d4d200241e8086a200241e0076a418801109a051a41880110282206450d382006200241e8086a418801109a052104200241a0026a2001109f01024020022903a002a7450d002004106a2004102a0c4e0b200241b0026a290300210a2004411876211c20022903a8022211422088a7211f2011a7211b4101211a0c4c0b200241b8026a2001106c20022802b8020d4c20022802bc022206411876211c4102211a0c4a0b200241c0026a2001106c20022802c0020d4b20072802002204450d4b20022802c4022106200128020022052d0000210320012004417f6a3602042001200541016a360200200341ff0071220d41064b0d4b2006411876211c200341077621084103211a0c480b200241c8026a2001106c20022802c8020d4a20072802002204450d4a20022802cc022106200128020022052d0000210320012004417f6a3602042001200541016a360200200341ff0071220d41064b0d4a2006411876211c200341077621084104211a0c470b201d4104490d492004280002210620012003417a6a3602042001200441066a3602002006411876211c4105211a0c470b200241e0076a200110810120022802e0074113460d48200241e8086a200241e0076a418801109a051a41880110282206450d342006200241e8086a418801109a05411876211c4106211a0c460b200241e0076a200110810120022802e0074113460d47200241e8086a200241e0076a418801109a051a41880110282206450d342006200241e8086a418801109a05411876211c4107211a0c450b200241e0076a200110810120022802e0074113460d46200241e8086a200241e0076a418801109a051a41880110282206450d342006200241e8086a418801109a05411876211c4108211a0c440b41002105200241003a0088092003417e6a2109417d21060340024020092005470d00200541ff0171450d47200241003a0088090c470b200241e8086a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a0088092006417f6a21062007210520074120470d000b200241b0056a2205200241f1086a290000370300200241a8056a41106a200241f9086a290000370300200241bf056a220620024180096a290000370000200220022900e908220a3703a805200320076b2203417e6a4104490d4520022d00ac05210920022f01aa05210d200241b5056a330000211120023500b105211220052d0000211b20022f01ae05211a200241bd056a3100002113200241bb056a330000211620023500b705211820022d00e80821082006280000210f20022d00ad05211c20022d00a905211020022800c305210b20022d00be05210e200420076a220441026a280000210c20012003417a6a22053602042001200441066a220736020020054104490d45200d2009411074722106200aa7210d200728000021192001200341766a36020420012004410a6a36020020182016201342108684422086844208862012201142208684221142ffffffffffff3f83221242288884210a2012421886201a201b41107472ad42ffffff078384a7211b2011420888a7211f4109211a0c440b41002105200241003a0088092003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d46200241003a0088090c460b200241e8086a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0088092003417f6a21032006210520064120470d000b200241b0056a200241f1086a290000370300200241bf056a220120024180096a290000370000200241a8056a41106a200241f9086a290000370300200220022900e90822113703a80520022f01aa0520022d00ac0541107472210620022901ae052212422088a7211f20022d00e80821082001280000210f200241b6056a290100210a20022d00ad05211c20022d00a905211020022800c305210b20022d00be05210e2011a7210d2012a7211b410a211a0c430b200241d0026a2001106c20022802d0020d4320022802d4022206411876211c410b211a0c410b200241e8026a2001106c20022802e8020d4220022802ec022106200241e0026a2001106c20022802e0020d4220022802e402211b200241d8026a2001106c20022802d8020d4220022802dc02211f2006411876211c410c211a0c410b41002105200241003a0088092003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d43200241003a0088090c430b200241e8086a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0088092003417f6a21032006210520064120470d000b200241b0056a200241f1086a290000370300200241bf056a220120024180096a290000370000200241a8056a41106a200241f9086a290000370300200220022900e90822113703a80520022f01aa0520022d00ac0541107472210620022901ae052212422088a7211f20022d00e80821082001280000210f200241b6056a290100210a20022d00ad05211c20022d00a905211020022800c305210b20022d00be05210e2011a7210d2012a7211b410d211a0c400b41002105200241003a0088092003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d42200241003a0088090c420b200241e8086a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0088092003417f6a21032006210520064120470d000b200241b0056a2201200241f1086a290000370300200241a8056a41106a200241f9086a290000370300200241bf056a220420024180096a290000370000200220022900e90822123703a80520023500b705200241bb056a330000200241bd056a310000421086844220868442088620023500b105200241b5056a33000042208684221142288884210a201142188620023301ae0520013100004210868484a7211b20022f01aa0520022d00ac054110747221062011420888a7211f20022d00e80821082004280000210f20022d00ad05211c20022d00a905211020022800c305210b20022d00be05210e2012a7210d410f211a0c3f0b41002105200241003a0088092003417e6a21092003417d6a21060340024020092005470d00200541ff0171450d41200241003a0088090c410b200241e8086a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a0088092006417f6a21062007210520074120470d000b200241b0056a200241f1086a290000370300200241b8056a200241f9086a290000370300200241bf056a220520024180096a290000370000200220022900e908220a3703a805200241d8076a41046a20022d00ac053a0000200241e8066a41046a200241b5056a2f00003b01002002200a3e02d807200220022800b1053602e8062003417e6a2007460d3f20022d00e808210820022800ad05211c2005290000211120022900b705210a200420076a220441026a2d00002109200120063602042001200441036a360200200941064b0d3f20024190076a200241e8066a41046a2f01003b0100200220022802d807220d3602d007200220022802e80636028c072002201c360288072002200a37019207200a423888201142088684a7210e4110211a20022f01d207200241d8076a41046a2d00004110747221062011422088a7210b2002290089072212422088a7211f20024191076a290000210a20022d00d10721102011a7210f2012a7211b0c3e0b4111211a0c3d0b200241e0076a200110e90120022d00e0074105470d0d200041133602000c420b200241e0076a200110e90120022d00e0074105470d0d200041133602000c410b2006450d3720042d0001210520012003417e6a3602042001200441026a360200200541094b0d37024002400240024002400240024002400240024020050e0a00010203040506070809000b200241e0076a2001107520022802e0072204450d40200241e8076a280200210520022802e4072103200241f0026a2001106c024020022802f002450d0020030d400c410b0240200728020022094104490d0020022802f402210620012802002208280000210720012009417c6a220d3602042001200841046a360200200d4110490d002008410c6a29000021122008290004211320012009416c6a3602042001200841146a360200410121010c3f0b20030d3f0c400b200241e0076a2001107520022802e0072204450d3f200241e8076a280200210520022802e4072103200241f8026a2001106c024020022802f802450d002003450d400c3f0b0240200728020022094104490d0020022802fc02210620012802002208280000210720012009417c6a220d3602042001200841046a360200200d4110490d002008410c6a29000021122008290004211320012009416c6a3602042001200841146a360200410221010c3e0b20030d3e0c3f0b20024190036a2001106c2002280290030d3e2002280294032104200241e0076a200110a50120022d00e0074102460d3e20024188066a41086a200241f8076a29030037030020024188066a41106a20024180086a2802003602002002200241e0076a41106a29030037038806200241ec076a2802002107200241e0076a41086a280200210620022802e407210520022802e007210320024188036a2001106c2002280288030d3e200228028c03210920024180036a2001106c2002280280030d3e20024198066a280200210820024190066a29030021122002290388062113200228028403ad210a42002111410321010c3c0b20024198036a2001106c2002280298030d3d41042101200228029c0321040c3b0b200241a0036a2001106c20022802a0030d3c4105210120022802a40321040c3a0b200241e0076a200110a50120022d00e0074102460d3b20024188066a41086a200241f8076a29030037030020024188066a41106a20024180086a2802003602002002200241e0076a41106a29030037038806200241e0076a41086a290300211620022903e0072118200241b0036a2001109f0120022903b003a70d3b200241b0036a41106a290300211120022903b803210a200241a8036a2001106c20022802a8030d3b20022802ac032108200241a8056a41106a20024188066a41106a280200360200200241a8056a41086a20024188066a41086a290300370300200220022903880622173703a8052018422088a721032016422088a72106200241b4056a290200211220022902ac0521132017a721072018a721042016a72105410621010c390b200241c8036a2001106c20022802c8030d3a4107210120022802cc0321040c380b200241e0076a200110a50120022d00e0074102460d39200241fc076a2902002112200241f4076a2902002113200241f0076a2802002107200241ec076a280200210641082101200241e0076a41086a280200210520022802e407210320022802e00721040c370b200241d0036a2001106c20022802d0030d384109210120022802d40321040c360b200241d8036a2001106c20022802d8030d37410a210120022802dc0321040c350b2006450d3320042d0001210520012003417e6a3602042001200441026a360200200541034b0d33024002400240024020050e0400010203000b41002105200241003a0080082003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d38200241003a0080080c380b200241e0076a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0080082003417f6a21032006210520064120470d000b200241a8056a41106a200241f1076a290000370300200241b0056a200241e0076a41096a290000220a370300200241bf056a2201200241e0076a41186a290000370000200241e8066a41096a200a370000200241e8066a41106a200241b7056a290000370000200220022d00e007220d3a00e806200220022900e1073700e9062001280000210f20022800c305210b20022800ef06220c411876211020022800eb062201411876210820022d00ff06211b20022900f706211220022800f306211a20022d00ea06211920022d00e906211f4101211c0c350b41002105200241003a0080082003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d37200241003a0080080c370b200241e0076a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0080082003417f6a21032006210520064120470d000b200241b0056a200241e9076a290000370300200241bf056a2204200241e0076a41186a290000370000200241a8056a41106a200241f1076a290000370300200220022900e107220a3703a80520022f01aa0520022d00ac0541107472210120022901ae052211a7220c41187621102011422088a7211a20022d00e007210d2004280000210f200241b6056a290100211220022d00ad05210820022d00a905211920022800c305210b20022d00be05211b200aa7211f4102211c0c340b41002105200241003a008008410220036b21092003417d6a210603400240200920056a0d00200541ff0171450d36200241003a0080080c360b200241e0076a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a0080082006417f6a21062007210520074120470d000b200241b0056a200241e9076a290000370300200241b8056a200241f1076a290000370300200241bf056a2205200241f8076a290000370000200220022900e107220a3703a805200241d8076a41046a20022d00ac053a0000200241e8066a41046a200241b5056a2f00003b01002002200a3e02d807200220022800b1053602e80620022d00e007210d20022800ad0521082005290000211320022900b705211241002105200241003a008008200420076a2109200720036b41026a210303400240200320056a0d00200541ff0171450d36200241003a0080080c360b200241e0076a20056a200920056a220441026a2d00003a0000200120063602042001200441036a3602002002200541016a22043a0080082006417f6a21062004210520044120470d000b200241bf056a2201200241f8076a290000370000200241a8056a41106a200241f1076a290000370300200241a8056a41086a2203200241e9076a290000370300200220022900e10722163703a80520022d00e007210420012800002109200241bb056a3300002111200241bd056a3100002118200241b5056a330000210a2003310000211720022801aa05210620022d00a905210520022800c305210e20022d00be05210720023500b705211520023500b105211420023301ae052121200241d0076a41046a2201200241d8076a41046a2d00003a0000200220022802d8073602d007200220083602880720024188076a41086a200241e8066a41046a2f01003b0100200220022802e80636028c0720022012370192072002419a076a20133701002014200a422086842214421886202120174210868484210a201520112018421086844220868442088620144228888421112012423888201342088684a7211b2008410876210c20022f01d20720012d00004110747221012013422088a7210b2002290091072112200228008d07211a20022d008c07211020022d00d107211920022d00d007211f2016a721032013a7210f4103211c0c330b200241e0076a2001106d20022802e0072201450d3320022802e407220c411876211020014118762108200241e8076a280200211a4104211c0c320b024002402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241e0036a2001106c20022802e003450d010b200041133602000c3f0b20022802e40321012000410d36020020002001360204200041086a200241e8086a418001109a051a0c3e0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241e8036a2001106c20022802e8030d00200128020420022802ec032204490d002004417f4c0d0b024002400240024020040d00410121030c010b2004102e2203450d0120072802002004490d02200320012802002004109a051a200128020422052004490d1b2001200520046b3602042001200128020020046a3602000b2003450d02200020033602042000410e360200200041086a2004ad220a422086200a84370200200041106a200241e8086a41f800109a051a0c400b200441011037000b2003102a0b200041133602000c3d0b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541024b0d0002400240024020050e03000102000b200241f0036a2001109f0120022903f003a70d0220024180046a290300210a20022903f8032111200241e0076a200110a50120022d00e0074102460d02200241fc076a2902002112200241f4076a2902002113200241f0076a2802002101200241ec076a2802002104200241e8076a280200210320022802e407210520022802e0072106410121070c310b20024188046a2001106c2002280288040d0141022107200228028c0421060c300b20024190046a2001106c2002280290040d004103210720022802940421060c2f0b200041133602000c3c0b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541044b0d0002400240024002400240024002400240024020050e050001020607000b200241e8086a200110ea0120022d00d8094102460d08200241e8076a20024198096a290300370300200241f0076a200241a0096a29030037030020022002290390093703e0072002418c096a280200210b20024184096a2802002104200241fd086a2800002108200241f9086a280000210d200228028809211b20022d008309210520022d008209210620022d008109210f20022d00f808210e20022903f008210a20022903e8082111200241d8096a2903002113200241b8096a2903002116200241c5096a2800002101200241c1096a280000210320022903d009211820022903b009211720022802cc09210720022d00cb09210c20022d00ca09211f20022d00c909211c20022d00c009211d20022903a8092112410121220c020b200241a0046a2001109e0120022903a004a70d0720022903a804210a20024198046a2001106c2002280298040d072001280204200228029c042204490d072004417f4c0d1002400240024020040d00410121090c010b2004102e2209450d0120072802002004490d08200920012802002004109a051a200128020422032004490d202001200320046b3602042001200128020020046a3602000b2009450d082004ad22114220862011842111200241e0076a41106a200241e8086a41106a290300370300200241e0076a41086a200241e8086a41086a290300370300200220022903e8083703e007410221220c350b200441011037000b200241e8086a200110a50120022d00e8084102460d06200241f4086a290200210a20024188096a280200210420024187096a2d0000210520024186096a2d0000210620024185096a2d0000210f20024181096a2800002108200241fd086a280000210d200241fc086a2d0000210e20022902ec08211120022802e8082109200241c8046a2001109f0120022903c804a70d06200241d8046a290300211320022903d0042116200241b8046a2001109e0120022903b804a70d0620022903c0042112200241b0046a2001106c20022802b0040d06200128020420022802b404220b490d06200b417f4c0d0f02400240200b0d004101211b41010d010c080b200b102e221b450d022007280200200b490d03201b2001280200200b109a05210320012802042207200b490d1f20012007200b6b36020420012001280200200b6a3602002003450d070b200241f0076a2013370300200220163703e8072002200b3602e007410321220b0c320b200b41011037000b201b102a0c030b200241f8046a2001109f0120022903f804a70d0220024188056a290300210a2002290380052111200241e8046a2001109e0120022903e804a70d0220022903f004211241002103200241003a0088092007280200417f6a21040240024002400240024003402004417f460d01200241e8086a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a0088092004417f6a21042005210320054120470d000b20024190076a200241e8086a410e6a290100221337030020024198076a200241e8086a41166a2204290100370300200241a0076a20024186096a2f01003b0100200241e8066a410e6a2013370100200241e8066a41166a20042f01003b0100200220022d00e80822103a00e806200220022800e9083600e906200220022d00ed083a00ed06200220022901ee0822133701ee062002201337038807200228019e072108200228019a07210d200241e0046a2001106c20022802e0040d07200128020420022802e404220b490d07200b417f4c0d10200b0d01410121040c020b200341ff0171450d06200241003a0088090c060b200b102e2204450d012007280200200b490d0220042001280200200b109a051a20012802042203200b490d1e20012003200b6b36020420012001280200200b6a3602000b2004450d04200220113703e007200220123703f0072002200a3703e807200241f7066a290000210a20022900ef06211120022d00ff06210e20022800eb06210920022d00ea06211a20022d00e906211941042122200b211b0c310b200b41011037000b2004102a0c020b41002105200241003a0088092003417e6a21092003417d6a21060340024020092005470d00200541ff0171450d03200241003a0088090c030b200241e8086a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a0088092006417f6a21062007210520074120470d000b2003417e6a2007460d01200241f7086a290000210a20022900ef08211120022d00e808211020022d00e908211920022d00ea08211a20022800eb08210920022d00ff08210e200228028009210d2002280284092108200420076a220c41026a2d0000211f200120063602042001200c41036a360200201f41014b0d014100210f02400240201f0e020100010b41002104200241003a008809200720036b41036a2106200320076b417c6a210303400240200620046a0d00200441ff0171450d04200241003a0088090c040b200241e8086a20046a200c20046a220541036a2d00003a0000200120033602042001200541046a3602002002200441016a22053a0088092003417f6a21032005210420054120470d000b200241b0056a200241f1086a290000370300200241b8056a200241f9086a290000370300200241bf056a220120024180096a290000370000200220022900e90822123703a805200241d8076a41046a20022d00ac053a0000200241e8066a41046a2203200241b5056a2f00003b0100200220123e02d807200220022800b1053602e80620022d00e808210620022800ad05211b2001290000211320022900b705211220022802e806210b20022800d907210420022d00d8072105200220032f01003b0188074101210f0b200241ea076a2013370100200241f6076a200241ce076a2f01003b0100200220022f0188073b01e007200220123701e207200220022801ca073601f207410521220c2e0b2009102a0b200041133602000c3b0b2006450d2a20042d0001210520012003417e6a3602042001200441026a360200200541024b0d2a0240024002400240024020050e03000102000b200241e0076a200110810120022802e0074113470d020c2e0b200241e8086a200110a5014102210120022d00e8084102460d2d200241a8056a41106a20024188096a280200360200200241a8056a41086a20024180096a2903003703002002200241e8086a41106a29030022123703a80520022903e8082213422088a72103200241e8086a41086a2903002216422088a72105200241b4056a290200210a20022902ac0521112013a721042012a721062016a721070c020b200241e8086a200110a50120022d00e8084102460d2c20024184096a290200210a200241fc086a2902002111200241f8086a2802002106200241f4086a2802002105200241f0086a280200210720022802ec08210320022802e8082104200241e0076a200110810120022802e0074113460d2c200241e8086a200241e0076a418801109a051a41880110282209450d1b2009200241e8086a418801109a051a410321010c010b200241e8086a200241e0076a418801109a051a41880110282204450d192004200241e8086a418801109a051a410121010b2000200136020420004111360200200041246a200a3702002000411c6a20113702002000412c6a2009360200200041186a2006360200200041146a2005360200200041106a20073602002000410c6a2003360200200041086a2004360200200041306a20024188066a41d800109a051a0c3a0b2006450d2820042d0001210520012003417e6a22063602042001200441026a36020020050d2820064104490d282004280002210b20012003417a6a3602042001200441066a360200200241a0056a2001106c20022802a0050d28200128020420022802a4052205490d282005417f4c0d060240024020050d004101210c41010d010c2a0b2005102e220c450d2520072802002005490d28200c20012802002005109a052104200128020422032005490d1a2001200320056b3602042001200128020020056a3602002004450d290b20024198056a2001106c2002280298050d262007280200410c6e220f410c6c2204417f4c0d06200228029c0521100240024020040d004104210e0c010b20041028220e450d1b0b0240024002400240024002402010450d00410021084100210341002109034020024190056a2001106c2002280290050d0320012802042002280294052204490d032004417f4c0d0d0240024020040d004101210d0c010b2004102e220d450d2b20072802002004490d03200d20012802002004109a051a200128020422062004490d232001200620046b3602042001200128020020046a3602000b200941016a210602402009200f470d0020082006200820064b1b220fad420c7e220a422088a70d3f200aa7221b4100480d3f0240024020090d00201b1028210e0c010b200e2003201b102c210e0b200e450d240b200e20036a2209200d360200200941046a2004ad220a422086200a84370200200841026a21082003410c6a21032006210920102006470d000b0b200e450d2b200c450d2d200728020022034104490d0220012802002207280000210820012003417c6a22043602042001200741046a36020020044104490d032007280004210d2001200341786a22093602042001200741086a36020041002104200241003a00a809200341776a2103034020092004460d05200241e8086a20046a200720046a220641086a2d00003a0000200120033602042001200641096a3602002002200441016a22063a00a8092003417f6a210320062104200641c000470d000b200241e0076a41386a2201200241e8086a41386a290300370300200241e0076a41306a2204200241e8086a41306a290300370300200241e0076a41286a2203200241e8086a41286a290300370300200241e0076a41206a2207200241e8086a41206a290300370300200241e0076a41186a2209200241e8086a41186a290300370300200241e0076a41106a221b200241e8086a41106a290300370300200241e0076a41086a221a200241e8086a41086a290300370300200220022903e8083703e007200641ff017141c000490d2a20024188066a41386a2206200129030037030020024188066a41306a2004290300220a37030020024188066a41286a2003290300221137030020024188066a41206a2007290300221237030020024188066a41186a2009290300221337030020024188066a41106a201b290300221637030020024188066a41086a201a2903002218370300200220022903e007221737038806200241a8056a41306a200a370300200241a8056a41286a2011370300200241a8056a41206a2012370300200241a8056a41186a2013370300200241a8056a41106a2016370300200241a8056a41086a2018370300200241a8056a41386a2006290300370300200220173703a805200c450d2d20024188076a41386a2201200241a8056a41386a29030037030020024188076a41306a2204200241a8056a41306a29030037030020024188076a41286a2203200241a8056a41286a29030037030020024188076a41206a2206200241a8056a41206a29030037030020024188076a41186a2207200241a8056a41186a29030037030020024188076a41106a2209200241a8056a41106a29030037030020024188076a41086a221b200241a8056a41086a290300370300200220022903a80537038807200041246a200d360200200041206a20083602002000411c6a2010360200200041186a200f360200200041146a200e360200200041106a20053602002000410c6a2005360200200041086a200c3602002000200b36020420004112360200200041286a200229038807370200200041306a201b290300370200200041386a2009290300370200200041c0006a2007290300370200200041c8006a2006290300370200200041d0006a2003290300370200200041d8006a2004290300370200200041e0006a200129030037020020004180016a200241e8066a41186a290300370300200041f8006a200241e8066a41106a290300370300200041f0006a200241e8066a41086a290300370300200041e8006a20022903e8063703000c3e0b200d102a0b02402009450d00200e210103400240200141046a280200450d002001280200102a0b2001410c6a2101200341746a22030d000b0b200f450d29200e102a0c290b02402005450d00200c102a0b02402010450d002010410c6c2104200e210103400240200141046a280200450d002001280200102a0b2001410c6a2101200441746a22040d000b0b200f450d2a200e102a0c2a0b02402005450d00200c102a0b02402010450d002010410c6c2104200e210103400240200141046a280200450d002001280200102a0b2001410c6a2101200441746a22040d000b0b200f450d29200e102a0c290b200441ff0171450d25200241003a00a8090c250b02402006450d0020012003417e6a3602042001200441026a3602000b200041133602000c380b02402006450d0020012003417e6a3602042001200441026a3602000b200041133602000c370b200041133602000c360b200041086a20022902e4073702002000200136020420004103360200200041106a200241e8086a41f800109a051a0c350b20024188066a41206a200241e0076a41206a290300220a37030020024188066a41186a200241e0076a41186a290300221137030020024188066a41106a200241e0076a41106a290300221237030020024188066a41086a200241e0076a41086a2903002213370300200220022903e00722163703880620004109360200200020163702042000410c6a2013370200200041146a20123702002000411c6a2011370200200041246a200a3702002000412c6a200241e8086a41dc00109a051a0c340b20024188066a41206a200241e0076a41206a290300220a37030020024188066a41186a200241e0076a41186a290300221137030020024188066a41106a200241e0076a41106a290300221237030020024188066a41086a200241e0076a41086a2903002213370300200220022903e0072216370388062000410a360200200020163702042000410c6a2013370200200041146a20123702002000411c6a2011370200200041246a200a3702002000412c6a200241e8086a41dc00109a051a0c330b1036000b200420031044000b200420031044000b200441041037000b200420031044000b200320091044000b201041041037000b200441041037000b200420061044000b200b41041037000b200441041037000b202041041037000b200420061044000b200420051044000b200420031044000b200b20071044000b200b20031044000b41880141081037000b41880141081037000b200520031044000b200441041037000b200420061044000b201b41041037000b200441011037000b200441011037000b41880141081037000b41880141081037000b41880141081037000b41880141081037000b200441011037000b200541011037000b02402005450d00200c102a0b02402010450d002010410c6c2104200e210103400240200141046a280200450d002001280200102a0b2001410c6a2101200441746a22040d000b0b200f450d02200e102a0c020b2005450d010b200c102a0b200041133602000c100b200041133602000c0f0b20024188066a41106a221e200241e0076a41106a29030037030020024188066a41086a2220200241e0076a41086a290300370300200220022903e00737038806200041346a200b360200200041306a201b3602002000412c6a2004360200200020053a002b200020063a002a2000200f3a0029200041256a2008360000200041216a200d360000200041206a200e3a0000200041186a200a370200200041106a20113700002000410c6a20093600002000201a3a000b200020193a000a200020103a0009200041086a20223a000020004110360200200041d0006a2012370200200041e9006a2003360000200041ed006a2001360000200041f4006a2007360200200041f8006a201837020020004180016a20133702002000200c3a00732000201f3a00722000201c3a0071200041e8006a201d3a0000200041d8006a2017370200200041e0006a2016370200200041386a200229038806370200200041c0006a2020290300370200200041c8006a201e2903003702000c0e0b2000410f360200200041386a200a370200200041306a2011370200200041286a2012370200200041206a20133702002000411c6a2001360200200041186a2004360200200041146a2003360200200041106a20053602002000410c6a2006360200200041086a2007360200200041c0006a200241e8086a41c800109a051a0c0d0b2000200e3600412000200936003d200020053a0027200020033a0026200020043a0025200020193a00072000201f3a00062000200d3a00052000201c3a00042000410c360200200041346a20113700002000412c6a200a3700002000413c6a20073a0000200041286a2006360000200041216a200b3600002000411d6a200f3600002000411c6a201b3a0000200041146a2012370000200041106a201a3600002000410c6a2010411874200c41ffffff077172360000200041086a2008411874200141ffffff07717236000020004180016a200241a0096a290300370300200041f8006a20024198096a290300370300200041f0006a200241e8086a41286a290300370300200041e8006a20024188096a290300370300200041e0006a200241e8086a41186a290300370300200041d8006a200241e8086a41106a290300370300200041d0006a200241e8086a41086a290300370300200041c8006a20022903e8083703000c0c0b200041133602000c0b0b2000410b360200200041c0006a2011370200200041386a200a370200200041286a2012370200200041206a2013370200200041346a2009360200200041306a20083602002000411c6a2007360200200041186a2006360200200041146a2005360200200041106a20033602002000410c6a2004360200200041086a2001360200200041c8006a20022903e808370300200041d0006a200241e8086a41086a290300370300200041d8006a200241e8086a41106a290300370300200041e0006a200241e8086a41186a290300370300200041e8006a200241e8086a41206a290300370300200041f0006a200241e8086a41286a290300370300200041f8006a200241e8086a41306a29030037030020004180016a200241e8086a41386a2903003703000c0a0b2004102a0b200041133602000c080b4100211f4200210a0c010b4100211f4200210a0b200020093a0029200020103a000b2000200d3a000a200020083a000920004108360200200041186a200a370200200041346a4100360200200041306a20193602002000412c6a200c360200200041256a200b360000200041216a200f360000200041206a200e3a0000200041086a201a3a00002000410c6a201c411874200641ffffff077172360200200041106a201fad422086201bad84370200200041386a20024188066a41d000109a051a0c050b200041133602000c040b200041133602000c030b200020083a002b2000200d3a002a2000200c3a0029200020093a000920004106360200200041386a2013370200200041306a2012370200200041186a2011370200200041106a200a3702002000412c6a200b360200200041216a200f360000200041206a200e3a00002000410c6a2006360200200041086a20103a0000200041256a201b201a41ff017172360000200041c0006a200241e8086a41c800109a051a0c020b1031000b20004100360200200041106a200a3702002000410c6a2005360200200041086a2009360200200041186a200241e8086a41f000109a051a0b200241f0096a24000bf602010b7f230041106b22022400200241086a2001106c0240024002400240024020022802080d0020012802042203417c712204417f4c0d02200228020c210502400240200341027622060d00410421070c010b200410282207450d040b02402005450d0041002108410021094100210403400240024002402001280204220a4104490d00200441016a21032001280200220b280000210c2001200a417c6a3602042001200b41046a36020020042006470d02024020082003200820034b1b220641ffffffff03712006470d002006410274220a41004e0d020b1031000b200041003602002006450d052007102a0c050b0240024020040d00200a102821070c010b20072009200a102c21070b2007450d070b200720096a200c360200200841026a2108200941046a21092003210420052003470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241106a24000f0b1036000b200441041037000b200a41041037000bbf0701107f230041f0006b22032400200341206a2001200228020c22041102000240024020032802200d002000410036020820004201370200200120022802001103002002280204450d012001102a0c010b200341c8006a41106a200341206a41106a290300370300200341c8006a41086a200341206a41086a290300370300200341c8006a41186a200341206a41186a290300370300200341c8006a41206a200341206a41206a280200360200200341086a200341d4006a290200370300200341106a200341dc006a290200370300200341186a200341e4006a290200370300200320032903203703482003200329024c370300200341c8006a2001200228021022051102000240417f2003280248220641016a220720072006491b220641ffffff3f712006470d0020064105742207417f4c0d004101210841012109024002402007450d00200710282209450d010b20092003290300370000200941186a200341186a220a290300370000200941106a200341106a220b290300370000200941086a200341086a220c290300370000200341206a200120041102000240024020032802200d002006210d0c010b200341c8006a41047221074120210e410121080340200341c8006a41206a200341206a41206a280200360200200341c8006a41186a220f200341206a41186a290300370300200341c8006a41106a2210200341206a41106a290300370300200341c8006a41086a2211200341206a41086a29030037030020032003290320370348200c200741086a290000370300200b200741106a290000370300200a200741186a29000037030020032007290000370300200f200a2903003703002010200b2903003703002011200c290300370300200320032903003703480240024020082006460d002006210d0c010b200341206a2001200511020002402006417f2003280220220d41016a22122012200d491b6a220d2006490d0020064101742212200d2012200d4b1b220d41ffffff3f71200d470d00200d41057422124100480d000240024020060d002012102821090c010b200920064105742012102c21090b20090d01201241011037000b1031000b2009200e6a22062003290348370000200641186a200f290300370000200641106a2010290300370000200641086a2011290300370000200341206a20012004110200200e41206a210e200841016a2108200d210620032802200d000b0b2001200228020011030002402002280204450d002001102a0b200020083602082000200d360204200020093602000c020b200741011037000b1036000b200341f0006a24000bad08040c7f017e057f037e23004180016b22022400024002400240200141086a220328020022042001410c6a2802002205460d002001280210220628020021072006280208220841014b210903402003200441206a220a360200200241e0006a41186a200441186a290000370300200241e0006a41106a200441106a290000370300200241e0006a41086a200441086a29000037030020022004290000370360410021040240024020090d0020080e020401040b2008210b0340200b410176220c20046a220d20042007200d4105746a200241e0006a4120109c054101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241e0006a4120109c050d02200a2104200a2005470d000b0b20004100360208200042013702002001280204450d012001280200102a0c010b200241c0006a41086a2204200241e0006a41086a290300370300200241c0006a41106a220b200241e0006a41106a290300370300200241c0006a41186a220c200241e0006a41186a29030037030020022002290360220e3703002002200e370340024041201028220f450d00200f2002290340370000200f41186a200c290300370000200f41106a200b290300370000200f41086a2004290300370000200128020421102001280200211102400240200a2005470d0041012112410121130c010b41012112410121130340200628020821032006280200210702400340200241e0006a41186a2208200a41186a290000370300200241e0006a41106a2209200a41106a290000370300200241e0006a41086a2201200a41086a2900003703002002200a290000370360200a41206a210a4100210402400240200341014b0d0020030e020301030b2003210b0340200b410176220c20046a220d20042007200d4105746a200241e0006a4120109c054101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241e0006a4120109c050d01200a2005470d000c030b0b200241c0006a41086a2001290300220e370300200241c0006a41106a20092903002214370300200241c0006a41186a20082903002215370300200220022903602216370340200241186a220b2015370300200241106a220c2014370300200241086a220d200e37030020022016370300024020132012470d000240201241016a22042012490d00201241017422072004200720044b1b221341ffffff3f712013470d00201341057422044100480d000240024020120d0020041028210f0c010b200f20124105742004102c210f0b200f0d01200441011037000b1031000b200f20124105746a22042002290300370000200441186a200b290300370000200441106a200c290300370000200441086a200d290300370000201241016a2112200a2005470d000b0b02402010450d002011102a0b20002012360208200020133602042000200f3602000c010b412041011037000b20024180016a24000bce0401057f23004180016b2202240002400240024020012802042203200128020022046b41e100490d0003402001200441206a360200200241206a2004108601024020022802602204450d00200241206a21010c030b20012001280200220441206a360200200241206a2004108601024020022802602204450d00200241206a21010c030b20012001280200220441206a360200200241206a2004108601024020022802602204450d00200241206a21010c030b20012001280200220441206a360200200241206a2004108601024020022802602204450d00200241206a21010c030b20012802042203200128020022046b41e0004b0d000b0b024020042003460d0003402001200441206a360200200241206a2004108601024020022802602204450d00200241206a21010c030b200128020022042001280204470d000b0b200041003602400c010b20002001290300370300200041386a200141386a290300370300200041306a200141306a290300370300200041286a200141286a290300370300200041206a200141206a290300370300200041186a200141186a290300370300200041106a200141106a290300370300200041086a200141086a290300370300200241086a2203200141cc006a290200370300200241106a2205200141d4006a290200370300200241186a2206200141dc006a2802003602002002200141c4006a2902003703002000200436024020002002290300370244200041cc006a2003290300370200200041d4006a2005290300370200200041dc006a20062802003602000b20024180016a24000bf00c030c7f017e067f230041a0026b22022400024002400240411010282203450d002003410029008ab740370000200341086a4100290092b7403700002002429080808080023702e401200220033602e0012002200241e0016a3602a0012001200241a0016a10c80120022802e001210320022802e8012101200241f8006a41186a22044200370300200241f8006a41106a22054200370300200241f8006a41086a220642003703002002420037037820032001200241f8006a1000200241d8006a41186a2004290300370300200241d8006a41106a2005290300370300200241d8006a41086a200629030037030020022002290378370358024020022802e401450d0020022802e001102a0b200241003602e001200241d8006a4120200241e0016a1006210420022802e0012205417f460d012004450d012002200536029c01200220043602980141002103200241003a0038024002400340024020052003470d002002410036029c01200341ff0171450d02200241003a00380c020b200241186a20036a200420036a22012d00003a00002002200141016a360298012002200341016a22013a00382001210320014120470d000b200241f8006a41086a2206200241186a41086a2207290300370300200241f8006a41106a2208200241186a41106a2209290300370300200241f8006a41186a220a200241186a41186a220b290300370300200220022903183703782002200520016b36029c01200241186a20024198016a10d40120022802382203450d00200241e0016a41186a220c200a290300370300200241e0016a41106a220a2008290300370300200241e0016a41086a220d2006290300370300200241e0016a41286a22062007290300370300200241e0016a41306a22072009290300370300200241e0016a41386a2208200b290300370300200220022903783703e00120022002290318370380022002413c6a2802002101200241186a41286a2209290300210e200241a0016a41086a200d290300370300200241a0016a41106a200a290300370300200241a0016a41186a200c290300370300200241a0016a41206a220a200229038002370300200241a0016a41286a220b2006290300370300200241a0016a41306a220c2007290300370300200241a0016a41386a220d2008290300370300200220022903e0013703a001200241186a20024198016a106d20022802180d012001450d002003102a0b41c4d1c3004133200241a0016a419cd9c3001038000b200241f8006a41086a220f200241186a41086a2210280200360200200241e0016a41086a2211200241a0016a41086a290300370300200241e0016a41106a2212200241a0016a41106a290300370300200241e0016a41186a2213200241a0016a41186a290300370300200241e0016a41206a2214200a2903003703002006200b2903003703002007200c2903003703002008200d29030037030020022002290318370378200220022903a0013703e00120102011290300370300200241186a41106a2012290300370300200241186a41186a2013290300370300200241186a41206a201429030037030020092006290300370300200241186a41306a2007290300370300200241186a41386a2008290300370300200241086a41086a200f280200360200200220022903e001370318200220022903783703082005450d022004102a0c020b411041011037000b410021030b200241e0016a41086a2204200241186a41086a290300370300200241e0016a41106a2205200241186a41106a290300370300200241e0016a41186a2206200241186a41186a290300370300200241e0016a41206a2207200241186a41206a290300370300200241e0016a41286a2208200241186a41286a290300370300200241e0016a41306a2209200241186a41306a290300370300200241e0016a41386a220a200241186a41386a290300370300200220022903183703e001200241a0016a41086a220b200241086a41086a280200360200200220022903083703a00102402003450d00200020022903e00137030020002001360244200041c8006a200e370200200041386a200a290300370300200041306a2009290300370300200041286a2008290300370300200041206a2007290300370300200041186a2006290300370300200041106a2005290300370300200041086a2004290300370300200041d8006a200b280200360200200041d0006a20022903a0013702000b20002003360240200241a0026a24000bb00705077f037e097f017e017f23004180016b22022400024002400240200141086a220328020022042001410c6a2802002205460d0020012802102106200241f4006a2107034020032004220841206a2204360200200841086a2903002109200841106a290300210a2008290300210b200241e0006a41186a200841186a290300370300200241e0006a41106a200a370300200241e0006a41086a20093703002002200b3703600240200aa720062802004d0d002001280214220c2007460d002007290000200c290000520d030b20052004470d000b0b20004100360208200042083702002001280204450d012001280200102a0c010b200241086a2204200241e0006a41086a290300370300200241106a2203200241e0006a41106a290300370300200241186a2207200241e0006a41186a29030037030020022002290360220a3703202002200a3703000240024002400240024041201028220d450d00200d2002290300370300200d41186a2007290300370300200d41106a2003290300370300200d41086a20042903003703002001280204210e2001280200210f200541606a2008460d03200841206a2110200541606a2111200241f4006a21014101211241012113200d21140340200c2001460d042010210802400340200241e0006a41186a2204200841186a290300370300200241e0006a41106a2203200841106a290300220a370300200241e0006a41086a2207200841086a290300370300200220082903003703600240200aa720062802004d0d002001290000200c290000520d020b2005200841206a2208470d000c070b0b200241206a41086a2007290300220a370300200241206a41106a20032903002209370300200241206a41186a2004290300220b3703002002200229036022153703202004200b370300200320093703002007200a37030020022015370360024020132012470d00201241016a22132012490d04201241017422102013201020134b1b221341ffffff3f712013470d04201341057422104100480d040240024020120d002010102821140c010b201420124105742010102c21140b2014450d030b200841206a2110201420124105746a22162002290360370300201641186a2004290300370300201641106a2003290300370300201641086a2007290300370300201241016a211220112008470d000c050b0b412041081037000b201041081037000b1031000b4101211241012113200d21140b0240200e450d00200f102a0b2000201236020820002013360204200020143602000b20024180016a24000bed0704067f017e0a7f027e230041f0006b22032400200341206a2001200228020c22041102000240024020032802200d002000410036020820004208370200200120022802001103002002280204450d012001102a0c010b200341c8006a41106a200341206a41106a290300370300200341c8006a41086a200341206a41086a290300370300200341c8006a41186a200341206a41186a290300370300200341c8006a41206a200341206a41206a280200360200200341086a200341d4006a290200370300200341106a200341dc006a290200370300200341186a200341e4006a290200370300200320032903203703482003200329024c370300200341c8006a2001200228021022051102000240024002400240417f2003280248220641016a220720072006491b2208ad42287e2209422088a70d002009a72206417f4c0d000240024020060d004108210a4108210b0c010b20061028220a450d02200a210b0b200a2003290300370300200a41186a200341186a220c290300370300200a41106a200341106a220d290300370300200a41086a200341086a290300370300200b4201370320200341206a200120041102000240024020032802200d004101210e0c010b200341c8006a410472210641c800210f4101210e0340200341c8006a41206a200341206a41206a280200360200200341c8006a41186a2210200341206a41186a290300370300200341c8006a41106a2211200341206a41106a290300370300200341c8006a41086a2212200341206a41086a29030037030020032003290320370348200341086a2207200641086a290200370300200d200641106a290200370300200c200641186a290200370300200320062902003703002010200c2903003703002011200d29030037030020122007290300370300200320032903003703480240200e2008470d00200341206a200120051102002008417f2003280220220741016a221320132007491b6a22072008490d06200841017422132007201320074b1b2213ad42287e2209422088a70d062009a722074100480d060240024020080d0020071028210a0c010b200a200841286c2007102c210a0b200a450d05200a210b201321080b200b200f6a221341606a2207200329034837030020122903002109201129030021142010290300211520134201370300200741186a2015370300200741106a2014370300200741086a2009370300200341206a20012004110200200f41286a210f200e41016a210e20032802200d000b0b2001200228020011030002402002280204450d002001102a0b2000200e360208200020083602042000200b3602000c040b1036000b200641081037000b200741081037000b1031000b200341f0006a24000b02000bef0101057f230041c0006b220524000240024020030d00200041003602000c010b2003280208210620032802002103200541206a41186a22074200370300200541206a41106a22084200370300200541206a41086a220942003703002005420037032020044120200541206a1000200541186a2007290300370300200541106a2008290300370300200541086a200929030037030020052005290320370300200541003602202003200620054120200541206a10012104024020052802202203417f460d002000200336020420002004360200200041086a20033602000c010b200041003602000b200541c0006a24000baf0201027f23004190016b2203240020032002108c010240024020032d000022024102470d00200041003a00000c010b200341e0006a200341286a290300370300200341e8006a200341306a290300370300200341d8006a41186a200341386a290300370300200341d8006a41206a200341c0006a290300370300200341d8006a41286a200341c8006a290300370300200341d8006a41306a200341d0006a2802003602002003200341206a29030037035802402002450d00200041003a00000c010b2003411c6a2802002102200341186a28020021042000200329026c370001200041013a0000200041196a20034184016a290200370000200041116a200341fc006a290200370000200041096a200341d8006a411c6a2902003700002002450d002004102a0b20034190016a24000bd60201057f230041d0016b220224000240411710282203450d00200341002900f1d8433700002003410f6a4100290080d943370000200341086a41002900f9d84337000020024297808080f00237027c200220033602782001200241f8006a108f01200228028001210320022802782101200241186a22044200370300200241106a22054200370300200241086a22064200370300200242003703002001200320021000200241d8006a41186a2004290300370300200241d8006a41106a2005290300370300200241d8006a41086a2006290300370300200220022903003703580240200228027c450d002002280278102a0b2002200241d8006a10960220022d00002103200241f8006a200241017241d700109a051a0240024020034102470d00200041023a00000c010b200020033a0000200041016a200241f8006a41d700109a051a0b200241d0016a24000f0b411741011037000b870102017f037e230041e0006b22032400200341086a2002108c010240024020032d000822024102470d00420021040c010b2002410173ad2104200341186a2903002105200341106a290300210620020d00200341246a280200450d00200341206a280200102a0b2000200637030820002004370300200041106a2005370300200341e0006a24000b940201057f230041d0006b220224000240411710282203450d00200341002900f1d8433700002003410f6a4100290080d943370000200341086a41002900f9d84337000020024297808080f002370224200220033602202001200241206a108f012002280228210320022802202101200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020012003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b2002412041014100410010032103200241d0006a24002003417f470f0b411741011037000b952801057f02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2202280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00003a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00013a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00023a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00033a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00043a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00053a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00063a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00073a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00083a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00093a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000e3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1020012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000f3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00103a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00113a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00123a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00133a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00143a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00153a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00163a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00173a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00183a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00193a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001e3a000002400240200228020020032802002202460d00200128020021040c010b200241016a22042002490d21200241017422052004200520044b1b22054100480d210240024020020d002005102821040c010b200128020020022005102c21040b2004450d2020012004360200200141046a2005360200200141086a28020021020b2003200241016a360200200420026a20002d001f3a00000f0b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200541011037000b1031000b3802017f017e230041106b2203240020032002109101200329030021042000200341086a29030037030820002004370300200341106a24000bf40202057f027e230041d0006b2202240002400240411410282203450d00200341002900cfe140370000200341106a41002800dfe140360000200341086a41002900d7e14037000020024294808080c002370224200220033602202001200241206a108f012002280228210320022802202101200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020012003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b2002410036023020024120200241306a100621030240024020022802302201417f470d0042002107420021080c010b20014110490d02200341086a2900002108200329000021072003102a0b2000200737030020002008370308200241d0006a24000f0b411441011037000b41c4d1c3004133200241306a419cd9c3001038000bbc200b067f017e0d7f067e047f037e017f027e0d7f027e067f230041c0046b22022400200241186a42003703002002420037031020024200370308200128020821032001280200210402400240200128020422050d00200421010c010b2005210620042101034020012802880b21012006417f6a22060d000b0340200420042f01064102746a41880b6a28020021042005417f6a22050d000b0b200241106a21072002413c6a20042f0106360200200241206a41186a4100360200200241346a2004360200200220033602402002410036023020024200370328200220013602242002410036022020024188016a200241206a109301024002400240024020022903a80122084202510d00200241bc016a210920024188016a412c6a210a20024188016a410472210b200241e5016a210c20024188016a41086a2103200241e8026a412c6a210d200241e8026a41106a210e200241b8016a210f200241d0016a21100340200241e8006a41186a220620024188016a41186a2201290300370300200241e8006a41106a221120024188016a41106a2204290300370300200241e8006a41086a22122003290300370300200241c8006a41086a2213200c41086a290000370300200241c8006a41106a2214200c41106a290000370300200241c8006a41186a2215200c41186a29000037030020022002290388013703682002200c290000370348200f29030021162010290300211720022903b001211820022903c801211920022903c001211a20022903d801211b20022802e001211c20022d00e401211d20022d008502210520024188026a41186a200629030037030020024188026a41106a201129030037030020024188026a41086a20122903003703002002200229036837038802200241a8026a41186a22122015290300370300200241a8026a41106a221e2014290300370300200241a8026a41086a221f2013290300370300200220022903483703a8020240024002402005ad42ff0183200820085022061b4201520d0020024188016a20024188026a4200201820061b4200201620061b10940120042903002120200229039001211820022d00a00121062002290388012121200241086a41106a221129030021082002290310211602400240024002400240024020022903084201510d0020214200510d022016201856200820205620082020511b0d04202020087d2018201654ad7d2121201820167d21220c010b20214200510d02427f200820207c201620187c22182016542213ad7c22162013201620085420162008511b22131b2121427f201820131b21220b420121080c030b427f200820207c201620187c22182016542213ad7c22162013201620085420162008511b22131b2121427f201820131b2122420021080c020b202020087d2018201654ad7d200820207d2016201854ad7d20182016562020200856202020085122131b22141b2121201820167d201620187d20141b21222018201658202020085820131bad21080c010b200820207d2016201854ad7d2121201620187d2122420021080b201120213703002002202237031020022008370308200641ff01710d010b024002400240201d41ff0171222341014622060d00200541ff01710d00201c201aa772450d010b20024188016a20024188026a108c010240024020022d0088012211417f6a221341014b0d00024020130e020002000b20110d0420022802a401450d0420022802a001102a0c040b200241c8026a41086a200941086a290200370300200241c8026a41106a200941106a290200370300200241c8026a41186a200941186a290200370300200220092902003703c80220042903002124200229039001212520022802dc01212620022802b801212720022802b401212820022802b001212920022802ac01212a20022802a801212b20022802a401212c20022802a001212d0c020b4102212820110d0120022802a401450d0120022802a001102a0c010b201ba7210402400240201b422088a722050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b2002201c3602a801200241003602a001200241003602980120024200370390012002200136028c0120024100360288012002200436029c01200220042f01063602a40120024188016a1095010c020b4102212e02400240024002400240024002400240024020284102460d00202b417f4c0d0102400240202b0d004100212f410121300c010b202b212f202b10282230450d030b2030202d202b109a051a2001200241c8026a41186a2903003703002004200241c8026a41106a2903003703002003200241c8026a41086a290300370300200220022903c802370388012028410146212e202b2131202a2132202521332024213420292135202721360b200241b8036a41186a22372001290300370300200241b8036a41106a22382004290300370300200241b8036a41086a22392003290300370300200241a0046a41086a221d201f290300370300200241a0046a41106a2214201e290300370300200241a0046a41186a2215201229030037030020022002290388013703b803200220022903a8023703a004200541ff0171450d030c020b1036000b202b41011037000b202e4102460d0120302031100420060d0320024188026a109601202f450d022030102a0c020b202e4102460d00200d20022903b803370200200d41086a2039290300370200200d41106a2038290300370200200d41186a2037290300370200200220333703e80220022036360290032002202e36028c032002203536028803200220323602840320022031360280032002202f3602fc02200220303602f802200220343703f0022035213a2033212020342121203221110c030b2006450d004108211120024188016a20024188026a109701109801213a200e41086a20024188016a41086a280200360200200e200229038801370200200d20022903a004370100200d41086a200241a0046a41086a290300370100200d41106a2014290300370100200d41186a2015290300370100427f21202002427f3703f0022002427f3703e80220024108360284034100212e2002410036028c032002203a36028803427f21210c020b20284102460d020240202c0d004100212c0c030b202d102a0c020b4108211120024188016a20024188026a109701109801213a200e41086a20024188016a41086a280200360200200e200229038801370200200d20022903a004370100200d41086a200241a0046a41086a290300370100200d41106a2014290300370100200d41186a2015290300370100427f21202002427f3703f0022002427f3703e80220024108360284034100212e2002410036028c032002203a360288030240202f450d002030102a427f21200b427f21210b0240201a4201520d00200220193703e802200220173703f00220192120201721210b02402023450d00200d20022903a802370000200d41186a2012290300370000200d41106a201e290300370000200d41086a201f2903003700000b0240201c450d0010980121054101212e2002410136028c0320022005360290030b201ba7210502400240201b422088a722120d00200521060c010b2012211320052106034020062802ec0321062013417f6a22130d000b0340200520052f01064102746a41ec036a28020021052012417f6a22120d000b0b20052f010621122002201c3602d803200220123602d403200241003602d003200220053602cc03200241003602c803200242003703c003200220063602bc03200241003602b80320024188016a200241b8036a10990102402002280288014101470d00200228028003211320022802f802211c0340200241e0036a41186a200b41186a2902002208370300200241e0036a41106a200b41106a290200221b370300200241e0036a41086a200b41086a29020022163703002002200b29020022183703e00320022802ac01210520022802b001211e20022802b401210620024180046a41186a200837030020024180046a41106a201b37030020024180046a41086a20163703002002201837038004200142003703002004420037030020034200370300200242003703880120024180046a412020024188016a10002015200129030037030020142004290300370300201d200329030037030020022002290388013703a0042002410036028801201c2013200241a0046a412020024188016a1001211f02402002280288012212417f460d00201120126b21112012450d00201f102a0b0240024020050d00200142003703002004420037030020034200370300200242003703880120024180046a412020024188016a10002015200129030037030020142004290300370300201d200329030037030020022002290388013703a004201c2013200241a0046a412010020c010b200142003703002004420037030020034200370300200242003703880120024180046a412020024188016a10002015200129030037030020142004290300370300201d200329030037030020022002290388013703a004201c2013200241a0046a4120200520061005201120066a2111201e450d002005102a0b20024188016a200241b8036a1099012002280288014101460d000b20022011360284030b200241b8036a1095012037200241c8026a41186a2903003703002038200241c8026a41106a2903003703002039200241c8026a41086a290300370300200220022903c8023703b8030240024020284102460d00200a20022903b803370200200a41086a2039290300370200200a41106a2038290300370200200a41186a20372903003702002002202537038801200220273602b001200220283602ac01200220293602a8012002202a3602a4012002202c36029c012002202d36029801200220263602d40120022024370390012002202b3602a001410121040240202b200228028003470d0002400240202d20022802f8022201460d00202d2001202b109c050d02202a2011470d020c010b202a2011470d010b200a200d4120109c050d0020252020852024202185844200520d002029203a470d0002402028202e470d004100210420284101470d012027200228029003460d010b410121040b0240202c450d00202d102a0b20044102460d002004450d010b2003200241e8026a41d000109a051a200241003a00880120024188026a20024188016a109a010c020b20022802fc02450d0120022802f802102a0c010b201ba7210402400240201b422088a722050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b2002201c3602a801200241003602a001200241003602980120024200370390012002200136028c0120024100360288012002200436029c01200220042f01063602a40120024188016a1095010b20024188016a200241206a10930120022903a80122084202520d000b20022903082108200241206a109b012008500d010c020b200241206a109b010b02402002290310200241186a29030084500d0041f4b5c0001032000b20022903084200520d00200220073602880120024188016a109c010c010b200220073602880120024188016a109d010b200241c0046a24000bf90503087f017e017f23004180026b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2203200128020422052f01064f0d01200241186a2206200520034105746a220741206a290000370300200241106a2208200741186a290000370300200241086a2209200741106a2900003703002002200741086a290000370300200241206a2005200341e0006c6a41e8026a41e000109a051a2001200341016a36020c200120043602082001200536020420024180016a41186a200629030037030020024180016a41106a200829030037030020024180016a41086a2009290300370300200220022903003703800120024180016a41206a200241206a41e000109a051a200020024180016a418001109a051a0c020b200042023703200c010b2001280200210702400240200528020022030d002004ad210a410021030c010b200741016a210720053301044220862004ad84210a0b2005102a200aa7210402400240200a422088a7220620032f01064f0d00200321050c010b034002400240200328020022050d002004ad210a410021050c010b200741016a210720033301044220862004ad84210a0b2003102a200aa7210420052103200a422088a7220620052f01064f0d000b0b200241186a2208200520064105746a220341206a290000370300200241106a2209200341186a290000370300200241086a220b200341106a2900003703002002200341086a290000370300200241206a2005200641e0006c6a41e8026a41e000109a051a200641027420056a418c0b6a280200210302402007417f6a2205450d00034020032802880b21032005417f6a22050d000b0b2001410036020c20012004360208200120033602042001410036020020024180016a41186a200829030037030020024180016a41106a200929030037030020024180016a41086a200b290300370300200220022903003703800120024180016a41206a200241206a41e000109a051a200020024180016a418001109a051a0b20024180026a24000ba90703067f027e017f230041a0016b220424000240024002400240411410282205450d00200541002900cfe140370000200541106a41002800dfe140360000200541086a41002900d7e14037000020044294808080c002370224200420053602202001200441206a108f012004280228210520042802202106200441306a41186a22074200370300200441306a41106a22084200370300200441306a41086a220942003703002004420037033020062005200441306a1000200441186a2007290300370300200441106a2008290300370300200441086a20092903003703002004200429033037030002402004280224450d002004280220102a0b2004410036023020044120200441306a100621050240024020042802302206417f470d004200210a4200210b0c010b20064110490d02200541086a290000210b2005290000210a2005102a0b0240200242ffffe883b1de1656200342005220035022051b0d00200a200b844200520d0020004200370300200041013a0018200041106a4200370300200041086a42003703000c040b4101210602402002428080e983b1de1654410020051b0d00411410282205450d0341002106200541002900cfe140370000200541106a41002800dfe140360000200541086a41002900d7e14037000020044294808080c002370224200420053602202001200441206a108f012004280228210520042802202107200441306a41186a22084200370300200441306a41106a22094200370300200441306a41086a220c42003703002004420037033020072005200441306a1000200441186a2008290300370300200441106a2009290300370300200441086a200c2903003703002004200429033037030002402004280224450d002004280220102a0b200441204101410041001003417f470d002001109302200441e8006a2003370300200441e0006a200237030041002106200441306a41086a41003a0000200441396a2001290000370000200441c1006a200141086a290000370000200441c9006a200141106a290000370000200441d1006a200141186a290000370000200441023a003041014100200441306a10cc010b200120022003108f02200041106a200b20037d200a200254ad7d2003200b7d2002200a54ad7d200a200256200b200356200b2003511b22051b3703002000200a20027d2002200a7d20051b370308200020063a001820002005ad3703000c030b411441011037000b41c4d1c3004133200441306a419cd9c3001038000b411441011037000b200441a0016a24000bb00101037f230041306b2201240020012000109901024020012802004101470d000340024020012802242202450d002001280228450d002002102a0b2001200010990120012802004101460d000b0b02402000280204220241f8b9c000460d00200228020021032002102a2003450d00200328020021002003102a2000450d00024020002802002202450d0003402000102a2002210020022802002203210220030d000b0b2000102a0b200141306a24000b870201057f230041d0006b220124000240411710282202450d00200241002900f1d8433700002002410f6a4100290080d943370000200241086a41002900f9d84337000020014297808080f002370224200120023602202000200141206a108f012001280228210220012802202100200141306a41186a22034200370300200141306a41106a22044200370300200141306a41086a220542003703002001420037033020002002200141306a1000200141186a2003290300370300200141106a2004290300370300200141086a20052903003703002001200129033037030002402001280224450d002001280220102a0b200141201009200141d0006a24000f0b411741011037000ba60603037f017e017f230041c0006b22022400200241206a41086a220342003703002002420037032041d8fec5004117200241206a1008200241086a2003290300370300200220022903203703002002410036022020024110200241206a1006210302400240024002400240024020022802202204417f470d00420121050c010b024020030d00420121050c010b20044108490d01200329000021052003102a200542017c21050b200241206a41086a220342003703002002420037032041d8fec5004117200241206a1008200241086a2003290300370300200220022903203703002002200537032020024110200241206a41081007412010282203450d0120032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003412041c000102c2201450d0220012005370020200241206a41186a22034200370300200241206a41106a22044200370300200241206a41086a220642003703002002420037032020014128200241206a1000200241186a2003290300370300200241106a2004290300370300200241086a200629030037030020022002290320370300413710282203450d03200342bac6a1cbc68dd9aff300370000200342f4dec98bf6ac999de400370008200341e5cc85ab073600102003413a3a0016200341ece8013b001420032002290300370017200320022f01083b001f2003200228010a360021200320022f010e3b0025200320022d00103a0027200320022d00113a0028200320022d00123a0029200320022d00133a002a200320022d00143a002b200320022d00153a002c200320022d00163a002d200320022d00173a002e200320022d00183a002f200320022d00193a0030200320022d001a3a0031200320022d001b3a0032200320022d001c3a0033200320022d001d3a0034200320022d001e3a0035200320022d001f3a0036200041ed93c40041c593c4006b410f6a36020820004137360204200020033602002001102a200241c0006a24000f0b41c4d1c3004133200241206a419cd9c3001038000b412041011037000b41c00041011037000b413741011037000ba70101047f230041206b22002400200041106a41086a220142003703002000420037031041d9efc200410d200041106a1008200041086a200129030037030020002000290310370300410021022000410036021020004110200041106a100621010240024020002802102203417f460d002001450d0020034104490d01200128000021022001102a0b200041206a240020020f0b41c4d1c3004133200041106a419cd9c3001038000bdd0605057f047e017f017e047f23004190016b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2203200128020422052f01064f0d01200241e0006a41186a200520034105746a220641206a2900002207370300200241e0006a41106a200641186a2900002208370300200241e0006a41086a200641106a29000022093703002002200641086a290000220a370360200241306a41086a20052003410c6c6a220641f0026a280200220b360200200641e8026a290200210c2001200341016a36020c20012004360208200120053602042002200c3703302000200a3702042000410c6a2009370200200041146a20083702002000411c6a2007370200200041246a200c3702002000412c6a200b360200200041013602000c020b200041003602000c010b2001280200210602400240200528020022030d002004ad210c410021030c010b200641016a210620053301044220862004ad84210c0b2005102a200ca7210402400240200c422088a7220b20032f01064f0d00200321050c010b034002400240200328020022050d002004ad210c410021050c010b200641016a210620033301044220862004ad84210c0b2003102a200ca7210420052103200c422088a7220b20052f01064f0d000b0b200241306a41186a220d2005200b4105746a220341206a290000370300200241306a41106a220e200341186a290000370300200241306a41086a220f200341106a2900003703002002200341086a290000370330200241d0006a41086a22102005200b410c6c6a220341f0026a2802003602002002200341e8026a290200370350200b41027420056a41f0036a280200210302402006417f6a2205450d00034020032802ec0321032005417f6a22050d000b0b2001410036020c200120043602082001200336020420014100360200200241e0006a41186a200d290300220c370300200241e0006a41106a200e2903002207370300200241e0006a41086a200f290300220837030020024188016a201028020022033602002000200229033022093702042000410c6a2008370200200041146a20073702002000411c6a200c370200200041246a2002290350220c3702002000412c6a2003360200200220093703602002200c37038001200041013602000b20024190016a24000ba70201057f230041d0006b220224000240411710282203450d00200341002900f1d8433700002003410f6a4100290080d943370000200341086a41002900f9d84337000020024297808080f002370224200220033602202000200241206a108f012002280228210320022802202100200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020002003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b2002200110e203024020012d00000d002001411c6a280200450d00200141186a280200102a0b200241d0006a24000f0b411741011037000bca0201067f230041b0016b22012400200141086a2000109301024020012903284202510d000340200128026021022001280258210302400240200128025c22040d00200321050c010b2004210620032105034020052802ec0321052006417f6a22060d000b0340200320032f01064102746a41ec036a28020021032004417f6a22040d000b0b200120023602a801200141003602a001200141003602980120014200370390012001200536028c0120014100360288012001200336029c01200120032f01063602a40120014188016a109501200141086a200010930120012903284202520d000b0b02402000280204220341f8b9c000460d00200328020021042003102a2004450d00200428020021052004102a2005450d00024020052802002203450d0003402005102a2003210520032802002204210320040d000b0b2005102a0b200141b0016a24000bcf0204017f017e027f037e230041206b2201240042002102200141106a41086a220342003703002001420037031041ace1c0004116200141106a1008200141086a2003290300370300200120012903103703002001410036021020014110200141106a1006210302400240024020012802102204417f470d00420021050c010b20044110490d01200341086a2900002105200329000021022003102a0b2000280200220341086a290300210620032903002107200141106a41086a220342003703002001420037031041ace1c0004116200141106a1008200141086a2003290300370300200120012903103703002001427f200520067c200220077c22062002542203ad7c22022003200220055420022005511b22031b3703182001427f200620031b37031020014110200141106a41101007200141206a24000f0b41c4d1c3004133200141106a419cd9c3001038000bd00204017f017e027f037e230041206b2201240042002102200141106a41086a220342003703002001420037031041ace1c0004116200141106a1008200141086a2003290300370300200120012903103703002001410036021020014110200141106a1006210302400240024020012802102204417f470d00420021050c010b20044110490d01200341086a2900002105200329000021022003102a0b2000280200220341086a290300210620032903002107200141106a41086a220342003703002001420037031041ace1c0004116200141106a1008200141086a20032903003703002001200129031037030020014200200520067d2002200754ad7d2206200220077d2207200256200620055620062005511b22031b37031820014200200720031b37031020014110200141106a41101007200141206a24000f0b41c4d1c3004133200141106a419cd9c3001038000bb50404057f017e017f017e0240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a3602000240200441037122064103460d00024002400240024020060e03000102000b2004410276ad21070c020b41012106024020050d000c050b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d04200141fcff0371410276ad21070c010b410121060240200541034f0d000c040b200341036a2d0000210520032f0001210820012002417c6a3602042001200341046a3602002008200541107472410874200472220141808004490d032001410276ad21070b410021060c020b02402004410276220841044b0d000240024020080e050002020201000b20054104490d022003350001210720012002417b6a3602042001200341056a36020020074280808080045421060c030b20054108490d01200329000121072001200241776a3602042001200341096a3602002007428080808080808080015421060c020b200841046a220541084b0d002002417e6a2102200341026a2103410021044200210741012106034002402002417f470d000c030b2003417f6a310000210920012002360204200120033602002002417f6a2102200341016a210320092004410374413871ad862007842107200441016a220441ff01712005490d000b2007427f412820084103746b413871ad885821060c010b410121060b2000200737030820002006ad3703000bde0506067f017e017f017e017f017e230041206b220224000240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200024002400240200541037122074103460d0002400240024020070e03000102000b2005410276ad21080c040b410121072006450d0220042d0001210620012003417e6a3602042001200441026a3602002006410874200572220141ffff0371418002490d02200141fcff0371410276ad21080c030b4101210720064103490d01200441036a2d0000210620042f0001210920012003417c6a3602042001200441046a3602002009200641107472410874200572220141808004490d012001410276ad21080c020b024020054102762209410c4b0d0002400240024020090e0d00030303010303030303030302000b20064104490d052004350001210820012003417b6a3602042001200441056a36020020084280808080045421074200210a0c060b20064108490d04200429000121082001200341776a3602042001200441096a3602002008428080808080808080015421074200210a0c050b20064110490d03200441096a290000210a2004290001210820012003416f6a3602042001200441116a360200200a428080808080808080015421070c040b200941046a220641104b0d022003417e6a2103200441026a21044100210541012107200241186a210b420021084200210a03402003417f460d01200241106a2004417f6a3100004200200541037441f80071109d0520012003360204200120043602002003417f6a2103200441016a2104200b290300200a84210a20022903102008842108200541016a220541ff01712006490d000b2002427f427f41e80020094103746b41f80071109e052008200229030058200a200241086a290300220c58200a200c511b21070c030b0c020b4200210a410021070c010b410121070b20002008370308200041106a200a37030020002007ad370300200241206a24000b9e0701037f02400240024002400240024020002802002202413f4b0d0002400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d06200041017422042003200420034b1b22044100480d060240024020000d002004102821030c010b200128020020002004102c21030b2003450d0220012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a20024102743a00000f0b200241808001490d032002418080808004490d020c010b200441011037000b0240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d05200241017422042003200420034b1b22044100480d050240024020020d002004102821030c010b200128020020022004102c21030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a00002000280200210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d05200241017422002004200020044b1b22004100480d050240024020020d002000102821020c010b200128020020022000102c21020b2002450d0220012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b200441011037000b200041011037000b024002400240200141046a2802002203200141086a28020022006b4104490d00200128020021030c010b200041046a22042000490d03200341017422002004200020044b1b22004100480d030240024020030d002000102821030c010b200128020020032000102c21030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20024102744102723600000f0b200041011037000b024002400240200141046a2802002203200141086a28020022006b4102490d00200128020021030c010b200041026a22042000490d02200341017422002004200020044b1b22004100480d020240024020030d002000102821030c010b200128020020032000102c21030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a20024102744101723b00000f0b200041011037000b1031000bac0903017f017e057f230041e0006b220224000240024002400240024002400240024002400240024020002903002203423f560d0002400240200141046a280200200141086a2802002200460d00200128020021040c010b200041016a22042000490d0b200041017422052004200520044b1b22054100480d0b0240024020000d002005102821040c010b200128020020002005102c21040b2004450d0220012004360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200420006a2003a74102743a00000c080b200342808001540d062003428080808004540d054108200379a741037622056b4104490d0402400240200141046a280200200141086a2802002204460d00200128020021060c010b200441016a22072004490d0a200441017422062007200620074b1b22074100480d0a0240024020040d002007102821060c010b200128020020042007102c21060b2006450d0220012006360200200141046a2007360200200141086a28020021040b200141086a2207200441016a360200200620046a411320054102746b3a0000200220002903002203370308200541786a2104200141046a2106034002400240200628020020072802002200460d00200128020021050c010b200041016a22052000490d0b200041017422082005200820054b1b22084100480d0b0240024020000d002008102821050c010b200128020020002008102c21050b2005450d042001200536020020062008360200200728020021000b2007200041016a360200200520006a2003a73a000020034208882103200441016a22002004492105200021042005450d000b20022003370308200350450d030c070b200541011037000b200741011037000b200841011037000b200241286a41146a4108360200200241346a4109360200200241106a41146a41033602002002200241086a360240200241f8b9c00036024420024203370214200241c8afc6003602102002410936022c200242043703582002420137024c20024180bac0003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a4188bac000103e000b41dcb9c0001032000b024002400240200141046a2802002204200141086a28020022006b4104490d00200128020021040c010b200041046a22052000490d05200441017422002005200020054b1b22004100480d050240024020040d002000102821040c010b200128020020042000102c21040b2004450d0120012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a2003a74102744102723600000c020b200041011037000b02400240200141046a2802002204200141086a28020022006b4102490d00200128020021040c010b200041026a22052000490d03200441017422002005200020054b1b22004100480d030240024020040d002000102821040c010b200128020020042000102c21040b2004450d0220012004360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200420006a2003a74102744101723b00000b200241e0006a24000f0b200041011037000b1031000bbf0202027f017e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d01200441012001103f21000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000b20024180016a240020000f0b20034180011044000b20034180011044000b800a03017f027e057f230041e0006b2202240002400240024002400240024002400240024002400240200028020022002903002203423f56200041086a290300220442005220045022051b0d0002400240200141046a280200200141086a2802002200460d00200128020021050c010b200041016a22052000490d0b200041017422062005200620054b1b22064100480d0b0240024020000d002006102821050c010b200128020020002006102c21050b2005450d0220012005360200200141046a2006360200200141086a28020021000b200141086a200041016a360200200520006a2003a74102743a00000c080b20034280800154410020051b0d06200342808080800454410020051b0d05411020047920037942c0007c20044200521ba741037622066b4104490d0402400240200141046a280200200141086a2802002205460d00200128020021070c010b200541016a22082005490d0a200541017422072008200720084b1b22084100480d0a0240024020050d002008102821070c010b200128020020052008102c21070b2007450d0220012007360200200141046a2008360200200141086a28020021050b200141086a2208200541016a360200200720056a413320064102746b3a0000200029030021032002200041086a290300220437030820022003370300200641706a2105200141046a2107034002400240200728020020082802002200460d00200128020021060c010b200041016a22062000490d0b200041017422092006200920064b1b22094100480d0b0240024020000d002009102821060c010b200128020020002009102c21060b2006450d042001200636020020072009360200200828020021000b2008200041016a360200200620006a2003a73a00002003420888200442388684210320044208882104200541016a22002005492106200021052006450d000b2002200337030020022004370308200320048450450d030c070b200641011037000b200841011037000b200941011037000b200241286a41146a4108360200200241346a410a360200200241106a41146a410336020020022002360240200241a8bbc00036024420024203370214200241c8afc6003602102002410a36022c200242043703582002420137024c20024180bac0003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a41b8bbc000103e000b418cbbc0001032000b024002400240200141046a2802002205200141086a28020022006b4104490d00200128020021050c010b200041046a22062000490d05200541017422002006200020064b1b22004100480d050240024020050d002000102821050c010b200128020020052000102c21050b2005450d0120012005360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200520006a2003a74102744102723600000c020b200041011037000b02400240200141046a2802002205200141086a28020022006b4102490d00200128020021050c010b200041026a22062000490d03200541017422002006200020064b1b22004100480d030240024020050d002000102821050c010b200128020020052000102c21050b2005450d0220012005360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200520006a2003a74102744101723b00000b200241e0006a24000f0b200041011037000b1031000b810605027f027e017f027e027f230041a0016b220224002000280200210002400240024002400240024002400240200128020022034110710d00200041086a29030021042000290300210520034120710d0220054290ce005441002004501b450d012005a72103412721000c060b200041086a2903002105200029030021044180012100024003402000450d01200241206a20006a417f6a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a210020044204882005423c8684220420054204882205844200520d000b0b20004181014f0d0220014101419087c0004102200241206a20006a41800120006b104221000c060b41272100200241186a21060340200241106a200520044290ce00420010a0052002200229031022072006290300220842f0b17f427f109f05200241206a20006a2203417c6a200520022903007ca7220941ffff037141e4006e220a41017441ba84c0006a2f00003b00002003417e6a200a419c7f6c20096a41ffff037141017441ba84c0006a2f00003b0000200542ffc1d72f56210320044200522109200450210a2000417c6a2100200721052008210420032009200a1b0d000c040b0b4180012100024003402000450d01200241206a20006a417f6a2005a7410f712203413072200341376a2003410a491b3a00002000417f6a210020054204882004423c8684220520044204882204844200520d000b0b20004181014f0d0120014101419087c0004102200241206a20006a41800120006b104221000c040b20004180011044000b20004180011044000b2007a721030b02400240200341e3004a0d00200321090c010b200241206a2000417e6a22006a2003200341ffff037141e4006e2209419c7f6c6a41ffff037141017441ba84c0006a2f00003b00000b024002402009410a480d00200241206a2000417e6a22006a200941017441ba84c0006a2f00003b00000c010b200241206a2000417f6a22006a200941306a3a00000b2001410141b8aec6004100200241206a20006a412720006b104221000b200241a0016a240020000bf40601067f230041f0006b21020240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a2206360204410121072001200441016a360200200541f001490d0a200541847e6a220541034b0d0420050e0401020803010b200041023a00000f0b20064102490d0320042f0001210520012003417d6a3602042001200441036a360200200541ef014b0d04200041023a00000f0b20064104490d042004280001210520012003417b6a3602042001200441056a36020041012107200541ffff034b0d07200041023a00000f0b41002105200241003a00682003417f6a21062003417e6a210302400340024020062005470d000240200541ff0171450d00200241003a00680b410121010c020b200241c8006a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00682003417f6a21032007210520074120470d000b200241c6006a20022d004a3a0000200241306a200241d7006a290000370300200241386a200241df006a290000370300200241c0006a200241e7006a2d00003a0000200220022f01483b01442002200229004f370328200228004b2105410021010b200241246a41026a2203200241c4006a41026a2d00003a0000200241086a41086a2207200241286a41086a290300370300200241086a41106a2204200241286a41106a290300370300200241086a41186a2206200241286a41186a2d00003a0000200220022f01443b0124200220022903283703082001450d05200041023a00000f0b200041023a00000f0b200041023a00000f0b410121070c030b200041023a00000f0b0240200641044f0d00200041023a00000f0b200041023a000020012003417b6a3602042001200441056a3602000f0b200241286a41026a20032d00003a0000200241c8006a41086a2007290300370300200241c8006a41106a2004290300370300200241c8006a41186a20062d00003a0000200220022f01243b012820022002290308370348410021070b200020073a0000200020022f01283b0001200041046a2005360200200041086a2002290348370200200041036a2002412a6a2d00003a0000200041106a200241c8006a41086a290300370200200041186a200241c8006a41106a290300370200200041206a200241c8006a41186a2802003602000bb30801037f0240024002400240024002400240024020002d00004101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d08200241017422042003200420034b1b22044100480d080240024020020d002004102821030c010b200128020020022004102c21030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41ff013a0000200041016a2001108f010f0b0240024002400240200041046a280200220241ffff034b0d00200241ef014b0d03200141046a280200200141086a2802002200460d01200128020021030c020b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0a200041017422042003200420034b1b22044100480d0a0240024020000d002004102821030c010b200128020020002004102c21030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41fd013a000002400240200141046a2802002203200428020022006b4104490d00200128020021030c010b200041046a22042000490d0a200341017422002004200020044b1b22004100480d0a0240024020030d002000102821030c010b200128020020032000102c21030b2003450d0620012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20023600000f0b200041016a22032000490d08200041017422042003200420034b1b22044100480d080240024020000d002004102821030c010b200128020020002004102c21030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a20023a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d07200041017422042003200420034b1b22044100480d070240024020000d002004102821030c010b200128020020002004102c21030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41fc013a000002400240200141046a2802002203200428020022006b4102490d00200128020021030c010b200041026a22042000490d07200341017422002004200020044b1b22004100480d070240024020030d002000102821030c010b200128020020032000102c21030b2003450d0620012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a20023b00000f0b200441011037000b200441011037000b200041011037000b200441011037000b200441011037000b200041011037000b1031000bd80402097f017e230041106b22052400024002400240200128020041016a220641004c0d0020012006360200200141046a2106200141086a28020021070240024003402006280200220841086a210920082f0106220a41057421064100210b0240024003402006450d01200220094120109c05220c450d02200641606a2106200b41016a210b200941206a2109200c417f4a0d000b200b417f6a210a0b2007450d022007417f6a21072008200a4102746a41880b6a21060c010b0b2008200b41e0006c6a22094198036a2106200941e8026a210d2009419c036a2802002107024003402006280200220841086a210920082f0106220a41057421064100210b0240024003402006450d01200420094120109c05220c450d02200641606a2106200b41016a210b200941206a2109200c417f4a0d000b200b417f6a210a0b024020070d004100210c0c030b2007417f6a21072008200a4102746a41ec036a21060c010b0b4101210c0240200841e8026a200b410c6c6a2206280200220b0d00410021060c010b20062802082209417f4c0d040240024020090d0020054200370300410121060c010b200910282206450d0620054100360204200520093602000b200520093602042006200b2009109a051a2005290300210e0b02400240200d2d005d450d0020064100200c1b21060c010b200c450d010b2000200e370204200020063602000c010b20002001280210200220032004200141146a28020028020c1104000b20012001280200417f6a360200200541106a24000f0b41b8b8c0004118200541086a41e0b8c0001038000b1036000b200941011037000bfc0202097f037e230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a28020021060240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d01200220084120109c05220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a22054190036a290300210c20054188036a290300210d20054180036a290300210e0240200541c5036a2d00000d00200ea721054201210e2005450d010c020b200e4202520d010b200320012802102002200141146a280200280214110500200341106a290300210c200128020021042003290308210d2003290300210e0b20012004417f6a360200200041106a200c3703002000200d3703082000200e370300200341206a24000f0b41b8b8c0004118200341186a41e0b8c0001038000bd70501037f024002400240024002400240024020002d00004101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d07200241017422042003200420034b1b22044100480d070240024020020d002004102821030c010b200128020020022004102c21030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41003a00000c010b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d06200241017422042003200420034b1b22044100480d060240024020020d002004102821030c010b200128020020022004102c21030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041016a2001108f010b024020002d00214101460d0002400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d06200041017422032002200320024b1b22034100480d060240024020000d002003102821020c010b200128020020002003102c21020b2002450d0420012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41003a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d05200241017422042003200420034b1b22044100480d050240024020020d002004102821030c010b200128020020022004102c21030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041226a2001108f010f0b200441011037000b200441011037000b200341011037000b200441011037000b1031000bbf0501047f200141046a2802002102200141086a28020021030240024002400240024002400240200028020022040d000240024020022003460d00200128020021020c010b200341016a22022003490d07200341017422042002200420024b1b22044100480d070240024020030d002004102821020c010b200128020020032004102c21020b2002450d0320012002360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200220036a41003a00000c010b0240024020022003460d00200128020021020c010b200341016a22022003490d06200341017422052002200520024b1b22054100480d060240024020030d002005102821020c010b200128020020032005102c21020b2002450d0320012002360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200220036a41013a000020042001108f010b200141046a2802002102200141086a28020021030240200028020422040d000240024020022003460d00200128020021000c010b200341016a22002003490d06200341017422022000200220004b1b22024100480d060240024020030d002002102821000c010b200128020020032002102c21000b2000450d0420012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000f0b0240024020022003460d00200128020021000c010b200341016a22002003490d05200341017422022000200220004b1b22024100480d050240024020030d002002102821000c010b200128020020032002102c21000b2000450d0420012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41013a000020042001108f010f0b200441011037000b200541011037000b200241011037000b200241011037000b1031000b860a05037f047e057f027e047f230022022103200241c0016b41607122022400200141186a220429000021052004200229039801370000200129001021062001200229039001370010200129000821072001200229038801370008200241003a00800120012900002108200120022903800137000020022005370378200220063703702002200737036820022008370360200141206a2d0000210420024180016a41176a2209200537000020024180016a41106a220a200229007137030020024180016a41086a220b2002290069370300200220022900613703800102402008a741ff01714101460d0020004200370300200324000f0b200241186a41176a2009290000370000200241186a41106a200a290300370300200241186a41086a200b2903003703002002200229038001370318200220043a0037200241386a200241186a10ac012002410036028001200241386a412020024180016a1006210c02400240200228028001220d417f460d002002200d36025c2002200c3602582002200241d8006a109f012002290300a70d01200228025c2204450d01200241106a290300210e2002290308210f20022004417f6a220a36025c20022002280258221041016a220b36025820102d0000220441014b0d01410021110240024020040e020100010b4100210403400240200a2004470d002002410036025c0c040b2002201020046a41026a360258200441016a2209210420094120470d000b2002200a20096b220a36025c41012111201020096a41016a210b0b200a450d012002200a417f6a220a36025c2002200b41016a360258200b2d0000220941014b0d01410021040240024020090e020100010b41002104200241003a00a00103400240200a2004470d002002410036025c200441ff0171450d04200241003a00a0010c040b20024180016a20046a200b20046a220941016a2d00003a00002002200941026a3602582002200441016a22093a00a0012009210420094120470d000b200241e0006a41086a20024180016a41086a290300370300200241e0006a41106a20024180016a41106a290300370300200241e0006a41186a20024180016a41186a29030037030020022002290380013703602002200a20096b36025c410121040b20024180016a41186a2209200241e0006a41186a220a29030037030020024180016a41106a220b200241e0006a41106a221029030037030020024180016a41086a2212200241e0006a41086a2213290300370300200220022903603703800120114102460d01200a20092903003703002010200b2903003703002013201229030037030020022002290380013703600240200d450d00200c102a0b20024180016a41186a200241e0006a41186a2209290300220537030020024180016a41106a200241e0006a41106a220a290300220837030020024180016a41086a200241e0006a41086a220b29030022063703002002200229036022073703800120092005370300200a2008370300200b200637030020022007370360200120043a000020012007370001200141096a2006370000200141116a2008370000200141196a2005370000200041306a200e370300200041286a200f3703002000420137030020002002290318370008200041106a200241186a41086a290300370000200041186a200241186a41106a290300370000200041206a200241186a41186a290300370000200324000f0b41c9b4c00041dd001050000b41c4d1c3004133200241b8016a419cd9c3001038000bfc0101057f230041306b220224000240411210282203450d00200341002900c1ae44370000200341106a41002f00d1ae443b0000200341086a41002900c9ae4437000020024292808080a0023702042002200336020020012002108f012002280208210320022802002101200241106a41186a22044200370300200241106a41106a22054200370300200241106a41086a220642003703002002420037031020012003200241106a1000200041186a2004290300370000200041106a2005290300370000200041086a20062903003700002000200229031037000002402002280204450d002002280200102a0b200241306a24000f0b411241011037000b910a03037f047e0c7f230022022103200241c0016b41607122022400200141186a220429000021052004200229039801370000200129001021062001200229039001370010200129000821072001200229038801370008200241003a00800120012900002108200120022903800137000020022005370378200220063703702002200737036820022008370360200141206a2d0000210420024180016a41176a2209200537000020024180016a41106a220a200229007137030020024180016a41086a220b2002290069370300200220022900613703800102402008a741ff01714101460d0020004100360220200324000f0b200241086a41176a2009290000370000200241086a41106a200a290300370300200241086a41086a200b2903003703002002200229038001370308200220043a0027200241286a200241086a10ae012002410036028001200241286a412020024180016a1006210c024002400240200228028001220d417f460d002002200d36024c2002200c360248200241d0006a200241c8006a106d2002280250220e450d022002280254210f200228024c2204450d01200241d8006a280200211020022004417f6a220a36024c20022002280248221141016a220b36024820112d0000220441014b0d01410021120240024020040e020100010b4100210403400240200a2004470d002002410036024c0c040b2002201120046a41026a360248200441016a2209210420094120470d000b2002200a20096b220a36024c41012112201120096a41016a210b0b200a450d012002200a417f6a220a36024c2002200b41016a360248200b2d0000220941014b0d01410021040240024020090e020100010b41002104200241003a00a00103400240200a2004470d002002410036024c200441ff0171450d04200241003a00a0010c040b20024180016a20046a200b20046a220941016a2d00003a00002002200941026a3602482002200441016a22093a00a0012009210420094120470d000b200241e0006a41086a20024180016a41086a290300370300200241e0006a41106a20024180016a41106a290300370300200241e0006a41186a20024180016a41186a29030037030020022002290380013703602002200a20096b36024c410121040b20024180016a41186a2209200241e0006a41186a220a29030037030020024180016a41106a220b200241e0006a41106a221129030037030020024180016a41086a2213200241e0006a41086a2214290300370300200220022903603703800120124102460d02200a20092903003703002011200b2903003703002014201329030037030020022002290380013703600240200d450d00200c102a0b20024180016a41186a200241e0006a41186a2209290300220537030020024180016a41106a200241e0006a41106a220a290300220837030020024180016a41086a200241e0006a41086a220b29030022063703002002200229036022073703800120092005370300200a2008370300200b200637030020022007370360200120043a000020012007370001200141096a2006370000200141116a2008370000200141196a2005370000200041286a20103602002000200f3602242000200e36022020002002290308370000200041086a200241086a41086a290300370000200041106a200241086a41106a290300370000200041186a200241086a41186a290300370000200324000f0b41c9b4c00041dd001050000b200f450d00200e102a0b41c4d1c3004133200241d0006a419cd9c3001038000bfc0101057f230041306b220224000240411210282203450d0020034100290095ae44370000200341106a41002f00a5ae443b0000200341086a410029009dae4437000020024292808080a0023702042002200336020020012002108f012002280208210320022802002101200241106a41186a22044200370300200241106a41106a22054200370300200241106a41086a220642003703002002420037031020012003200241106a1000200041186a2004290300370000200041106a2005290300370000200041086a20062903003700002000200229031037000002402002280204450d002002280200102a0b200241306a24000f0b411241011037000bfe0703037f047e0a7f23002202210320024180036b41607122022400200141186a220429000021052004200229039802370000200129001021062001200229039002370010200129000821072001200229038802370008200241003a0080022001290000210820012002290380023700002002200537039801200220063703900120022007370388012002200837038001200141206a2d0000210420024180026a41176a2209200537000020024180026a41106a220a20022900910137030020024180026a41086a220b20022900890137030020022002290081013703800202402008a741ff01714101460d00200041073a0040200324000f0b200241186a41176a2009290000370000200241186a41106a200a290300370300200241186a41086a200b2903003703002002200229038002370318200220043a0037200241e0006a200241186a10b0012002410036028002200241e0006a412020024180026a1006210c0240200228028002220d417f460d002002200d36023c2002200c36023820024180026a200241386a10b101024020022d00a1024102460d00200241d8016a41206a220420024180026a41206a2d00003a0000200241d8016a41186a220920024180026a41186a220e290300370300200241d8016a41106a220a20024180026a41106a220f290300370300200241d8016a41086a220b20024180026a41086a221029030037030020022002290380023703d80120024180016a200241a2026a41c100109a051a0240200d450d00200c102a0b200241386a41206a220d20042d00003a0000200241386a41186a220c2009290300370300200241386a41106a2211200a290300370300200241386a41086a2212200b290300370300200220022903d80137033820024180026a20024180016a41c100109a051a2004200d2d00003a00002009200c290300370300200a2011290300370300200b2012290300370300200220022903383703d80120024180016a20024180026a41c100109a051a200141206a20024180016a41c0006a2d00003a0000200141186a20024180016a41386a290000370000200141106a20024180016a41306a290000370000200141086a20024180016a41286a290000370000200120022900a001370000200e200241186a41186a290300370300200f200241186a41106a2903003703002010200241186a41086a290300370300200220022903183703800220024180026a41286a200b29030037030020024180026a41306a200a29030037030020024180026a41386a200929030037030020024180026a41c0006a20042d00003a0000200220022903d8013703a002200020024180026a41c100109a051a200324000f0b41c4d1c300413320024180016a419cd9c3001038000b41c9b4c00041dd001050000bfc0101057f230041306b220224000240411510282203450d00200341002900d088453700002003410d6a41002900dd8845370000200341086a41002900d8884537000020024295808080d0023702042002200336020020012002108f012002280208210320022802002101200241106a41186a22044200370300200241106a41106a22054200370300200241106a41086a220642003703002002420037031020012003200241106a1000200041186a2004290300370000200041106a2005290300370000200041086a20062903003700002000200229031037000002402002280204450d002002280200102a0b200241306a24000f0b411541011037000bd30b03097f017e017f23004190026b2202240041002103200241003a00880220012802042204417d6a2105417f21060240024002400240024002400240034020042003460d01200241e8016a20036a200128020022072d00003a00002001200420066a3602042001200741016a3602002002200341016a22083a0088022005417f6a21052006417f6a21062008210320084120470d000b200241c8016a41186a200241e8016a41186a290300370300200241c8016a41106a200241e8016a41106a290300370300200241c8016a41086a200241e8016a41086a290300370300200220022903e8013703c80120042008460d0120072d000121092001200420066a3602042001200741026a360200200941074f0d01200241086a41186a200241c8016a41186a290300370300200241086a41106a200241c8016a41106a290300370300200241086a41086a200241c8016a41086a290300370300200220022903c8013703082004417f6a2008460d0520072d000221032001200741036a220a3602002001200420086b2206417e6a2208360204200341014b0d0520030e020302030b200341ff0171450d00200241003a0088020b200041023a00210c040b41002103200241003a0088022006417e6a2104417d21080340024020042003470d00200341ff0171450d04200241003a0088020c040b200241e8016a20036a200720036a220641036a2d00003a00002001200520036b3602042001200641046a3602002002200341016a22063a0088022008417f6a21082006210320064120470d000b200241a8016a41086a200241e8016a41086a290300220b37030020024188016a41186a200241e8016a41186a29030037030020024188016a41106a200241e8016a41106a29030037030020024188016a41086a200b370300200220022903e801220b3703a8012002200b370388014101210c200520066b41016a2108200720066a41036a210a0c010b4100210c0b200241e8006a41186a20024188016a41186a290300370300200241e8006a41106a20024188016a41106a290300370300200241e8006a41086a20024188016a41086a29030037030020022002290388013703682008450d00200a2d0000210320012008417f6a3602042001200a41016a360200200341014b0d00410021060240024020030e020100010b41002103200241003a0088022008417f6a21042008417e6a21060340024020042003470d00200341ff0171450d03200241003a0088020c030b200241e8016a20036a200a20036a220841016a2d00003a0000200120063602042001200841026a3602002002200341016a22083a0088022006417f6a21062008210320084120470d000b200241a8016a41086a200241e8016a41086a290300220b37030020024188016a41186a200241e8016a41186a29030037030020024188016a41106a200241e8016a41106a29030037030020024188016a41086a200b370300200220022903e801220b3703a8012002200b37038801410121060b200241286a41186a220320024188016a41186a290300370300200241286a41106a220120024188016a41106a290300370300200241286a41086a220820024188016a41086a290300370300200241c8006a41086a2204200241e8006a41086a290300370300200241c8006a41106a2205200241e8006a41106a290300370300200241c8006a41186a2207200241e8006a41186a290300370300200220022903880137032820022002290368370348200041186a200241086a41186a290300370000200041106a200241086a41106a290300370000200041086a200241086a41086a290300370000200020022903083700002000200c3a0021200020093a0020200041c2006a20063a0000200020022903483700222000412a6a2004290300370000200041326a20052903003700002000413a6a2007290300370000200041c3006a2002290328370000200041cb006a2008290300370000200041d3006a2001290300370000200041db006a20032903003700000c010b200041023a00210b20024190026a24000b340020004197dbc00036020420004100360200200041146a4103360200200041106a41bcbcc000360200200041086a42083702000b5201027f230041106b2202240002404104102822030d00410441011037000b20024204370204200220033602004100200210b401200041086a200228020836020020002002290300370200200241106a24000b920701037f0240024002400240024002402000413f4b0d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d06200241017422042003200420034b1b22044100480d060240024020020d002004102821030c010b200128020020022004102c21030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20004102743a00000f0b200041808001490d032000418080808004490d020c010b200441011037000b0240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d05200241017422042003200420034b1b22044100480d050240024020020d002004102821030c010b200128020020022004102c21030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a000002400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d05200341017422022004200220044b1b22024100480d050240024020030d002002102821030c010b200128020020032002102c21030b2003450d0220012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20003600000f0b200441011037000b200241011037000b024002400240200141046a2802002203200141086a28020022026b4104490d00200128020021030c010b200241046a22042002490d03200341017422022004200220044b1b22024100480d030240024020030d002002102821030c010b200128020020032002102c21030b2003450d0120012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20004102744102723600000f0b200241011037000b024002400240200141046a2802002203200141086a28020022026b4102490d00200128020021030c010b200241026a22042002490d02200341017422022004200220044b1b22024100480d020240024020030d002002102821030c010b200128020020032002102c21030b2003450d0120012003360200200141046a2002360200200141086a28020021020b200141086a200241026a360200200320026a20004102744101723b00000f0b200241011037000b1031000bd82504027f027e087f037e230041b00d6b220724000240024002402001280230200128024022082802b801460d002004420020042903082209200841c0006a2903007d220a200a20095622081b3703082008450d0120004188c5c00036020420004101360200200041086a412a3602002000410c6a2006290200370200200041146a200641086a2802003602000c020b200041f3c3c00036020420004101360200200041086a41293602002000410c6a2006290200370200200041146a200641086a2802003602000c010b200741186a41186a200141e8006a290000370300200741186a41106a200141e0006a290000370300200741186a41086a200141d8006a290000370300200720012900503703182006280208210b20062802002108200741b0026a41186a220c4200370300200741b0026a41106a220d4200370300200741b0026a41086a220e4200370300200742003703b0022008200b200741b0026a1000200741d00a6a41186a200c290300370300200741d00a6a41106a200d290300370300200741d00a6a41086a200e290300370300200720072903b0023703d00a0240024002400240024002400240024002400240412010282208450d0020082005290000370000200841186a200541186a290000370000200841106a200541106a290000370000200841086a200541086a2900003700002008412041c000102c2208450d01200820072903d00a370020200841386a200741d00a6a41186a290300370000200841306a200741d00a6a41106a290300370000200841286a200741d00a6a41086a290300370000200841c000418001102c2208450d0220082007290318370040200841d8006a200741186a41186a290300370000200841d0006a200741186a41106a290300370000200841c8006a200741186a41086a290300370000200741b0026a41186a220c4200370300200741b0026a41106a220d4200370300200741b0026a41086a220e4200370300200742003703b002200841e000200741b0026a1000200741386a41186a220f200c290300370300200741386a41106a220c200d290300370300200741386a41086a220d200e290300370300200720072903b0023703382008102a20062902002109200741d8006a41d8006a200d290300370300200741d8006a41e0006a200c290300370300200741c0016a200f29030037030020074194016a410036020020074184016a419cc4c000360200200741f8006a4200370300200741f4006a221041f8b9c00036020020072001360260200741d8006a41286a200141186a2211360200200720072903383703a8012007420837028c012007410036027020074100360264200720012802483602a00120072001290340370398012007200128023041016a360288012001290300210a2007200128024c3602a4012007200a370358200741c8016a41186a200541186a290000370300200741c8016a41106a200541106a290000370300200741c8016a41086a200541086a29000037030020074101360270200720052900003703c8012011200741386a10b601210620072007280270417f6a2208360270024020060d0020080d042007417f36027020074190026a41186a200741386a41186a29030037030020074190026a41106a200741386a41106a29030037030020074190026a41086a200741386a41086a2903003703002007200729033837039002024002402007280274220e41f8b9c000460d002007280278210f0c010b4100210f200741d00a6a410041e0021099051a200741b0026a410041a0081099051a41880b1028220e450d06200e41003b0106200e4100360200200e41086a200741d00a6a41e002109a051a200e41e8026a200741b0026a41a008109a051a200741003602782007200e3602740b024002400340200e41086a2108200e2f0106221241057421064100210c0240024003402006450d0120074190026a20084120109c05220d450d02200641606a2106200c41016a210c200841206a2108200d417f4a0d000b200c417f6a21120b200f450d02200f417f6a210f200e20124102746a41880b6a280200210e0c010b0b200e200c41e0006c6a41e8026a21060c010b200741f0016a41186a20074190026a41186a290300220a370300200741f0016a41106a20074190026a41106a2903002213370300200741f0016a41086a20074190026a41086a2903002214370300200720072903900222153703f001200741ec0a6a2014370200200741d00a6a41246a2013370200200741fc0a6a200a3702002007200741d8006a41246a3602e00a200720123602dc0a200720103602d80a2007200e3602d40a200741003602d00a200720153702e40a200741e4026a4200370200200741003a00ec02200742003703b002200741003a008d03200741f8b9c0003602e002200742003703c802200741d00a6a200741b0026a10b70121060b200741e0016a290300210a20064201370318200641013a003c200641286a427f370300200641206a427f3703002006413d6a20072903c801370000200641d5006a200a370000200641cd006a200741d8016a290300370000200641c5006a200741d0016a2903003700002007200728027041016a360270200741106a20044101200741186a200741386a20022003200741d8006a10b8012007280210220e0d06200741b0026a200520072802a00128020010b901024020072802b0024101470d002009422088a72106200741b8026a280200210520072802b402210e2009a721010c0b0b20074190026a41186a200741b0026a410472220641186a2802002208360200200741d00a6a41106a200641086a290200370300200741d00a6a41186a200641106a290200370300200741f00a6a2008360200200741063602d40a200741b38dc6003602d00a200720062902003703d80a200728029c0121062007200741d8006a3602c8022007290358210a20072802a4012108200741d8026a200741186a41086a290300370300200741e0026a200741186a41106a290300370300200741e8026a200741186a41186a290300370300200720033703b802200720023703b002200720083602cc022007200a3703c002200720072903183703d0022007200b3602f801200720093703f00120074190026a2006200741d00a6a200741b0026a200741f0016a200410ba012007419c026a290200210220074190026a41086a2802002112200728029402210f02402007280290024101470d002002422088a72106200741a4026a280200210b2002a7210120122105200f210e0c0a0b200728027041016a220b41004c0d072007200b360270200728027821040240024003402010280200220541086a210820052f0106220e41057421064100210c0240024003402006450d01200741386a20084120109c05220d450d02200641606a2106200c41016a210c200841206a2108200d417f4a0d000b200c417f6a210e0b2004450d022004417f6a21042005200e4102746a41880b6a21100c010b0b2005200c41e0006c6a220641c5036a310000200641e8026a290300220320035022081ba7450d004200200641f8026a29030020081b21034200200641f0026a29030020081b21090c010b2007200728028001200741386a20072802840128021c110500200741086a2903002103200729030021092007280270210b0b2007200b417f6a3602702009200728029801220629037854200320064180016a29030022095420032009511b450d082002a7210b41c0c4c000210e411e2105200f2101201221060c090b2009422088a721062009a7210141dec4c000210e412a21050c090b412041011037000b41c00041011037000b41800141011037000b41a8b8c0004110200741b0026a41d0b8c0001038000b41880b41081037000b200728021421052009422088a721062009a721010c030b41b8b8c0004118200741b0026a41e0b8c0001038000b20074190026a41086a2208200741186a41086a29030037030020074190026a41106a220c200741186a41106a29030037030020074190026a41186a220d200741186a41186a290300370300200741f0016a41086a2205200741386a41086a290300370300200741f0016a41106a2204200741386a41106a290300370300200741f0016a41186a220e200741386a41186a2903003703002007200729031837039002200720072903383703f00102400240024002402007280294012206200728029001470d00200641016a220b2006490d0320064101742210200b2010200b4b1b2210ad42b0017e2203422088a70d032003a7220b4100480d030240024020060d00200b102821060c010b200728028c01200641b0016c200b102c21060b2006450d0120072010360290012007200636028c0120072802940121060b200728028c01200641b0016c6a220641003a0000200620072f00ed013b0001200641013a00102006410036000c200642013700042006200729039002370011200620072903f001370031200641036a200741ef016a2d00003a0000200641196a2008290300370000200641216a200c290300370000200641296a200d290300370000200641396a2005290300370000200641c1006a2004290300370000200641c9006a200e290300370000200641e0006a200741d7016a290000370000200641d9006a200741c8016a41086a290000370000200620072900c801370051200641e8006a200741b0026a41c800109a051a200720072802940141016a2208360294010240200741d00a6a41186a280200450d00200741e40a6a280200102a20072802940121080b200728029001210e200728028c012105200728027c210b2007280278210d2007280274210602402007280264220c450d00200741e8006a280200450d00200c102a0b0240024020024280808080f01f8350450d002007200b3602b8022007200d3602b402200720063602b0022011200741b0026a10bb012007200e3602b402200720053602b00220072005200841b0016c22086a22043602bc0202400240200141386a280200220c2001413c6a28020022066b200841b0016d220d490d002001280234210c0c010b2006200d6a220e2006490d05200c4101742206200e2006200e4b1b2206ad42b0017e2203422088a70d052003a7220e4100480d0502400240200c0d00200e1028210c0c010b2001280234200c41b0016c200e102c210c0b200c450d042001200c360234200141386a20063602002001413c6a28020021060b200c200641b0016c6a20052008109a051a2001413c6a22062006280200200d6a360200200720043602b802200741b0026a10690c010b02402008450d00200841b0016c210441002108034002400240200520086a220c2d0000220141014b0d000240024020010e020001000b0240200c41086a280200450d00200c41046a280200102a0b200c41106a2d00004105490d02200c41386a280200450d02200c41346a280200102a0c020b200c41286a106a0c010b200c41e8006a280200450d00200c41e4006a280200102a0b2004200841b0016a2208470d000b0b0240200e450d002005102a0b02400240200d0d00200621080c010b200d210c20062108034020082802880b2108200c417f6a220c0d000b0340200620062f01064102746a41880b6a2802002106200d417f6a220d0d000b0b200741cc026a20062f0106360200200741c8026a4100360200200741c4026a20063602002007200b3602d002200741003602c002200742003703b802200720083602b402200741003602b002200741b0026a109b010b20002007290338370004200041003602002000412c6a2002370200200041286a2012360200200041246a200f3602002000411c6a200741d0006a290300370000200041146a200741c8006a2903003700002000410c6a200741c0006a2903003700000c050b200b41081037000b200e41081037000b1031000b200741e80a6a280200450d00200741e40a6a280200102a0b024020072802642208450d00200741e8006a280200450d002008102a0b2006ad2102200728027c21042007280274210602400240200728027822080d002006210c0c010b2008210d2006210c0340200c2802880b210c200d417f6a220d0d000b0340200620062f01064102746a41880b6a28020021062008417f6a22080d000b0b200242208621022001ad2103200741cc026a20062f010636020041002108200741c8026a4100360200200741c4026a2006360200200720043602d002200741003602c002200742003703b8022007200c3602b402200741003602b002200741b0026a109b0102402007280294012206450d00200728028c01210d200641b0016c2101034002400240200d20086a22062d0000220c41014b0d0002400240200c0e020001000b0240200641086a280200450d00200641046a280200102a0b200641106a2d00004105490d02200641386a280200450d02200641346a280200102a0c020b200641286a106a0c010b200641e8006a280200450d00200641e4006a280200102a0b2001200841b0016a2208470d000b0b200220038421020240200728029001450d00200728028c01102a0b2000200e36020420004101360200200041146a200b3602002000410c6a2002370200200041086a20053602000b200741b00d6a24000bb80201097f230041106b220224000240200028020041016a220341004c0d0020002003360200200041046a2104200041086a280200210502400240024003402004280200220641086a210720062f010622084105742104410021090240024003402004450d01200120074120109c05220a450d02200441606a2104200941016a2109200741206a2107200a417f4a0d000b2009417f6a21080b2005450d022005417f6a2105200620084102746a41880b6a21040c010b0b2006200941e0006c6a220441a4036a2d000022074101410220074101461b200441c5036a2d00001b22044102470d010b20002802102001200041146a2802002802181101002104200028020021030c010b200441014621040b20002003417f6a360200200241106a240020040f0b41b8b8c0004118200241086a41e0b8c0001038000b8f1901187f230041d0116b2202240020002802102203200328020041016a360200200028020c21042000280208210520002802042103200241206a41186a22062000412c6a290000370300200241206a41106a2207200041246a290000370300200241206a41086a22082000411c6a29000037030020022000290014370320200241a0026a200141e000109a051a024002400240024020032f01062201410b490d00200241b0036a410041e0021099051a20024198066a410041a0081099051a0240024041880b10282209450d00200941003b010620094100360200200941086a200241b0036a41e002109a052101200941e8026a20024198066a41a008109a052106200220032f00c8013b01ac032002200341ca016a2d00003a00ae03200220032900db01370398032002200341e0016a29000037009d03200341cb016a280000210a200341cf016a280000210b200341d3016a280000210c200341d7016a280000210d20024198066a200341a8076a41e000109a051a2001200341e8016a20032f010641796a2200410574109a052101200620034188086a200041e0006c109a052106200341063b0106200920003b0106200220022f01ac033b019403200220022d00ae033a0096032002200229039803370380032002200229009d0337008503200241b0036a20024198066a41e000109a051a0240024020044107490d00200441057420016a41c07e6a2001200441796a22074105746a2201200041ffff037120076b410574109b051a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200441e0006c20066a220041c07b6a200041e07a6a220e200941066a22002f010020076b41e0006c109b051a200e200241a0026a41e000109a051a0c010b200341086a20044105746a220141206a2001200341066a22002f010020046b410574109b051a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200341e8026a200441e0006c6a220e41e0006a200e20002f010020046b41e0006c109b051a200e200241a0026a41e000109a051a0b20024188026a41026a220420022d0096033a0000200020002f010041016a3b0100200220022f0194033b01880220022002290380033703800120022002290085033700850120024190016a200241b0036a41e000109a051a2002411c6a41026a220f20042d00003a0000200220022f0188023b011c2002200229038001370308200220022900850137000d200241206a20024190016a41e000109a051a20032802002206450d0320032f0104211020024198066a410272211103402002419c026a41026a2212200f2d00003a0000200220022f011c3b019c0220022002290308370388022002200229000d37008d02200241a0026a200241206a41e000109a051a201041ffff0371210702400240024020062f01062203410b490d002011410041b20b1099051a41b80b10282201450d0520014100360200200141046a20024198066a41b40b109a051a200220062f00c8013b01ac032002200641ca016a2d00003a00ae03200220062900db01370398032002200641e0016a29000037009d03200641cb016a2800002113200641cf016a2800002114200641d3016a2800002115200641d7016a280000211620024198066a200641a8076a41e000109a051a200141086a200641e8016a20062f0106220041796a2203410574109a052117200141e8026a20064188086a200341e0006c109a052118200141880b6a200641a40b6a2000417a6a2208410274109a052119200641063b0106200120033b010602402008450d00410021032019210003402000280200220420033b010420042001360200200041046a21002008200341016a2203470d000b0b200241b0036a20024198066a41e000109a051a200220022d00ae0322033a009603200220022f01ac0322003b0194032002200229009d033700850320022002290398033703800320024194066a41026a220820033a0000200220003b01940620022002290380033703800120022002290085033700850120024198066a200241b0036a41e000109a051a201041ffff037122004107490d0120172007417a6a22044105746a2017200741796a22034105746a220020012f010620036b410574109b051a200041186a200229008d023700002000200d36000f2000200c36000b2000200b3600072000200a360003200041026a20122d00003a0000200020022f019c023b00002000200229038802370013200741e0006c20186a220041c07b6a200041e07a6a220020012f010620036b41e0006c109b051a2000200241a0026a41e000109a051a200120012f010641016a22003b01062007410274220a20196a416c6a201920044102746a2210200041ffff0371220720046b410274109b051a2010200936020020072004490d022001200a6a41f00a6a2100034020002802002204200341016a22033b010420042001360200200041046a210020032007490d000c030b0b200641086a2200200741016a22044105746a200020074105746a2200200320076b2201410574109b051a2000200d36000f2000200c36000b2000200b3600072000200a360003200041026a2002419c026a41026a2d00003a0000200020022f019c023b00002000200229038802370013200041186a200229008d023700002006200741e0006c6a220041c8036a200041e8026a2200200141e0006c109b051a2000200241a0026a41e000109a051a2006200341016a22033b01062007410274200641880b6a22006a41086a200020044102746a2200200341ffff037120046b410274109b051a20002009360200201041ffff037120062f010622034f0d07200920043b010420092006360200200420034f0d072003417f6a210120062004417f6a22034102746a41900b6a2100034020002802002204200341026a3b010420042006360200200041046a21002001200341016a2203470d000c080b0b200641086a2203200741016a22044105746a200320074105746a220320062f0106221020076b2219410574109b051a2003200d36000f2003200c36000b2003200b3600072003200a360003200341026a20122d00003a0000200320022f019c023b00002003200229038802370013200341186a200229008d02370000200641e8026a200741e0006c6a220341e0006a2003201941e0006c109b051a2003200241a0026a41e000109a051a2006201041016a22033b010620074102742219200641880b6a22106a41086a201020044102746a2210200341ffff037120046b410274109b051a20102009360200200020062f010622044f0d00200620196a418c0b6a2103034020032802002200200741016a22073b010420002006360200200341046a210320042007470d000b0b20024184026a41026a220320082d00003a0000200220022f0194063b01840220022002290380013703f00120022002290085013700f50120024190016a20024198066a41e000109a051a200f20032d00003a0000200220022f0184023b011c200220022903f001370308200220022900f50137000d200241206a20024190016a41e000109a051a0240200628020022030d002013210a2016210d2015210c2014210b200121090c050b20062f010421102013210a2016210d2015210c2014210b20032106200121090c000b0b41880b41081037000b41b80b41081037000b200320044105746a220041286a200041086a2210200120046b410574109b051a200041206a2006290300370000200041186a2007290300370000200041106a2008290300370000201020022903203700002003200441e0006c6a220041c8036a200041e8026a220e20032f010620046b41e0006c109b051a200e200241a0026a41e000109a051a200320032f010641016a3b01060c010b20024198066a410272410041b20b1099051a41b80b10282203450d0120034100360200200341046a20024198066a41b40b109a051a2003200528020022003602880b200520033602002005200528020441016a360204200041003b010420002003360200200320032f010622044105746a220041086a20022f011c3b00002000410a6a2002411c6a41026a2d00003a0000200041176a200d360000200041136a200c3600002000410f6a200b3600002000410b6a200a3600002000411b6a2002290308370000200041206a200229000d3700002003200441e0006c6a41e8026a200241206a41e000109a051a200341880b6a200441016a22004102746a2009360200200320003b0106200920003b0104200920033602000b200241d0116a2400200e0f0b41b80b41081037000b9f19020a7f087e230041800c6b220824000240024002400240024002400240024002400240200728021841016a220941004c0d0020072009360218200741206a280200210a2007411c6a220b210c024002400340200c280200220d41086a210e200d2f0106220f410574210c41002110024002400340200c450d012004200e4120109c052211450d02200c41606a210c201041016a2110200e41206a210e2011417f4a0d000b2010417f6a210f0b200a450d02200a417f6a210a200d200f4102746a41880b6a210c0c010b0b200d201041e0006c6a220c41c5036a310000200c41e8026a2903002212201250220e1ba7450d004200200c41f8026a290300200e1b21134200200c41f0026a290300200e1b21140c010b200841286a200741286a28020020042007412c6a28020028021c110500200841306a290300211320072802182109200829032821140b20072009417f6a360218200141186a29030021122007280240210c20012903102115024002400240024041004101410220142013842216501b20021b0e03010200010b200c41a8016a210c0c020b200c4188016a210c0c010b200c4198016a210c0b20152012844200510d01200841186a200c290300200c41086a2903002015201210a00520014200200129030822122008290318427f200841186a41086a290300501b7d22152015201256220c1b3703080240200c450d0041b2c5c000210c4122210e0c0a0b200728021841016a220141004c0d02200720013602182007280220210a200b210c024002400340200c280200220d41086a210e200d2f0106220f410574210c41002110024002400340200c450d012003200e4120109c052211450d02200c41606a210c201041016a2110200e41206a210e2011417f4a0d000b2010417f6a210f0b200a450d02200a417f6a210a200d200f4102746a41880b6a210c0c010b0b200d201041e0006c6a220c41c5036a310000200c41e8026a2903002212201250220e1ba7450d004200200c41f8026a290300200e1b21124200200c41f0026a290300200e1b21150c010b200841086a200741286a28020020032007412c6a28020028021c110500200841106a290300211220072802182101200829030821150b20072001417f6a3602180240201520057d2217201556201220067d2015200554ad7d221520125620152012511b4101470d00419893c100210c411d210e0c0a0b024020164200520d002007280240220c290378200556200c4180016a290300221220065620122006511b450d0041e293c100210c411f210e0c0a0b2008200341022017201510bc0102402008280200220c450d002008280204210e0c0a0b0240201420057c2216201454220c201320067c200cad7c221220135420122013511b450d0041b593c100210c412d210e0c0a0b4100210c024020032004470d000c0a0b0240200320044120109c050d000c0a0b20072802180d032007417f360218200841e0006a41186a200341186a290000370300200841e0006a41106a200341106a290000370300200841e0006a41086a200341086a2900003703002008200329000037036002400240200728021c221141f8b9c000460d002007280220210a0c010b4100210a200841a0096a410041e0021099051a20084180016a410041a0081099051a41880b10282211450d05201141003b010620114100360200201141086a200841a0096a41e002109a051a201141e8026a20084180016a41a008109a051a200741003602202007201136021c0b02400240034020112f0106220f410574210d4100210c4100210e02400340200d200c460d01200841e0006a2011200c6a41086a4120109c052210450d03200c41206a210c200e41016a210e2010417f4a0d000b200e417f6a210f0b0240200a450d00200a417f6a210a2011200f4102746a41880b6a28020021110c010b0b200841c0006a41186a200841e0006a41186a2903002213370300200841c0006a41106a200841e0006a41106a2903002214370300200841c0006a41086a200841e0006a41086a2903002218370300200820082903602219370340200841bc096a2018370200200841a0096a41246a2014370200200841cc096a20133702002008200741246a22013602b0092008200f3602ac092008200b3602a809200820113602a409200841003602a009200820193702b409200841b4016a4200370200200841bc016a41003a0000200841f8b9c0003602b00120084200370398012008420037038001200841003a00dd01200841a0096a20084180016a10b701210c0c010b20084198016a420037030020084194016a41f8b9c000360200200841003602a00120084100360290012008420037038801200841f8b9c000360284012008410036028001200741246a21012011200e41e0006c6a41e8026a210c20084180016a1095010b200c41106a2015370300200c2017370308200c420137030020072007280218220c41016a220e360218200e200c4f0d052007417f360218200841e0006a41186a200441186a290000370300200841e0006a41106a200441106a290000370300200841e0006a41086a200441086a2900003703002008200429000037036002400240200728021c221141f8b9c000460d002007280220210a0c010b4100210a200841a0096a410041e0021099051a20084180016a410041a0081099051a41880b10282211450d07201141003b010620114100360200201141086a200841a0096a41e002109a051a201141e8026a20084180016a41a008109a051a200741003602202007201136021c0b02400240034020112f0106220f410574210d4100210c4100210e02400340200d200c460d01200841e0006a2011200c6a41086a4120109c052210450d03200c41206a210c200e41016a210e2010417f4a0d000b200e417f6a210f0b0240200a450d00200a417f6a210a2011200f4102746a41880b6a28020021110c010b0b200841c0006a41186a200841e0006a41186a2903002215370300200841c0006a41106a200841e0006a41106a2903002213370300200841c0006a41086a200841e0006a41086a2903002214370300200820082903602217370340200841bc096a2014370200200841c4096a2013370200200841cc096a2015370200200820013602b0092008200f3602ac092008200b3602a809200820113602a409200841003602a009200820173702b409200841b4016a4200370200200841bc016a41003a0000200841f8b9c0003602b00120084200370398012008420037038001200841003a00dd01200841a0096a20084180016a10b701210c0c010b20084198016a420037030020084194016a41f8b9c000360200200841003602a00120084100360290012008420037038801200841f8b9c0003602840120084100360280012011200e41e0006c6a41e8026a210c20084180016a1095010b200c41106a2012370300200c2016370308200c42013703002007200728021841016a360218200841a0096a41086a2210200341086a290000370300200841a0096a41106a2211200341106a290000370300200841a0096a41186a220d200341186a290000370300200841e0006a41086a220a200441086a290000370300200841e0006a41106a220f200441106a290000370300200841e0006a41186a2201200441186a290000370300200820032900003703a0092008200429000037036002402007413c6a280200220e200741386a280200470d00200e41016a220c200e490d09200e4101742204200c2004200c4b1b2203ad42b0017e2212422088a70d092012a722044100480d0902400240200e0d0020041028210c0c010b2007280234200e41b0016c2004102c210c0b200c450d082007200c360234200741386a2003360200200728023c210e0b4100210c2007280234200e41b0016c6a220e41003a0000200e20082f003d3b0001200e4200370008200e4101360004200e20082903a009370011200e2008290360370031200e41036a2008413f6a2d00003a0000200e41106a41003a0000200e41196a2010290300370000200e41216a2011290300370000200e41296a200d290300370000200e41396a200a290300370000200e41c1006a200f290300370000200e41c9006a2001290300370000200e2005370358200e41e0006a2006370300200e41d4006a200841c0006a41036a280000360000200e2008280040360051200e41e8006a20084180016a41c800109a051a2007200728023c41016a36023c0c090b41b8b8c000411820084180016a41e0b8c0001038000b419cb7c0001032000b41b8b8c000411820084180016a41e0b8c0001038000b41a8b8c000411020084180016a41d0b8c0001038000b41880b41081037000b41a8b8c000411020084180016a41d0b8c0001038000b41880b41081037000b200441081037000b1031000b2000200e3602042000200c360200200841800c6a24000bb011030b7f017e047f230041b0016b220324000240024002400240024002400240024002400240411410282204450d00200441002900ddd843370000200441106a41002800edd843360000200441086a41002900e5d84337000020034294808080c00237023c200320043602382003200341386a36028001200120034180016a10c801200328023821042003280240210520034180016a41186a2206420037030020034180016a41106a2207420037030020034180016a41086a2208420037030020034200370380012004200520034180016a1000200341d8006a41186a2006290300370300200341d8006a41106a2007290300370300200341d8006a41086a200829030037030020032003290380013703580240200328023c450d002003280238102a0b2003410036028001200341d8006a412020034180016a100621062003280280012209417f460d032006450d0320032009360284012003200636028001200341286a20034180016a106c20032802280d02200328022c2105200341206a20034180016a106c20032802200d0220032802242108200341186a20034180016a106c20032802180d022003280284012204450d02200328021c210a20032004417f6a360284012003200328028001220441016a3602800120042d0000220441014b0d024100210b0240024020040e020100010b4101210b0b200341106a20034180016a106c20032802100d02200328028401220c20032802142204490d022004417f4c0d050240024020040d00410121070c010b2004102e2207450d022007200328028001220d2004109a051a2003200c20046b360284012003200d20046a360280010b2007450d02200341a0016a41026a220c200341386a41026a220d2d00003a0000200320032f00383b01a00102402009450d002006102a0b200d200c2d000022063a0000200341346a41026a20063a0000200320032f01a00122063b0138200320063b0134410021060c040b411441011037000b200441011037000b41c4d1c3004133200341386a419cd9c3001038000b4101210641d2bfc2002105411121084102210b0b200341306a41026a2209200341346a41026a220c2d00003a0000200320032f01343b013002402006450d002000200536020420004101360200200041086a20083602000c050b200c20092d00003a0000200320032f01303b013402400240200228025820054b0d002004210620042102200721090c010b411510282205450d02200541002900c8d8433700002005410d6a41002900d5d843370000200541086a41002900d0d84337000020034295808080d00237023c200320053602382003200341386a36028001200120034180016a10c801200328023821052003280240210620034180016a41186a2208420037030020034180016a41106a2209420037030020034180016a41086a220b420037030020034200370380012005200620034180016a1000200341d8006a41186a2008290300370300200341d8006a41106a2009290300370300200341d8006a41086a200b29030037030020032003290380013703580240200328023c450d002003280238102a0b2003410036028001200341d8006a412020034180016a100621060240024002402003280280012208417f460d002006450d0020032008360284012003200636028001200341086a20034180016a106c02400240024020032802080d002003280284012209200328020c2205490d002005417f4c0d070240024020050d004101210c0c010b2005102e220c450d02200c200328028001220b2005109a051a2003200920056b360284012003200b20056a360280010b200c0d020b41c4d1c3004133200341386a419cd9c3001038000b200541011037000b2005ad220e422086200e84210e02402008450d002006102a0b20034180016a200c200e422088a7200210f802200ea7210d20034180016a41086a280200210820032802840121052003280280014101470d022000200536020420004101360200200041086a2008360200200d450d01200c102a0c010b200041e3bfc20036020420004101360200200041086a411a3602000b2004450d062007102a0c060b200341d8006a41026a220f2003419f016a2d00003a0000200320032f009d013b01582003419c016a2d0000210b20034198016a280200210620034194016a280200210220034190016a28020021092003418c016a280200210a02402004450d002007102a0b200341346a41026a200f2d00003a0000200320032f01583b01342006417f4c0d010240024020060d0041002107410121040c010b20062107200610282204450d040b200420092006109a05210f200341386a41146a2006360200200341386a41106a20073602002003200a3602402003200836023c200320053602382003200f3602442003200b41ff01714101463a0050411410282204450d04200441002900ddd843370000200441106a41002800edd843360000200441086a41002900e5d84337000020034294808080c0023702a401200320043602a0012003200341a0016a36028001200120034180016a10c80120032802a001210420032802a801210120034180016a41186a2210420037030020034180016a41106a2211420037030020034180016a41086a2212420037030020034200370380012004200120034180016a1000200341d8006a41186a2010290300370300200341d8006a41106a2011290300370300200341d8006a41086a20122903003703002003200329038001370358024020032802a401450d0020032802a001102a0b20034120360284012003200341d8006a36028001200341386a20034180016a10f90202402007450d00200f102a0b200d450d00200c102a0b20002005360204200020032f01343b001d200041003602002000411c6a200b3a0000200041186a2006360200200041146a2002360200200041106a20093602002000410c6a200a360200200041086a20083602002000411f6a200341366a2d00003a00000c040b1036000b411541011037000b200641011037000b411441011037000b200341b0016a24000b821d02097f017e230041e0006b22062400024002402002410c6a280200200241106a280200100f2207417f460d00410c102822080d01410c41041037000b10fc02000b200820073602082008428180808010370200200641186a420037030020064280808080c0003703102006420437030802400240024002400240024002400240024002400240024002400240024002402008280200220741016a220941014d0d00200820093602002007417e460d002008200741026a3602000240200628021c22072006280218470d00200741016a22092007490d0b2007410174220a2009200a20094b1b220941ffffffff03712009470d0b2009410274220b4100480d0b0240024020070d00200b1028210a0c010b20062802142007410274200b102c210a0b200a450d02200620093602182006200a3602140b200628021420074102746a20083602002006200628021c41016a36021c2008280208210b410310282209450d02200941026a41002d00fae2453a0000200941002f00f8e2453b000041061028220a450d03200a41046a41002f00cf8f443b0000200a41002800cb8f44360000024020062802102207200628020c470d00200741016a220c2007490d0b2007410174220d200c200d200c4b1b220c41ffffff3f71200c470d0b200c410574220e4100480d0b0240024020070d00200e1028210d0c010b20062802082007410574200e102c210d0b200d450d052006200c36020c2006200d3602080b200628020820074105746a220741013602182007200a36020c2007428380808030370204200720093602002007411c6a200b360200200741106a4286808080e0003702002006200628021041016a36021020082008280200417f6a2207360200024020070d002008280208101020082008280204417f6a220736020420070d002008102a0b200641086a41f8e2c500410341effec5004103410b10fe02200641086a41f8e2c500410341f2fec500410f410c10fe02200641086a41f8e2c50041034181ffc500410f410d10fe02200641086a41f8e2c50041034190ffc5004108410e10fe02200641086a41f8e2c50041034198ffc500410f410f10fe02200641086a41f8e2c500410341a7ffc500410a411010fe02200641086a41f8e2c500410341b1ffc500410a411110fe02200641086a41f8e2c500410341bbffc500410b411210fe02200641086a41f8e2c500410341c6ffc500410d411310fe02200641086a41f8e2c500410341d3ffc500410c411410fe02200641086a41f8e2c500410341dfffc500410b411510fe02200641086a41f8e2c500410341eaffc5004115411610fe02200641086a41f8e2c500410341ffffc500410a411710fe02200641086a41f8e2c5004103418980c6004107411810fe02200641086a41f8e2c5004103419080c6004113411910fe02200641086a41f8e2c500410341a380c6004111411a10fe02200641086a41f8e2c500410341b480c600410e411b10fe02200641086a41f8e2c500410341c280c6004110411c10fe02200641086a41f8e2c500410341d280c6004110411d10fe02200641086a41f8e2c500410341e280c6004111411e10fe02200641086a41f8e2c500410341f380c6004111411f10fe02200641086a41f8e2c5004103418481c6004116412010fe02200641086a41f8e2c5004103419a81c6004112412110fe02200641086a41f8e2c500410341ac81c600410b412210fe02200641086a41f8e2c500410341b781c6004110412310fe02200641206a410c6a200441086a280200360200200620033602204100210d2006410036023c20062005360238200620083602342006200429020037022420062001280200360230200241146a280200210b2002411c6a280200210c200628020821072006280210210820064100360258200642013703502008200641d0006a10b40102402008450d00200720084105746a2105034020072802002104200741086a2802002208200641d0006a10b401024002402006280254220a200628025822096b2008490d002006280250210a0c010b200920086a22012009490d0d200a41017422032001200320014b1b22014100480d0d02400240200a0d0020011028210a0c010b2006280250200a2001102c210a0b200a450d08200620013602542006200a3602500b2006200920086a360258200a20096a20042008109a051a2007410c6a2802002103200741146a280200220a200641d0006a10b4010240024020062802542209200628025822046b200a490d00200628025021080c010b2004200a6a22082004490d0d200941017422012008200120084b1b22014100480d0d0240024020090d002001102821080c010b200628025020092001102c21080b2008450d092006200136025420062008360250200121090b20062004200a6a2201360258200820046a2003200a109a051a02400240200741186a2802004101460d000240024020092001460d002009210a0c010b200941016a220a2009490d0f20094101742204200a2004200a4b1b220a4100480d0f0240024020090d00200a102821080c010b20082009200a102c21080b2008450d0c2006200a360254200620083602500b2006200141016a2209360258200820016a41013a000020062007411c6a2802002204360248200641c8006a21010c010b0240024020092001460d002009210a0c010b200941016a220a2009490d0e20094101742204200a2004200a4b1b220a4100480d0e0240024020090d00200a102821080c010b20082009200a102c21080b2008450d0c2006200a360254200620083602500b2006200141016a2209360258200820016a41023a000020062007411c6a2802002204360248200641c8006a21010b0240200a20096b41034b0d00200941046a22042009490d0d200a41017422032004200320044b1b22044100480d0d02400240200a0d002004102821080c010b2008200a2004102c21080b2008450d0c2006200436025420062008360250200128020021040b2006200941046a360258200820096a2004360000200741206a22072005470d000b0b2006280254210302404124200b200c2006280250220e2006280258200641206a1011220b41036a220841024b0d000240024020080e03000201000b4102210d0b41012104024020030d000c110b200e102a0c100b200628021c220541ffffffff03712005470d0b20054102742207417f4c0d0b200628021421080240024020070d004104210c0c010b20071028220c450d0d0b0240024020050d004100210a0c010b200541027421044100210a200c210703402008280200220928020041016a220141014d0d022009200136020020072009360200200a41016a210a200741046a2107200841046a21082004417c6a22040d000b0b02402003450d00200e102a0b200228020421092002280200210420064100360258200642013703504100200641d0006a10b401200628025821012006280254210220062802502107410a102e2208450d0d0240024002400240200b20042009200720012008410a200641206a101241036a220941034b0d004101210420090e0402000001020b41a8c7c2001032000b2006410936024c410121042006200841016a36024820082d0000220941014b0d01410421010240024020090e020100010b200641d0006a200641c8006a109803200628025022014104460d02200628025421030b410021040b2008102a2002450d0f2007102a0c0f0b2008102a024020020d000c0f0b2007102a0c0e0b00000b200b41041037000b410341011037000b410641011037000b200e41041037000b200141011037000b200141011037000b200a41011037000b200a41011037000b200441011037000b1031000b1036000b200741041037000b410a41011037000b200b10130240200a450d00200a4102742107200c21080340200828020022092009280200417f6a3602000240200828020022092802000d0020092802081010200828020022092009280204417f6a360204200828020022092802040d002009102a0b200841046a21082007417c6a22070d000b0b4102210d2005450d00200c102a0b200641206a41086a28020021072006280234210820062802242109024002400240024002400240024002400240200628023c220a0d002006412c6a290200210f20040d04200141044b0d0320010e050203030301020b2000200a36020420004100360200200041106a41003a0000200041086a200641c0006a29030037020002402007450d002009102a0b20082008280200417f6a220736020020070d072008280208101020082008280204417f6a22073602042007450d060c070b2000200936020441002109200041106a41003a00002000410c6a4100360200200041086a20073602000c040b20002009360204200041106a20033a00002000410c6a200f3e0200200041086a2007360200410021090c030b200041aa9cc400360204200041146a200f3e0200200041106a20073602002000410c6a2009360200200041086a41113602000c010b0240200d450d00200041cb9cc400360204200041146a200f3e0200200041106a20073602002000410c6a2009360200200041086a41103602000c010b200041bb9cc400360204200041146a200f3e0200200041106a20073602002000410c6a2009360200200041086a41103602000b410121090b2000200936020020082008280200417f6a220736020020070d012008280208101020082008280204417f6a220736020420070d010b2008102a0b024020062802102207450d00200628020821082007410574210703400240200841046a280200450d002008280200102a0b0240200841106a280200450d002008410c6a280200102a0b200841206a2108200741606a22070d000b0b0240200628020c450d002006280208102a0b0240200628021c2207450d0020062802142108200741027421070340200828020022092009280200417f6a3602000240200828020022092802000d0020092802081010200828020022092009280204417f6a360204200828020022092802040d002009102a0b200841046a21082007417c6a22070d000b0b02402006280218450d002006280214102a0b200641e0006a24000b8a1409057f017e0c7f047e037f017e037f047e097f230041f00c6b22022400024020002802000d002000417f360200200128020821032001280200210402400240200128020422050d00200421010c010b2005210620042101034020012802880b21012006417f6a22060d000b0340200420042f01064102746a41880b6a28020021042005417f6a22050d000b0b2002411c6a20042f0106360200200241186a4100360200200241146a20043602002002200336022020024100360210200242003703082002200136020420024100360200200241f0016a2002109301024020022903900222074202510d002000410c6a2108200041046a2109200241900a6a41146a210a200241900a6a41206a210b200241f0016a4104722103200241f0016a413d6a210c200241cd026a210d200241b8026a210e200241f0016a41306a210f200241f0016a41286a21100340200241c8006a41086a2204200241f0016a41086a2211290300370300200241c8006a41106a2201200241f0016a41106a2212290300370300200241c8006a41186a2205200241f0016a41186a2213290300370300200220022903f001370348200e2903002114200f290300211520022903b0022116200229039802211720022f01ee02211820022d00ed02211920022d00cc02211a20022903a802211b20022802c002211c20022802c402211d20022802c802211e200241286a41186a200d41186a290000221f370300200241286a41106a200d41106a2900002220370300200241286a41086a200d41086a29000022213703002002200d2900002222370328200241e8006a41186a2223201f370300200241e8006a41106a22242020370300200241e8006a41086a222520213703002002202237036820024188016a41186a2226200529030037030020024188016a41106a2227200129030037030020024188016a41086a222820042903003703002002200229034837038801024002400240024002402009280200222941f8b9c000460d002000280208212a0c010b200241900a6a410041e0021099051a200241f0016a410041a0081099051a41880b10282229450d014100212a202941003b010620294100360200202941086a200241900a6a41e002109a051a202941e8026a200241f0016a41a008109a051a20004100360208200020293602040b0340202941086a210120292f0106222b410574210441002105024003402004450d0120024188016a20014120109c052206450d04200441606a2104200541016a2105200141206a21012006417f4a0d000b2005417f6a212b0b0240202a450d00202a417f6a212a2029202b4102746a41880b6a28020021290c010b0b200241c0016a41186a2026290300221f370300200241c0016a41106a20272903002220370300200241c0016a41086a20282903002221370300200220022903880122223703c001200a2022370200200a41086a2021370200200a41106a2020370200200a41186a201f370200200220083602a00a2002202b36029c0a200220093602980a200220293602940a200241003602900a20102014370300201220153703002002201637039002200220173703f8012002201a3a00ac022002201e3602a8022002201d3602a4022002201c3602a0022002201b37038802200220073703f001200c2002290368370000200c41086a2025290300370000200c41106a2024290300370000200c41186a2023290300370000200220183b01ce02200220193a00cd02200241900a6a200241f0016a10b7011a0c020b41880b41081037000b202941e8026a200541e0006c6a2129024020194101710d0020292029290300200720075022041b37030020292029290308201720041b370308202941106a22012001290300201520041b370300200241900a6a41186a22062023290300370300200241900a6a41106a222a2024290300370300200241900a6a41086a222b2025290300370300200220022903683703900a20292d003c21012013202941d5006a22052900003703002012202941cd006a22192900003703002011202941c5006a222329000037030020022029413d6a22242900003703f0012028200241900a6a200241f0016a201a41ff0171410146221a1b220441086a2900003703002027200441106a2900003703002026200441186a2900003703002002200429000037038801202941012001201a1b3a003c2024200229038801370000202320282903003700002019202729030037000020052026290300370000202920162029290320201ba722041b370320202941286a22012014200129030020041b3703002029201b202929031820041b37031802400240201d0d00201c21040c010b201d2101201c2104034020042802ec0321042001417f6a22010d000b0340201c201c2f01064102746a41ec036a280200211c201d417f6a221d0d000b0b201c2f010621012002201e3602a801200220013602a401200241003602a0012002201c36029c01200241003602980120024200370390012002200436028c012002410036028801200241f0016a20024188016a109901024020022802f0014101470d00202941306a211c0340200241900a6a41286a200341286a280200360200200b200341206a2902003703002006200341186a2204290200370300202a200341106a2201290200370300202b200341086a2205290200370300200220032902003703900a200241c0016a41186a2004290000370300200241c0016a41106a2001290000370300200241c0016a41086a2005290000370300200220032900003703c001200241e0016a41086a200b41086a2802003602002002200b2902003703e001200241b0016a201c200241c0016a200241e0016a10bd01024020022802b001450d0020022802b4012204450d0020022802b801450d002004102a0b200241f0016a20024188016a10990120022802f0014101460d000b0b20024188016a1095010c010b202941386a212b202941306a212a202928023821262029280230210402400240202941346a28020022050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b200220263602900220024100360288022002410036028002200242003703f801200220013602f401200241003602f0012002200436028402200220042f010636028c02200241f0016a109501202941286a201437030020292016370320202941106a2015370300202920173703082029201b37031820292007370300202a201d360204202a201c360200202b201e3602002029201a3a003c2029413d6a2002290368370000202941c5006a2025290300370000202941cd006a2024290300370000202941d5006a2023290300370000202920183b015e202920193a005d0b200241f0016a200210930120022903900222074202520d000b0b2002109b012000200028020041016a360200200241f00c6a24000f0b41a8b8c0004110200241f0016a41d0b8c0001038000bf00203027f017e037f230041306b22052400024002400240200241ff0171417e6a220641024b0d000240024020060e03000201000b200520011099022005290300200358200541086a290300220720045820072004511b0d010c020b200541106a20011099022005290310200356200541186a290300220720045620072004511b0d010b200541206a2001109a020240200528022822010d0002402005280224450d002005280220102a0b410021010c020b200141057421061098012108200528022421092005280220220a2101024002400240034002402008200141106a2802004f0d002001290300200358200141086a290300220720045820072004511b0d002001411c6a2d000020027141ff0171200241ff0171460d020b200141206a2101200641606a22060d000b4100210120090d010c020b4184dfc00021012009450d010b200a102a0b413121060c010b41dedec0002101412621060b2000200636020420002001360200200541306a24000bc31e03087f037e127f23004180076b22042400200441e0006a41186a200241186a290000370300200441e0006a41106a200241106a290000370300200441e0006a41086a200241086a290000370300200420022900003703600240024002400240024002400240024002402001280200220541f8b9c000460d00200128020421060c010b41002106200441e8026a410041e0021099051a200441c0016a41004184011099051a41ec0310282205450d01200541003b010620054100360200200541086a200441e8026a41e002109a051a200541e8026a200441c0016a418401109a051a20014100360204200120053602000b02400340200541086a2107200541066a210820052f0106220941057421024100210a0240024003402002450d01200441e0006a20074120109c05220b450d02200241606a2102200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200520094102746a41ec036a28020021050c010b0b200441e8026a41086a22022005200a410c6c6a220741f0026a220a2802003602002004200741e8026a22072902003703e80220072003290200370200200a200341086a280200360200200441c0016a41086a20022802002202360200200420042903e802220c3703c0012000410c6a20023602002000200c370204200041013602000c060b200441086a41186a220b200441e0006a41186a2202290300370300200441086a41106a200441e0006a41106a2207290300220c370300200441086a41086a200441e0006a41086a220a290300220d37030020042004290360220e3703082001200128020841016a3602082007200c370300200a200d3703002002200b2903003703002004200e370360200441d8026a41086a2206200341086a280200360200200420032902003703d802024020082f01002203410b490d00200441e8026a410041e0021099051a200441c0016a41004184011099051a41ec031028220f450d02200f41003b0106200f4100360200200f41086a200441e8026a41e002109a052107200f41e8026a200441c0016a418401109a05210a200441e8026a41086a220b200541b8036a280200360200200420052900db013703a8012004200541e0016a2900003700ad01200420052902b0033703e802200420052f00c8013b01bc012004200541ca016a2d00003a00be01200541cb016a2800002110200541cf016a2800002111200541d3016a2800002112200541d7016a28000021132007200541e8016a20052f010641796a2202410574109a052107200a200541bc036a2002410c6c109a05210a200541063b0106200f20023b0106200420042f01bc013b01a401200420042d00be013a00a601200420042903a8013703c001200420042900ad013700c501200441286a41086a200b280200360200200420042903e8023703280240024020094107490d00200941057420076a41c07e6a2007200941796a220b4105746a2207200241ffff0371200b6b410574109b051a200741186a200441e0006a41186a290300370000200741106a200441e0006a41106a290300370000200741086a200441e0006a41086a290300370000200720042903603700002009410c6c200a6a220241b87f6a200241ac7f6a2202200f41066a22082f0100200b6b410c6c109b051a200241086a200441d8026a41086a280200360200200220042903d8023702000c010b200541086a20094105746a220241206a200220082f010020096b410574109b051a200241186a200441e0006a41186a290300370000200241106a200441e0006a41106a290300370000200241086a200441e0006a41086a29030037000020022004290360370000200541e8026a2009410c6c6a2202410c6a200220082f010020096b410c6c109b051a200241086a200441d8026a41086a280200360200200220042903d8023702000b200820082f010041016a3b010020044198016a41026a220220042d00a6013a0000200441c8026a41086a2214200441286a41086a280200360200200420042f01a4013b019801200420042903c001370350200420042900c501370055200420042903283703c8022004413c6a41026a221520022d00003a0000200420042f0198013b013c2004200429005537002d20042004290350370328200441c0006a41086a22162014280200360200200420042903c80237034020052802002206450d0420052f01042103200441e8026a4102722117034020044194016a41026a221820152d00003a0000200420042f013c3b019401200420042903283703602004200429002d37006520044198016a41086a221920162802003602002004200429034037039801200341ffff0371210502400240024020062f01062202410b490d00201741004196041099051a419c041028220b450d07200b4100360200200b41046a200441e8026a419804109a051a200420062f00c8013b01bc012004200641ca016a2d00003a00be012004200641db016a2900003703a8012004200641e0016a2900003700ad01200641cb016a280000211a200641cf016a280000211b200641d3016a280000211c200641d7016a280000211d200441e8026a41086a221e200641b8036a2802003602002004200641b0036a2902003703e802200b41086a200641e8016a20062f0106220741796a2202410574109a05211f200b41e8026a200641bc036a2002410c6c109a052120200b41ec036a20064188046a2007417a6a2209410274109a052108200641063b0106200b20023b010602402009450d00410021022008210703402007280200220a20023b0104200a200b360200200741046a21072009200241016a2202470d000b0b200441d8026a41086a2202201e280200360200200420042d00be0122073a00a601200420042f01bc01220a3b01a401200420042903a8013703c001200420042900ad013700c501200420042903e8023703d802200441c4026a41026a220920073a00002004200a3b01c402200420042903c0013703e802200420042900c5013700ed0220142002280200360200200420042903d8023703c802200341ffff037122074107490d01201f2005417a6a220a4105746a201f200541796a22024105746a2207200b2f010620026b410574109b051a200741186a20042900653700002007201336000f2007201236000b2007201136000720072010360003200741026a20182d00003a0000200720042f0194013b0000200720042903603700132005410c6c20206a220741b87f6a200741ac7f6a2207200b2f0106220320026b410c6c109b051a200741086a20192802003602002007200429039801370200200b200341016a22073b01062005410274221020086a416c6a2008200a4102746a2203200741ffff03712205200a6b410274109b051a2003200f3602002005200a490d02200b20106a41d4036a210703402007280200220a200241016a22023b0104200a200b360200200741046a210720022005490d000c030b0b200641086a2207200541016a220a4105746a200720054105746a2207200220056b410574109b051a200741186a20042900653700002007201336000f2007201236000b2007201136000720072010360003200741026a20044194016a41026a2d00003a0000200720042f0194013b00002007200429036037001320062005410c6c6a220241f4026a200241e8026a220720062f0106220b20056b410c6c109b051a200241f0026a20044198016a41086a28020036020020072004290398013702002006200b41016a22023b01062005410274200641ec036a22076a41086a2007200a4102746a2207200241ffff0371220b200a6b410274109b051a2007200f360200200341ffff0371200b4f0d082006200a417f6a22024102746a41f0036a210703402007280200220a200241016a22023b0104200a2006360200200741046a21072002200b490d000c090b0b200641086a2202200541016a22034105746a200220054105746a220220062f010620056b410574109b051a200241186a20042900653700002002201336000f2002201236000b2002201136000720022010360003200241026a20182d00003a0000200220042f0194013b000020022004290360370013200641e8026a2005410c6c6a2202410c6a200220062f0106220a20056b410c6c109b051a200241086a201928020036020020022004290398013702002006200a41016a22023b010620054102742210200641ec036a220a6a41086a200a20034102746a2208200241ffff0371220a20036b410274109b051a2008200f3602002007200a4f0d00200620106a41f0036a2102034020022802002207200541016a22053b010420072006360200200241046a2102200a2005470d000b0b20044190016a41026a220220092d00003a000020044180016a41086a22072014280200360200200420042f01c402220a3b019001200420042903e802370350200420042900ed02370055200420042903c80237038001201520022d00003a00002004200a3b013c2004200429005537002d200420042903503703282016200728020036020020042004290380013703400240200628020022020d00201a2110201d2113201c2112201b2111200b210f0c060b20062f01042103201a2110201d2113201c2112201b211120022106200b210f0c000b0b200520094105746a220b41286a200b41086a2201200320096b410574109b051a200b41206a2002290300370000200b41186a2007290300370000200b41106a200a2903003700002001200429036037000020052009410c6c6a220241f4026a200241e8026a220720052f010620096b410c6c109b051a200241f0026a2006280200360200200720042903d802370200200520052f010641016a3b01060c040b41ec0341041037000b41ec0341041037000b419c0441041037000b200441e8026a41027241004196041099051a419c0410282202450d0220024100360200200241046a200441e8026a419804109a051a2002200128020022073602ec03200120023602002001200128020441016a360204200741003b010420072002360200200220022f0106220a4105746a220741086a20042f013c3b00002007410a6a2004413c6a41026a2d00003a0000200741176a2013360000200741136a20123600002007410f6a20113600002007410b6a20103600002007411b6a2004290328370000200741206a200429002d3700002002200a410c6c6a220741f0026a200441c0006a41086a280200360200200741e8026a2004290340370200200241ec036a200a41016a22074102746a200f360200200220073b0106200f20073b0104200f20023602000b200041003602000b20044180076a24000f0b419c0441041037000bc50101057f230041306b220124002000410c6a28020021022000280204210302400240200041086a28020022040d00200321000c010b2004210520032100034020002802880b21002005417f6a22050d000b0340200320032f01064102746a41880b6a28020021032004417f6a22040d000b0b200141246a20032f0106360200200141206a41003602002001411c6a20033602002001200236022820014100360218200142003703102001200036020c20014100360208200141086a109b01200141306a24000bcb0401097f230041c0006b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a280200210602400240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d01200220084120109c05220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a220841e8026a210502400240200841c5036a2d00000d00200341206a41086a220a200541c5006a290000370300200341206a41106a220b200541cd006a290000370300200341206a41186a2207200541d5006a29000037030020032005413d6a2900003703204102210820052d003c4101470d01200341186a2007290300370300200341106a200b290300370300200341086a200a29030037030020032003290320370300410121080c010b200341086a200541c5006a290000370300200341106a200541cd006a290000370300200341186a200541d5006a29000037030020032005413d6a29000037030020052d003c21080b200841ff01714102470d010b200020012802102002200141146a280200280210110500200128020021040c010b200020083a000020002003290300370001200041096a200341086a290300370000200041116a200341106a290300370000200041196a200341186a2903003700000b20012004417f6a360200200341c0006a24000f0b41b8b8c0004118200341206a41e0b8c0001038000be80202097f027e230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a28020021060240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d01200220084120109c05220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a220541c5036a310000200541e8026a290300220c200c5022081ba7450d004200200541f8026a29030020081b210c4200200541f0026a29030020081b210d0c010b200341086a20012802102002200141146a28020028021c110500200341106a290300210c200128020021042003290308210d0b20012004417f6a3602002000200c3703082000200d370300200341206a24000f0b41b8b8c0004118200341186a41e0b8c0001038000ba62a020c7f037e230022072108200741800f6b41607122072400200720043703382007200337033020072005360244024002400240024002402001280230200128024022092802b801460d002005420020052903082203200941386a2903007d2204200420035622091b37030820090d0120074180046a20024100410110c201200741a4046a280200210a200741a0046a280200210b20072d008804220541037122094103460d0220090e03030203030b200041d4c5c00036020420004101360200200041086a41293602002000410c6a2006290200370200200041146a200641086a2802003602000c030b200041fdc5c00036020420004101360200200041086a41233602002000410c6a2006290200370200200041146a200641086a280200360200200824000f0b200041a0c6c00036020420004101360200200041086a41193602002000410c6a2006290200370200200041146a200641086a28020036020020050d01200a450d01200b102a200824000f0b200741a8046a2802002109200741c8006a41186a220c200141e8006a290000370300200741c8006a41106a220d200141e0006a290000370300200741c8006a41086a220e200141d8006a290000370300200720012900503703484100210f4100211002400240024002400240024002400240024002400240024002400240024020050d002009417f4c0d010240024020090d002007420037038004410121100c010b200910282210450d03200741003602840420072009360280040b20072009360284042010200b2009109a051a2007290380042103200a450d00200b102a0b200741a4016a410036020020074194016a419cc4c000360200200741e8006a41206a420037030020074184016a41f8b9c000360200200741e8006a41106a2003370300200741e8006a41d8006a200241086a290000370300200741e8006a41e0006a200241106a290000370300200741e8006a41e8006a200241186a29000037030020072001360270200741e8006a41286a200141186a22113602002007420837029c01200741003602800120072010360274200720022900003703b801200720012802483602b001200720012903403703a8012007200128023041016a36029801200129030021032007200128024c3602b40120072003370368200741d8016a41206a200e290300370300200741d8016a41286a200d29030037030020074188026a200c290300370300200741ec016a200641086a280200360200200720023602e001200720072903483703f001200720062902003702e4012007200741c4006a3602dc012007200741306a3602d8010240024020072903302203200741306a41086a290300220484500d00200741286a20072802444100200741f0016a200220032004200741e8006a10b801200728022822060d01200728028001210f20072802e00121020b200f41016a220d41004c0d03200741d8016a41186a210e200741e4016a210f2007200d36028001200741e8006a41206a280200210a20074184016a2212210602400240024003402006280200220b41086a2105200b2f0106220c4105742106410021090240024003402006450d01200220054120109c052210450d02200641606a2106200941016a2109200541206a21052010417f4a0d000b2009417f6a210c0b200a450d02200a417f6a210a200b200c4102746a41880b6a21060c010b0b200b200941e0006c6a220541e8026a210602400240200541c5036a2d00000d0020074180046a41086a2209200641c5006a29000037030020074180046a41106a2210200641cd006a29000037030020074180046a41186a220b200641d5006a29000037030020072006413d6a290000370380044102210520062d003c4101470d01200741a00c6a41186a200b290300370300200741a00c6a41106a2010290300370300200741a00c6a41086a200929030037030020072007290380043703a00c410121050c010b200741a80c6a200641c5006a290000370300200741b00c6a200641cd006a290000370300200741b80c6a200641d5006a29000037030020072006413d6a2900003703a00c20062d003c21050b200541ff01714102470d010b20074190026a2007280290012002200728029401280210110500200728028001210d20072d00900221050c010b20074199026a200741a80c6a290300370000200741a1026a200741b00c6a290300370000200741a9026a200741b80c6a290300370000200720053a009002200720072903a00c370091020b2007200d417f6a360280014101210a0240200541ff01714101470d00200741b8026a41186a200741a9026a290000370300200741b8026a41106a200741a1026a290000370300200741b8026a41086a20074199026a29000037030020072007290091023703b80220074180046a200741b8026a20072802b00128020010b90102402007280280044101470d0020072902e4012203422088a7210520074180046a41086a28020021092007280284042106200741ec016a28020021102003a721020c100b200741a00c6a41186a220520074180046a410472220641186a2802002209360200200741d8026a41106a200641086a290200370300200741d8026a41186a200641106a290200370300200741f8026a2009360200200741043602dc02200741af8dc6003602d802200720062902003703e00220072802ac0121062005200e41186a2900002203370300200741a00c6a41106a200e41106a2900002204370300200741a00c6a41086a2205200e41086a2900002213370300200741a8046a2013370300200741b0046a2004370300200741b8046a20033703002007200e29000022033703a00c200720033703a00420072802d801220941086a29030021032007200741e8006a36029804200929030021042007290368211320072802b4012109200720033703880420072004370380042007200936029c0420072013370390042005200f41086a2802003602002007200f2902003703a00c200741e0036a2006200741d8026a20074180046a200741a00c6a20072802dc0128020010ba01200741ec036a2902002103200741e0036a41086a280200210c20072802e403210a024020072802e0034101470d002003422088a72105200741f4036a28020021102003a72102200c2109200a21060c0f0b20072802800141016a220f41004c0d0520072802e00121022007200f36028001200728028801210d201221060240024003402006280200220b41086a2105200b2f0106220e4105742106410021090240024003402006450d01200220054120109c052210450d02200641606a2106200941016a2109200541206a21052010417f4a0d000b2009417f6a210e0b200d450d02200d417f6a210d200b200e4102746a41880b6a21060c010b0b200b200941e0006c6a220641c5036a310000200641e8026a290300220420045022051ba7450d004200200641f8026a29030020051b21044200200641f0026a29030020051b21130c010b200741186a200728029001200220072802940128021c110500200741206a290300210420072903182113200728028001210f0b2007200f417f6a221036028001201320072802a801220629037854200420064180016a29030022135420042013511b0d060c070b4100210c420021030240200741e8016a280200450d0020072802e401102a0b420021040c070b200728022c210920072902e4012203422088a721052003a72102200741ec016a28020021100c0d0b1036000b200941011037000b41b8b8c000411820074180046a41e0b8c0001038000b41b8b8c000411820074180046a41e0b8c0001038000b20072802702206450d020240024020072802e0012205200641d0006a2209460d00200920054120109c05450d00034020062802082206450d022005200641d0006a2209460d01200920054120109c050d000b0b2003a7211041b9c6c000210641372109200c2105200a21020c080b20100d032007417f36028001200741003a00bc03200742003702b403200741013a009d03200741f8b9c0003602b003200741e0036a41186a200541186a290000370300200741e0036a41106a200541106a290000370300200741e0036a41086a200541086a290000370300200720052900003703e00302400240200728028401221041f8b9c000460d00200728028801210b0c010b200741a00c6a410041e0021099051a20074180046a410041a0081099051a41880b10282210450d054100210b201041003b010620104100360200201041086a200741a00c6a41e002109a051a201041e8026a20074180046a41a008109a051a200741003602880120072010360284010b02400240034020102f0106220d4105742102410021064100210502400240034020022006460d01200741e0036a201020066a41086a4120109c052209450d02200641206a2106200541016a21052009417f4a0d000b2005417f6a210d0b200b450d02200b417f6a210b2010200d4102746a41880b6a28020021100c010b0b2010200541e0006c6a22064190036a20072903a80337030020064188036a20072903a003370300200641c0036a200729039803370000200641b8036a200729039003370000200641b0036a200729038803370000200641a8036a20072903800337000020064180036a4200370300200641e8026a2205290300211320054200370300200641a0036a22052802002102200520072903b80337030020064198036a22062903002104200620072903b0033703002004a721062004422088a721050c010b200741c0036a41186a200741e0036a41186a2903002204370300200741c0036a41106a200741e0036a41106a2903002213370300200741c0036a41086a200741e0036a41086a2903002214370300200720072903e00322153703c003200741bc0c6a2014370200200741a00c6a41246a2013370200200741cc0c6a20043702002007200741e8006a41246a3602b00c2007200d3602ac0c200720123602a80c200720103602a40c200741003602a00c200720153702b40c20074180046a41186a42003703002007420037038004200741b8046a20072903b803370300200741b0046a20072903b003370300200741a8046a20072903a803370300200741a0046a20072903a003370300200741d8046a200729039803370300200741d0046a200729039003370300200741c8046a200729038803370300200741c0046a200729038003370300200741a00c6a20074180046a10b7011a420221130b024020134202510d000240024020050d00200621090c010b2005211020062109034020092802ec0321092010417f6a22100d000b0340200620062f01064102746a41ec036a28020021062005417f6a22050d000b0b2007419c046a20062f010636020020074198046a410036020020074194046a2006360200200720023602a004200741003602900420074200370388042007200936028404200741003602800420074180046a1095010b200720072802800141016a360280010b0240200741f0026a280200450d00200741ec026a280200102a0b200342ffffffff0f83210420034280808080708321030b20072802a401210520072802a001210d200728029c01210b200728028c01210e20072802880121102007280284012106024020072802742209450d00200741f8006a280200450d002009102a0b200420038421040240024020034280808080f01f8350450d002007200e3602880420072010360284042007200636028004201120074180046a10bb012007200d360284042007200b360280042007200b200541b0016c22056a220236028c0402400240200141386a28020022092001413c6a28020022066b200541b0016d2210490d00200128023421090c010b200620106a220d2006490d0720094101742206200d2006200d4b1b2206ad42b0017e2203422088a70d072003a7220d4100480d070240024020090d00200d102821090c010b2001280234200941b0016c200d102c21090b2009450d0620012009360234200141386a20063602002001413c6a28020021060b2009200641b0016c6a200b2005109a051a2001413c6a2206200628020020106a360200200720023602880420074180046a10692000410c6a2004370200200041086a200c3602002000200a3602040c010b2000200a3602042000410c6a2004370200200041086a200c36020002402005450d00200541b0016c210141002105034002400240200b20056a22092d0000220241014b0d000240024020020e020001000b0240200941086a280200450d00200941046a280200102a0b200941106a2d00004105490d02200941386a280200450d02200941346a280200102a0c020b200941286a106a0c010b200941e8006a280200450d00200941e4006a280200102a0b2001200541b0016a2205470d000b0b0240200d450d00200b102a0b0240024020100d00200621050c010b2010210920062105034020052802880b21052009417f6a22090d000b0340200620062f01064102746a41880b6a28020021062010417f6a22100d000b0b2007419c046a20062f010636020020074198046a410036020020074194046a20063602002007200e3602a004200741003602900420074200370388042007200536028404200741003602800420074180046a109b010b20004100360200200824000f0b41f0c6c00041321050000b41a8b8c000411020074180046a41d0b8c0001038000b41880b41081037000b200d41081037000b1031000b200741f0026a280200450d00200741ec026a280200102a0b2000200636020420004101360200200041146a2010360200200041086a20093602002000410c6a2005ad4220862002ad84370200024020072802742206450d00200741f8006a280200450d002006102a0b200741e8006a411c6a2802002106200728028c0121000240024020072802880122050d00200621090c010b2005211020062109034020092802880b21092010417f6a22100d000b0340200620062f01064102746a41880b6a28020021062005417f6a22050d000b0b20074180046a411c6a20062f01063602004100210520074198046a410036020020074194046a2006360200200720003602a004200741003602900420074200370388042007200936028404200741003602800420074180046a109b01024020072802a4012206450d00200728029c012110200641b0016c2100034002400240201020056a22062d0000220941014b0d000240024020090e020001000b0240200641086a280200450d00200641046a280200102a0b200641106a2d00004105490d02200641386a280200450d02200641346a280200102a0c020b200641286a106a0c010b200641e8006a280200450d00200641e4006a280200102a0b2000200541b0016a2205470d000b0b20072802a001450d00200728029c01102a200824000f0b200824000b871304057f027e0a7f077e230041f0026b22042400200441d0006a2001108c010240024020042d00502205417f6a41ff017141024f0d00200041003a0000200041086a200441d0006a41d800109a051a0c010b200441a8016a41086a2206200441d0006a413c6a290200370300200441a8016a41106a2207200441d0006a41c4006a290200370300200441a8016a41186a2208200441d0006a41cc006a2902003703002004200441d0006a41346a2902003703a801200441d0006a41106a2903002109200441d0006a41086a290300210a200441d0006a41306a280200210b200441d0006a412c6a280200210c200441d0006a41246a280200210d200441d0006a41206a280200210e200441ec006a280200210f200441d0006a41186a2802002110200441d0006a41d4006a2802002111200441d0006a41286a28020021120240024002400240024002400240024002400240024041004100109801221320026b2202200220134b1b220220126b2214201420024b1b2214450d00200441c0006a2001109101200441306a20042903402215200441c0006a41086a2903002216428080a8ec85afd1b101420010a0054200200dad2217200429033022187d221920192017564200200441306a41086a2903002017201854ad7c7d22174200522017501b22021b22184200201720021b221784500d042015428080d287e2bc2d5441002016501b0d01200441186a2014ad420020182017109f05200441086a2004290318200441186a41086a290300428080e983b1de164200109f05200441286a20014108420020152015428080aef89dc3527c2217200a200a201756200920162017201554ad7c427f7c22175620092017511b22021b22182004290308221920182019542017200920021b2218200441086a41086a29030022175420182017511b22021b221a7d221b201b20155620162018201720021b22187d2015201a54ad7d221520165620152016511b22141b4200201520141b10bc010240024020042802280d000240024020020d002003450d010b20044188026a2001201a201841081098022004280288024101460d08200420044198026a2903003703f001200420044188026a41086a2903003703e8012004200441e8016a3602880220044188026a109d010b20020d0020030d01200041003a0008200041023a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903a801370000200041c4006a200441b0016a290300370000200041cc006a200441a8016a41106a290300370000200041d4006a200441a8016a41186a290300370000200041dc006a2011360000200541037122004103460d0520000e030d05050d0b20044100360288022010200e20044188026a100d21142004280288022213417f460d07200441e8016a41186a200441a8016a41186a290300370300200441e8016a41106a200441a8016a41106a290300370300200441e8016a41086a200441a8016a41086a290300370300200420042903a8013703e801200441003602e802200442013703e00220142013200441e0026a10b2020240024020042802e402220320042802e802220d6b4120490d00200d41206a211220042802e00221020c010b200d41206a2212200d490d0a200341017422022012200220124b1b220b4100480d0a0240024020030d00200b102821020c010b20042802e0022003200b102c21020b2002450d092004200b3602e402200420023602e002200b21030b200420123602e8022002200d6a220d20042903e801370000200d41086a200441e8016a41086a290300370000200d41106a200441e8016a41106a290300370000200d41186a200441e8016a41186a29030037000020044188026a41186a220d420037030020044188026a41106a220b420037030020044188026a41086a220c420037030020044200370388022002201220044188026a1000200441c8016a41186a2212200d290300370300200441c8016a41106a220d200b290300370300200441c8016a41086a220b200c29030037030020042004290388023703c80102402003450d002002102a0b200441a1026a201229030037000020044199026a200d29030037000020044191026a200b290300370000200420042903c80137008902200441013a008802200120044188026a10b3022010200e1004200041013a0000200041086a20044188026a41d800109a051a2013450d032014102a0c030b200441b8026a200b360200200441b4026a200c360200200441b0026a2013360200200441ac026a200d360200200441a8026a200e360200200441a4026a200f36020020044188026a41186a2010360200200441bc026a20042903a801370200200441c4026a200441a8016a41086a290300370200200441cc026a200441a8016a41106a290300370200200441d4026a200441a8016a41186a29030037020020044188026a41106a200920177d200a201954ad7d370300200441003a0088022004200a20197d37039002200120044188026a10b302200041023a0000200041086a20044188026a41d800109a051a0c090b200041003a0008200041003a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903a801370000200041c4006a2006290300370000200041cc006a2007290300370000200041d4006a2008290300370000200041dc006a20113600000c080b20011096012010200e1004200041023a0008200041013a00000b200f450d062010102a0c060b200f450d070c060b200041003a0008200041003a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903a801370000200041c4006a200441b0016a290300370000200041cc006a200441a8016a41106a290300370000200041d4006a200441a8016a41186a290300370000200041dc006a20113600000c040b2004200429028c023703e80141f896c10041fe00200441e8016a41f897c1001038000b41eef3c50041381050000b200b41011037000b1031000b0240200541037122004103460d0020000e03020000020b200f450d010b2010102a0b200441f0026a24000be20d03047f017e027f230041106b2202240020024100360208200242013703000240024002400240024002400240024002400240024002400240024002402001280200220341044b0d000240024002400240024020030e050001020304000b410110282203450d05200242818080801037020420022003360200200341013a0000200128020421042001410c6a2802002203200210b40102402003450d002004200341286c6a2105034020042002108f01200441206a29030021060240024020022802042207200228020822036b4108490d00200228020021070c010b200341086a22082003490d15200741017422032008200320084b1b22034100480d150240024020070d002003102821070c010b200228020020072003102c21070b2007450d092002200336020420022007360200200228020821030b2002200341086a360208200720036a20063700002005200441286a2204470d000b0b200141106a28020021070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d13200441017422032008200320084b1b22034100480d130240024020040d002003102821040c010b200228020020042003102c21040b2004450d082002200336020420022004360200200228020821030b2002200341046a360208200420036a20073600000c040b410110282203450d07200242818080801037020420022003360200200341023a0000200128020421070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d12200441017422052008200520084b1b22084100480d120240024020040d002008102821040c010b200228020020042008102c21040b2004450d0920022008360204200220043602000b2002200341046a360208200420036a200736000020012802082104200141106a2802002203200210b40102402003450d002004200341286c6a2105034020042002108f01200441206a29030021060240024020022802042207200228020822036b4108490d00200228020021070c010b200341086a22082003490d14200741017422032008200320084b1b22034100480d140240024020070d002003102821070c010b200228020020072003102c21070b2007450d0c2002200336020420022007360200200228020821030b2002200341086a360208200720036a20063700002005200441286a2204470d000b0b200141146a28020021070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d12200441017422032008200320084b1b22034100480d120240024020040d002003102821040c010b200228020020042003102c21040b2004450d0b2002200336020420022004360200200228020821030b2002200341046a360208200420036a20073600000c030b410110282203450d0a200242818080801037020420022003360200200341033a0000200141086a29030021060240024020022802042207200228020822036b4108490d00200341086a2104200228020021070c010b200341086a22042003490d11200741017422082004200820044b1b22084100480d110240024020070d002008102821070c010b200228020020072008102c21070b2007450d0c20022008360204200220073602000b20022004360208200720036a20063700000c020b410110282203450d0b200242818080801037020420022003360200200341043a0000200128020421070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d10200441017422012008200120084b1b22084100480d100240024020040d002008102821040c010b200228020020042008102c21040b2004450d0d20022008360204200220043602000b2002200341046a360208200420036a20073600000c010b410110282203450d0c200242818080801037020420022003360200200341053a0000200128020421080240024020022802042207200228020822036b4104490d00200341046a2104200228020021070c010b200341046a22042003490d0f200741017422012004200120044b1b22014100480d0f0240024020070d002001102821070c010b200228020020072001102c21070b2007450d0e20022001360204200220073602000b20022004360208200720036a20083600000b20002002290300370200200041086a200241086a280200360200200241106a24000f0b410141011037000b200341011037000b200341011037000b410141011037000b200841011037000b200341011037000b200341011037000b410141011037000b200841011037000b410141011037000b200841011037000b410141011037000b200141011037000b1031000bfb0101077f230041106b220124002001410036020820014201370300200110c40120012802042102200128020021030240024002400240200041046a2802002204200041086a28020022056b20012802082206490d00200028020021040c010b200520066a22072005490d02200441017422052007200520074b1b22054100480d020240024020040d002005102821040c010b200028020020042005102c21040b2004450d0120002004360200200041046a2005360200200041086a28020021050b200041086a200520066a360200200420056a20032006109a051a02402002450d002003102a0b200141106a24000f0b200541011037000b1031000ba5900108027f017e0b7f037e2f7f027e057f0e7e23004190106b220224000240024002400240024002400240024002400240024002400240200141106a2802002203ad42d0007e2204422088a70d002004a72205417f4c0d00200128020821060240024002400240024002400240024020050d00410821070c010b200510282207450d010b0240024020030d00410021080c010b2006200341d0006c6a2109410021082007210a0340200241c8046a41186a220b200641186a290300370300200241c8046a41106a220c200641106a290300370300200241c8046a41086a220d200641086a290300370300200220062903003703c8042006280248220ead42307e2204422088a70d082004a7220f417f4c0d08200641386a2903002104200641286a290300211020062903302111200629032021122006280240210502400240200f0d00410821130c010b200f10282213450d040b200641d0006a210602400240200e0d00410021140c010b2005200e41306c6a2115410021142013210f0340200f2005290300370300200f200541086a290300370308200f41106a200541106a290300370300200f41186a200541186a290300370300200f41206a200541206a290300370300200f41286a200541286a290300370300200f41306a210f201441016a2114200541306a22052015470d000b0b200a2012370320200a20022903c804370300200a41386a2004370300200a41306a2011370300200a41286a2010370300200a41c8006a2014360200200a41c4006a200e360200200a41c0006a2013360200200a41186a200b290300370300200a41106a200c290300370300200a41086a200d290300370300200841016a2108200a41d0006a210a20062009470d000b0b200028020821162000280204211720002802002118200128020421192001280200210b41041028221a450d02201a200b36000020024284808080c0003702bc072002201a3602b807411b10282205450d03200541176a41002800f39646360000200541106a41002900ec9646370000200541086a41002900e49646370000200541002900dc96463700002002429b808080b00337028c08200220053602880841a2c7c00020024188086a10c601200228029008210f2002280288082105200241c8046a41186a22144200370300200241c8046a41106a22154200370300200241c8046a41086a22064200370300200242003703c8042005200f200241c8046a1000200241b00f6a41186a2014290300370300200241b00f6a41106a2015290300370300200241b00f6a41086a2006290300370300200220022903c8043703b00f0240200228028c08450d002005102a0b2002410036028808200241b00f6a412020024188086a100621142002280288082215417f460d042014450d042002201536028c082002201436028808200241d0026a20024188086a106c02400240024020022802d0020d00200228028c08220620022802d402220f490d00200f417f4c0d0902400240200f0d00410121050c010b200f102e2205450d022005200228028808220a200f109a051a20022006200f6b36028c082002200a200f6a360288080b20050d020b41c4d1c3004133200241f8056a419cd9c3001038000b200f41011037000b200fad220442208620048421042015450d052014102a0c050b200541081037000b200f41081037000b410441011037000b411b41011037000b410021050b20022005410120051b22133602b00f20022004420020051b22104220883e02b40f200241c8026a200241b00f6a106c20022802cc02210e41002106024020022802c8020d0020022802b40f220541246e220a41246c220f417f4c0d0102400240024002400240200f0d00410421060c010b200f10282206450d010b200e450d034100210c034020054104490d03200c41016a210d20022005417c6a22143602b40f200220022802b00f221541046a3602b00f2015280000210941002105200241003a00a8080340024020142005470d00200241003602b40f200541ff0171450d05200241003a00a8080c050b20024188086a20056a201520056a220f41046a2d00003a00002002200f41056a3602b00f2002200541016a220f3a00a808200f2105200f4120470d000b200241c8046a41086a221520024188086a41086a290300370300200241c8046a41106a220020024188086a41106a290300370300200241c8046a41186a221b20024188086a41186a29030037030020022002290388083703c80420022014200f6b22053602b40f0240200a200c470d00200c410174220f200d200f200d4b1b220aad42247e2204422088a70d122004a7220f4100480d1202400240200c0d00200f102821060c010b2006200c41246c200f102c21060b2006450d030b2006200c41246c6a220f2009360200200f20022903c804370204200f410c6a2015290300370200200f41146a2000290300370200200f411c6a201b290300370200200d210c200d200e470d000c040b0b200f41041037000b200f41041037000b0240200a0d00410021060c010b2006102a410021060b200241b00f6a200241b8076a10c70120022802b80f210f20022802b00f210520024100360288082005200f20024188086a1006210f024002402002280288082214417f460d00200f450d00200220143602dc062002200f3602d80620024188086a200241d8066a106d0240200228028808221c450d00200229028c0821042014450d02200f102a0c020b41c4d1c3004133200241f8056a419cd9c3001038000b420021044101211c0b024020022802b40f450d002005102a0b2004422088211102402010a7450d002013102a0b200e410020061b211d200a410020061b211e2006410420061b210c2011a7211f2004a72120200242003702dc02200241f8b9c0003602d8022007200841d0006c6a21210240024020080d00200721130c010b200241b8036a41306a212220024188086a410c6a212320164101742205201641ffffff3f712224200520244b1b222541ffffff3f71202547212620254105742127202420164721282016410574222941606a41057641016a212a20024188086a41306a212b20024188086a41206a212c20024188086a410272212d20024198056a41046a212e20024188086a41c0006a212f200241b00f6a41106a2130200241b8076a4104722131200241b8036a41c4006a21322018201820296a4621332007211302400240034020024188086a41386a22062013220541386a290300370300202b200541306a29030037030020024188086a41286a220a200541286a290300370300202c200541206a29030037030020024188086a41186a2234200541186a29030037030020024188086a41106a2235200541106a29030037030020024188086a41086a2236200541086a290300370300200241b00f6a41086a221b200541cc006a28020036020020022005290300370388082002200541c4006a2902003703b00f200541d0006a2113200541c0006a2802002205450d03200241f8026a41386a220f2006290300370300200241f8026a41306a2214202b290300370300200241f8026a41286a2215200a290300370300200241f8026a41206a220e202c290300370300200241f8026a41186a220d2034290300370300200241f8026a41106a22092035290300370300200241f8026a41086a22002036290300370300200241e8026a41086a2237201b28020036020020022002290388083703f802200220022903b00f3703e802200241b8036a41386a2238200f29030037030020222014290300370300200241b8036a41286a22392015290300370300200241b8036a41206a2215200e290300370300200241b8036a41186a223a200d290300370300200241b8036a41106a223b2009290300370300200241b8036a41086a223c2000290300370300200220022903f8023703b803200220053602f803203220022903e802370200203241086a20372802003602000240024002400240024002400240410410282214450d002014200b360000202341002900a2c740370000202341086a41002900aac74037000020024284808080c00037028c0820022014360288082002200241b8036a3602a408410810282205450d01200242083702b40f200220053602b00f2023200241b00f6a10c6014104200241b00f6a10b4010240024020022802b40f220f20022802b80f22056b4104490d0020022802b00f210f0c010b200541046a220e2005490d18200f4101742205200e2005200e4b1b22054100480d1802400240200f0d0020051028210f0c010b20022802b00f200f2005102c210f0b200f450d03200220053602b40f2002200f3602b00f20022802b80f21050b2002200541046a3602b80f200f20056a2014280000360000200241b8036a200241b00f6a108f01200220153602b807200241b8076a200241b00f6a10a301200220223602b807200241b8076a200241b00f6a10a30120022802f8032105200228028004220f200241b00f6a10b4010240200f450d00200f41306c210f0340200541106a200241b00f6a108f01200220053602b807200541306a2105200241b8076a200241b00f6a10a301200f41506a220f0d000b0b20022802b40f210f20022802b80f211520022802b00f2105200241c8046a41186a220d4200370300200241c8046a41106a22094200370300200241c8046a41086a22004200370300200242003703c80420052015200241c8046a100020024188046a41186a223d200d29030037030020024188046a41106a223e200929030037030020024188046a41086a223f2000290300370300200220022903c804370388040240200f450d002005102a0b2014102a411010282205450d032005410029008ab7402204370000200541086a4100290092b740221037000020024290808080800237028c082002200536028808200220024188086a3602b80720024188046a200241b8076a10c8012002280288082105200228029008210f200d42003703002009420037030020004200370300200242003703c8042005200f200241c8046a1000200241b00f6a41186a2240200d29030037030020302009290300370300201b2000290300370300200220022903c8043703b00f0240200228028c08450d00200228028808102a0b200241b00f6a41204101410041001003417f460d050c040b410441011037000b410841011037000b200541011037000b411041011037000b20022802fc03450d0120022802f803102a0c010b200241a8046a41186a2241203a290300370300200241a8046a41106a223a203b290300370300200241a8046a41086a223b203c290300370300200220022903b8033703a804200228028004220ead42307e2211422088a70d052011a7220f417f4c0d05203829030021112039290300211220022903e803214220022903d803214320022802f8032105024002400240024002400240024002400240024002400240200f0d00410821370c010b200f10282237450d010b02400240200e0d00410021140c010b2005200e41306c6a2115410021142037210f0340200f2005290300370300200f200541086a290300370308200f41106a200541106a290300370300200f41186a200541186a290300370300200f41206a200541206a290300370300200f41286a200541286a290300370300200f41306a210f201441016a2114200541306a22052015470d000b0b200241b00f6a41386a2011370300200241b00f6a41286a2012370300204020412903003703002030203a290300370300201b203b290300370300200220423703e00f200220433703d00f200220022903a8043703b00f200220143602f80f2002200e3602f40f200220373602f00f0240024020022802d802220541f8b9c000460d0020022802dc02210f0c010b20024188086a410041f0061099051a41f80610282205450d024100210f200541003b010620054100360200200541086a20024188086a41f006109a051a200241003602dc02200220053602d8020b2002200536028c082002200f360288082002200241d8026a36029008200241b8076a20024188086a200241b00f6a10c901024020022802b8074101470d00202f20312902003702002036203041086a2903003703002035203041106a2903003703002034203041186a290300370300202c203041206a290300370300200a203041286a290300370300202b203041306a2903003703002006203041386a290300370300202f41086a203141086a290200370200200220302903003703880820022802bc0f2115202e41086a220f201b280200360200202e20022903b00f370200200241c8046a20024188086a41d000109a051a200241a8056a200241c8046a41d000109a051a200220022802e00241016a3602e00220022802f005214120022802f405211420022802ec052105200241d8066a41086a22442000290300370300200241d8066a41106a220e2009290300370300200241d8066a41186a2237200d290300370300200241d8066a41206a2239200241c8046a41206a290300370300200241d8066a41286a223a200241c8046a41286a290300370300200241d8066a41306a223b200241c8046a41306a290300370300200241d8066a41386a223c200241c8046a41386a290300370300200241c8066a41086a2245200f280200360200200220022903c8043703d8062002202e2902003703c80620052f01062238410b490d0520024188086a410041f0061099051a41f80610282238450d03203841003b010620384100360200203841086a20024188086a41f006109a05210f20024188086a4108200541086a2246200541f8b9c0004622471b224841e0036a41d000109a051a200f204841b0046a20052f010641796a224841d0006c109a05210f200541063b0106203820483b0106200241b00f6a20024188086a41d000109a051a0240024020144107490d00201441d0006c4108200f203841f8b9c0004622061b6a220f41a07c6a200f41d07b6a220f4100204841ffff037120061b20146b41d0006c41b0046a109b051a200f201536020c200f41086a2045280200360200200f20022903c806370300200f20022903d806370310200f41186a2044290300370300200f41206a200e290300370300200f41286a2037290300370300200f41306a2039290300370300200f41386a203a290300370300200f41c0006a203b290300370300200f41c8006a203c290300370300203820382f010641016a3b01060c010b4108210f200241a8076a41086a200241c8066a41086a28020036020020024188086a41086a200241d8066a41086a2903003703002035200e29030037030020342037290300370300202c2039290300370300200a203a290300370300202b203b2903003703002006203c290300370300200220022903c8063703a807200220022903d80637038808024002402047450d004100210e0c010b20052f0106210e2046210f0b200f201441d0006c6a220f41d0006a200f200e20146b41d0006c109b051a200f201536020c200f41086a200241a8076a41086a280200360200200f20022903a807370300200f200229038808370310200f41186a2036290300370300200f41206a2035290300370300200f41286a2034290300370300200f41306a202c290300370300200f41386a200a290300370300200f41c0006a202b290300370300200f41c8006a2006290300370300200520052f010641016a3b01060b200241b8076a200241b00f6a41d000109a051a200241f8056a200241b8076a41d000109a051a2005280200220e450d0620052f010421370340200241d8066a200241f8056a41d000109a051a203741ffff0371210602400240024002400240200e2f01062205410b490d00202d410041a2071099051a41a80710282215450d0a20154100360200201541046a20024188086a41a407109a051a20024188086a4108200e41086a223b200e41f8b9c00046223c1b220541e0036a41d000109a051a201541086a223a200541b0046a200e2f0106220541796a220f41d0006c109a051a201541f8066a200e4194076a2005417a6a220a410274109a052139200e41063b01062015200f3b01060240200a450d00410021052039210f0340200f280200221420053b010420142015360200200f41046a210f200a200541016a2205470d000b0b200241b00f6a20024188086a41d000109a051a200241b8076a200241b00f6a41d000109a051a203741ffff037122054107490d0320024188086a200241d8066a41d000109a051a200641796a210541f8b9c0002114201541f8b9c000470d014108213a4100210a0c020b4108200e41086a200e41f8b9c0004622141b200641d0006c6a220f41d0006a200f4100200520141b20066b41d0006c109b051a200f200241d8066a41d000109a051a200e200e2f010641016a220f3b01062006410274200e41f8066a22146a41086a2014200641016a22054102746a2214200f41ffff0371220f20056b410274109b051a201420383602002006200f4f0d0c203820053b01042038200e3602002005200f4f0d0c200f417f6a2115200e2005417f6a22054102746a4180076a210f0340200f2802002214200541026a3b01042014200e360200200f41046a210f2015200541016a2205470d000c0d0b0b20152f0106210a201521140b203a2006417a6a220f41d0006c6a203a200541d0006c6a2237200a20056b41d0006c109b051a203720024188086a41d000109a051a201520152f010641016a220a3b01062006410274223720396a416c6a2039200f4102746a2206200a41ffff0371200f6b410274109b051a20062038360200200f20142f010622064b0d01201520376a41e0066a210f0340200f2802002214200541016a22053b010420142015360200200f41046a210f20052006490d000c020b0b200e41f8066a210f20024188086a200241d8066a41d000109a051a02400240203c450d004108213b4100210a0c010b200e2f0106210a0b203b200641d0006c6a221441d0006a2014200a20066b41d0006c109b051a201420024188086a41d000109a051a200e200e2f010641016a22143b010620064102742237200f6a41086a200f200641016a220a4102746a220f201441ffff0371200a6b410274109b051a200f20383602002005200e2f010622144f0d00200e20376a41fc066a210503402005280200220f200641016a22063b0104200f200e360200200541046a210520142006470d000b0b200241f8056a200241b8076a41d000109a051a0240200e28020022050d00201521380c080b200e2f010421372005210e201521380c000b0b20024198056a41086a203141086a2902003703002002203129020037039805200e450d062037102a0c060b200f41081037000b41f80641081037000b41f80641081037000b41a80741081037000b4108200541086a200541f8b9c0004622061b201441d0006c6a220f41d0006a200f4100203820061b20146b41d0006c109b051a200f201536020c200f41086a2045280200360200200f20022903c806370300200f20022903d806370310200f41186a2044290300370300200f41206a200e290300370300200f41286a2037290300370300200f41306a2039290300370300200f41386a203a290300370300200f41c0006a203b290300370300200f41c8006a203c290300370300200520052f010641016a3b01060c010b202d410041a2071099051a41a80710282205450d0120054100360200200541046a20024188086a41a407109a051a20052041280200220f3602f806204120053602002041204128020441016a360204200f41003b0104200f20053602004108200541086a200541f8b9c000461b20052f0106220f41d0006c6a200241f8056a41d000109a051a200541f8066a200f41016a220f4102746a2038360200200520052f010641016a3b01062038200f3b0104203820053602000b200241b00f6a200241b8036a41d000109a051a20280d082029417f4c0d080240024020290d00410121150c010b202910282215450d020b024020162024490d00201621060c030b20262027410048720d140240024020160d002027102821150c010b201520292027102c21150b2025210620150d02202741011037000b41a80741081037000b202941011037000b024002402033450d00410021050c010b20292114201521052018210f03402005200f290000370000200541186a200f41186a290000370000200541106a200f41106a290000370000200541086a200f41086a290000370000200541206a2105200f41206a210f201441606a22140d000b202a21050b20024188086a200241b00f6a41d000109a051a200220053602e008200220063602dc08200220153602d808024002400240411010282205450d0020052004370000200541086a20103700002002429080808080023702bc07200220053602b8072002200241b8076a3602d80620024188046a200241d8066a10c80120022802b807210520022802c007210f200d42003703002009420037030020004200370300200242003703c8042005200f200241c8046a10002040200d29030037030020302009290300370300201b2000290300370300200220022903c8043703b00f024020022802bc07450d0020022802b807102a0b200241003602c007200242013703b80720024188086a200241b8076a108f012002202c3602d806200241d8066a200241b8076a10a3012002202b3602d806200241d8066a200241b8076a10a30120022802c808210520022802d008220f200241b8076a10b4010240200f450d00200f41306c210f0340200541106a200241b8076a108f01200220053602d806200541306a2105200241d8066a200241b8076a10a301200f41506a220f0d000b0b20022802d808210520022802e008220f200241b8076a10b4010240200f450d00200f410574210f03402005200241b8076a108f01200541206a2105200f41606a220f0d000b0b20022802bc072105200241b00f6a412020022802b807220f20022802c007100702402005450d00200f102a0b024020022802cc08450d0020022802c808102a0b024020022802dc08450d0020022802d808102a0b200241b8076a41186a2206203d290300370300200241b8076a41106a220a203e290300370300200241b8076a41086a220e203f29030037030020022002290388043703b807410021050240201d41014b0d000240201d0e020003000b203420062903003703002035200a2903003703002036200e290300370300200220022903b80737038808410021050c030b201d210f03402005200f410176221420056a2215200c201541246c6a280200200b4b1b2105200f20146b220f41014b0d000c020b0b411041011037000b0240200c200541246c6a280200220f200b460d002005200f200b496a21050b203420062903003703002035200a2903003703002036200e290300370300200220022903b80737038808201d20054f0d0041f8b0c0001032000b0240201d201e470d00201d41016a220f201d490d12201d4101742214200f2014200f4b1b221ead42247e2204422088a70d122004a7220f4100480d1202400240201d0d00200f1028210c0c010b200c201d41246c200f102c210c0b200c450d030b200c200541246c6a220f41246a200f201d20056b41246c109b051a200f200b360200200f411c6a2034290300370200200f41146a2035290300370200200f410c6a2036290300370200200f200229038808370204204020062903003703002030200a290300370300201b200e290300370300200220022903b8073703b00f0240201f2020470d00201f41016a2205201f490d12201f410174220f2005200f20054b1b222041ffffff3f712020470d12202041057422054100480d1202400240201f0d0020051028211c0c010b201c201f4105742005102c211c0b201c450d040b201d41016a211d201c201f4105746a220520022903b00f370000200541186a2040290300370000200541106a2030290300370000200541086a201b290300370000201f41016a211f0b20132021470d000b202121130c020b200f41041037000b200541011037000b024020132021460d002007200841d0006c6a21140340201341c0006a280200220f450d01201341d0006a21050240201341c4006a280200450d00200f102a0b2005211320142005470d000b0b02402003450d002007102a0b0240024002400240024002400240024002400240024020022802e0020d0020022802d80220022802dc02410010ca01201a102a02402020450d00201c102a0b0240201e450d00200c102a0b2017450d012018102a0c010b2002201c3602d8062002201c201f4105746a3602dc06200241b00f6a200241d8066a10850102400240200241f00f6a2802000d004108210841002109410021230c010b20024188086a200241b00f6a41e000109a051a41e00010282208450d03200820024188086a41e000109a051a200220022903d8063703b807200241b00f6a200241b8076a1085010240200241f00f6a2802000d0041012109410121230c010b4102210f41e00021054101210941012123034020024188086a200241b00f6a41e000109a051a024020092023470d00200941016a22142009490d19200f2014200f20144b1b2223ad42e0007e2204422088a70d192004a722144100480d190240024020090d002014102821080c010b200820052014102c21080b2008450d060b200820056a20024188086a41e000109a051a200f41026a210f200541e0006a2105200941016a2109200241b00f6a200241b8076a10850120022802f00f0d000b0b200241a8086a201d360200200241a4086a201e36020020024198086a201fad4220862020ad843703002002201c3602940820024284808080c00037028c082002201a360288082002200c3602a008200241003602b80f200242013703b00f201d200241b00f6a10b4010240201d450d00200c201d41246c6a210a200c210f0340200f28020021150240024020022802b40f221420022802b80f22056b4104490d0020022802b00f21140c010b200541046a22062005490d19201441017422052006200520064b1b22054100480d190240024020140d002005102821140c010b20022802b00f20142005102c21140b2014450d07200220053602b40f200220143602b00f20022802b80f21050b2002200541046a3602b80f201420056a20153600002002200241b00f6a3602b807200f41046a200241b8076a10c801200f41246a220f200a470d000b0b20022802b80f211420022802b40f211520022802b00f210f411b10282205450d05200541176a41002800f39646360000200541106a41002900ec9646370000200541086a41002900e49646370000200541002900dc96463700002002429b808080b0033702bc07200220053602b80741a2c7c000200241b8076a10c60120022802c007210620022802b8072105200241c8046a41186a220a4200370300200241c8046a41106a220e4200370300200241c8046a41086a22134200370300200242003703c80420052006200241c8046a1000200241b00f6a41186a200a290300370300200241b00f6a41106a200e290300370300200241b00f6a41086a2013290300370300200220022903c8043703b00f024020022802bc07450d002005102a0b200241203602bc072002200241b00f6a3602b807200f2014200241b8076a10cb0102402015450d00200f102a0b200241b8076a20024188086a10c70120022802c007211520022802b8072114200241003602b80f200242013703b00f201f200241b00f6a10b4010240201f450d00201f410574210f201c210503402002200241b00f6a3602d8062005200241d8066a10c801200541206a2105200f41606a220f0d000b0b20022802b40f21052014201520022802b00f220f20022802b80f100702402005450d00200f102a0b024020022802bc07450d002014102a0b201a102a02402020450d00201c102a0b0240201e450d00200c102a0b20022802d802210520022902dc02210402402017450d002018102a0b20050d010b20012802082114024020012802102205450d00200541d0006c210f201441c0006a210503400240200541046a280200450d002005280200102a0b200541d0006a2105200f41b07f6a220f0d000b0b2001410c6a280200450d142014102a0c140b200220043702bc03200220053602b803410410282205450d042005200b36000020024190086a4284808080c00037030020024198086a41002900a2c740370300200241a0086a41002900aac7403703002002200536028c082002410f3a0088084101410020024188086a10cc012019418094ebdc036e22054101200541014b1b220520194b0d052019200941036c417d6a220f200f20194b1b20056ead428094ebdc037e201920056ead221080a741146e2215211420092004422088a76b220f0d060c070b41e00041081037000b201441081037000b200541011037000b411b41011037000b410441011037000b41acaac3001032000b2002418094ebdc0336028c082002418094ebdc03201941002009200f6b2214201420094b1b41036c417d6a2214201420194b1b20056ead428094ebdc037e201080a741146e22056bad4100201520056b2205200520154b1bad7e428094ebdc0380a722053602880820024188086a2005418094ebdc034b4102746a28020021140b200941e0006c220541e0006e2129410021130240024020050d0041042138410021290c010b2029410274220610282238450d020b0240200820056a2008460d000240200f0d00200941e0006c210f4100211320382105034020052014360200201341016a2113200541046a2105200f41a07f6a220f0d000c020b0b2008200941e0006c6a2106200941057441606a210a203821052008210f0340200220022802b8033602b40f200220022802bc033602b00f2002200241b8036a3602b80f20024188086a200241b00f6a200f10c9012005201420152002280288084101461b360200200541046a21052006200f41e0006a220f470d000b200a41057641016a21130b20024188086a41086a220542003703002002420037038808419e9dc600411b20024188086a1008200241b00f6a41086a200529030037030020022002290388083703b00f4100211b2002410036028808200241b00f6a411020024188086a100621050240200228028808220f417f460d002005450d00200f4104490d032005280000211b2005102a0b20024188086a41086a22054200370300200242003703880841bb9cc600411220024188086a1008200241b00f6a41086a200529030037030020022002290388083703b00f4100213b2002410036028808200241b00f6a411020024188086a100621050240200228028808220f417f460d002005450d00200f4104490d042005280000213b2005102a0b411710282205450d042005410f6a41002900d3fe44370000200541086a41002900ccfe44370000200541002900c4fe4437000020054117412e102c2205450d052005203b36001742002149200241f8056a41186a220f4200370300200241f8056a41106a22144200370300200241f8056a41086a22154200370300200242003703f8052005411b200241f8056a1000200241a8056a41186a200f290300370300200241a8056a41106a2014290300370300200241a8056a41086a2015290300370300200220022903f8053703a8052005102a2002410036028808200241a8056a412020024188086a100621002002280288082230417f460d092000450d09200220303602fc02200220003602f802200241c0026a200241f8026a106c20022802c0020d0820022802fc0222154140712205417f4c0d0020022802c402210d024002402015410676220e0d004108211d0c010b20051028221d450d070b0240200d450d004100210a0340200241003a00a808200a220641016a210a41002105024002400240034020152005460d0120024188086a20056a20022802f80222142d00003a00002002201441016a3602f8022002200541016a220f3a00a808200f2105200f4120470d000b200241f8056a41186a220520024188086a41186a290300370300200241f8056a41106a220b20024188086a41106a290300370300200241f8056a41086a220c20024188086a41086a29030037030020022002290388083703f8052015200f6b220f4110490d012002201441116a3602f802200f41706a410f4b0d02200f41706a210f0c010b0240200541ff0171450d00200241003a00a8080b4100210f0b200241b8076a41086a200241b00f6a41086a290300370300200220022903b00f3703b8072002200f3602fc02200e450d0b201d102a0c0b0b201441096a290000210420142900012110200241b8076a41086a2215200c290300370300200241b8076a41106a220c200b290300370300200241b8076a41186a220b20052903003703002002201441216a3602f802200220022903f80522113703b00f200220113703b807201441196a290000211120142900112112200241d8066a41186a2214200b290300370300200241d8066a41106a220b200c290300370300200241d8066a41086a220c2015290300370300200220022903b8073703d8060240200e2006470d0020064101742205200a2005200a4b1b220e41ffffff1f71200e470d0f200e41067422054100480d0f0240024020060d0020051028211d0c010b201d20064106742005102c211d0b201d450d0a0b200f41606a2115201d20064106746a220520123703102005200437030820052010370300200541186a2011370300200520022903d806370320200541286a200c290300370300200541306a200b290300370300200541386a2014290300370300200a200d470d000b2002200f41606a3602fc020b201d450d08200dad422086200ead84214902402030450d002000102a0b2049422088a7210f2049a7210e0c0a0b1036000b200641041037000b41c4d1c3004133200241f8056a419cd9c3001038000b41c4d1c3004133200241f8056a419cd9c3001038000b411741011037000b412e41011037000b200541081037000b200541081037000b41c4d1c3004133200241f8056a419cd9c3001038000b4108211d4100210f4100210e0b0240024020132009200920134b1b221f0d004200214a4200214b0c010b200241b00f6a4105722122200241b8076a41036a213920024188086a410572213220024188086a41086a2113201bad214c20024191086a2135200241e8016a41186a213a2008210b4200214a4200214b41002130034020134200370300200242003703880841c8ffc400411520024188086a1008200241b00f6a41086a2236201329030037030020022002290388083703b00f2002410036028808200241b00f6a411020024188086a100621140240024002400240024002400240024002400240024002400240024002400240024002400240200228028808220f417f460d002002200f3602bc07200220143602b80720024188086a200241b8076a106d2002280288082205450d02200229028c082104200f450d012014102a0c010b42002104410121050b20052004422088a72008203041e0006c6a220f10cd01211402402004a7450d002005102a0b20140d10200241b0026a200f41206a22342903002204203441086a222c290300428094ebdc03420010a005200241a0026a20022903b0022210200241b0026a41086a29030022114280ec94a37c427f109f0520024190026a20102011203820304102746a35020022124200109f0520022903900222102012200420022903a0027c7e428094ebdc038042ffffffff0f837c220420024190026a41086a2903002004201054ad7c2210844200510d1020134200370300200242003703880841c785c200411220024188086a100820024198056a41086a220c2013290300370300200220022903880837039805200241003602880820024198056a411020024188086a10062105024002402002280288082214417f460d002005450d00200220143602b40f200220053602b00f20024188086a200241b00f6a106d2002280288082237450d03200229028c0821122014450d012005102a0c010b41012137420021120b20372012422088a74105746a21064100211420372105024003400240200620056b41e0004b0d004102212b20052006460d080340200b2005460d0320142005200f4120109c0522154100476a21142015450d032006200541206a2205470d000c090b0b2005200f460d0120142005200f4120109c0522154100476a21142015450d01200541206a2215200f460d0120142015200f4120109c0522154100476a21142015450d01200541c0006a2215200f460d0120142015200f4120109c0522154100476a21142015450d01200541e0006a2215200f460d0120142015200f4120109c0522154100476a211420054180016a210520150d000b0b20134200370300200242003703880841bd99c600411a20024188086a1008200c2013290300370300200220022903880837039805200241003602880820024198056a411020024188086a100621052002280288082206417f460d032005450d03200220063602b40f200220053602b00f20024188086a200241b00f6a1082012002280288082215450d02200229028c0821112006450d042005102a0c040b41c4d1c3004133200241f8056a419cd9c3001038000b41c4d1c3004133200241f8056a419cd9c3001038000b41c4d1c3004133200241f8056a419cd9c3001038000b410021150b2015410420151b21004100210502400240024002402011420020151b22114220882242a7220e41014b0d00200e0e020201020b200e2115034020052015410176220620056a220a20142000200a4102746a280200491b2105201520066b221541014b0d000b0b4100212b02402014200020054102746a2802002215470d00410021400c020b2005201420154b6a21050b20134200370300200242003703880841c785c200411220024188086a1008200c2013290300370300200220022903880837039805200241003602880820024198056a411020024188086a1006210602400240200228028808220a417f470d00410021150c010b024020060d00410021150c010b2002200a36028c08200220063602880820024188026a20024188086a106c024002402002280288020d00200228028c0221150c010b410021150b200a450d002006102a0b20152015418094ebdc036e22064180ec94a37c6c6aad4280fd87d1007e428094ebdc038021432005200e4b0d020240200e2011a7470d00200e41016a2215200e490d11200e410174220a20152015200a491b221541ffffffff03712015470d112015410274220a4100480d1102400240200e0d00200a102821000c010b2000200e410274200a102c21000b2000450d042015ad21110b200020054102746a221541046a2015200e20056b410274109b051a2015201436020041012140201142ffffffff0f83200e41016a2205ad2242422086842111200520064180fd87d1006c2043a76a4b212b0b20134200370300200242003703880841bd99c600411a20024188086a1008200c20132903003703002002200229038808370398050240024020000d0020024198056a411010090c010b200241003602900820024201370388082042a7221520024188086a10b4010240024020150d00200228029008210c200228028c08210e20022802880821150c010b410020022802900822056b2106200020154102746a211b200228028c08210e2000210a0340200a280200210d02400240200e20066a4104490d0020022802880821150c010b200541046a22152005490d13200e410174220c2015200c20154b1b220c4100480d1302400240200e0d00200c102821150c010b200228028808200e200c102c21150b2015450d072002200c36028c082002201536028808200c210e0b2002200541046a220c36029008201520056a200d3600002006417c6a2106200c2105201b200a41046a220a470d000b0b2011a7210520024198056a41102015200c10070240200e450d002015102a0b2005450d002000102a0b2040450d00200241023602b00f20022014ad3703b80f20024188086a200241b00f6a10c301203941086a221520132802003600002039200229038808370000203220022900b807370000203241076a200241b8076a41076a2206290000370000200241c6a4b9da0436008908200241023a00880820024188086a10ce012002201436028c082002410136028808200241003602b80f200242013703b00f410110282205450d04200220053602b00f200520022802b80f22146a41023a0000200241013602b40f2002201441016a22053602b80f200228028c08210a02400240410020146b4104490d0020022802b00f21140c010b200541046a22142005490d10410141017422052014200520144b1b22054100480d100240024041010d002005102821140c010b20022802b00f41012005102c21140b2014450d06200220053602b40f200220143602b00f20022802b80f21050b2002200541046a3602b80f201420056a200a360000200241d8066a41086a20022802b80f2205360200200220022903b00f22113703d8062015200536000020392011370000202220022900b807370000202241076a2006290000370000200241c28289aa043600b10f200241023a00b00f200241b00f6a10ce012002280288080d00200228029008450d00200228028c08102a0b02402012a7450d002037102a0b0240202b4102460d00202b410171450d00201342003703002002420037038808418e9dc600411020024188086a10082036201329030037030020022002290388083703b00f410110282205450d06200541013a0000200241b00f6a41102005410110072005102a0b202c2903002212201020342903002243200454201220105420122010511b22051b214d2043200420051b214e024002402049422088224fa722060d0042002110420021040c010b20064106742114201d41206a21054200211042002104034002400240200b2005460d002005200f4120109c050d010b427f2004200541706a221541086a2903007c201020152903007c22112010542215ad7c22102015201020045420102004511b22151b2104427f201120151b21100b200541c0006a2105201441406a22140d000b0b200241e8016a200f204e4200200f290330221120107d22422042201156200f41386a290300224220047d2011201054ad7d220420425620042042511b22051b22102010204e564200200420051b2204204d562004204d511b22051b2210204d200420051b220410cf01200241e8016a41086a290300215020022903e80121510240204e201020022903f80122527d22537d2254204d2004203a2903007d2010205254ad7d22557d204e205354ad7d225284500d00204320117d2210201220427d2043201154ad7d220484500d00200f2802482214450d00200f2802402205201441306c6a2115200241c8016a20542052428094ebdc03420010a005200241d8016a20102004428094ebdc03420010a005200241b8016a20022903c8012252200241c8016a41086a29030022564280ec94a37c427f109f05200241d8016a41086a2903002211420020022903d801224242015620114200522011501b22141b21122042420120141b2142205420022903b8017c21540340200241a8016a2010200529030022112011201056200541086a290300221120045620112004511b22141b2004201120141b2042201210a00520022903a8012243428080808010544100200241a8016a41086a290300501b450d0820024198016a201020042042201210a005200229039801221142808080801054410020024198016a41086a290300501b450d092011a7450d0a200241e8006a20522056204342ffffffff0f83428094ebdc037e201142ffffffff0f838042ffffffff0f8322114200109f05200241f8006a200541106a20022903682243201120547e428094ebdc038042ffffffff0f837c2211200241e8006a41086a2903002011204354ad7c10cf01427f2050200241f8006a41086a2903007c205120022903787c22432051542214ad7c22112014201120505420112050511b22141b2150427f204320141b2151200541306a22052015470d000b0b200241a8056a41186a2215200f41186a220a290300370300200241a8056a41106a220e200f41106a220c290300370300200241a8056a41086a220d200f41086a22002903003703002002200f2903003703a8050240024020062049a7460d00200621140c010b200641016a22052006490d0f204fa72214410174221b20052005201b491b220541ffffff1f712005470d0f2005410674221b4100480d0f0240024020060d00201b1028211d0c010b201d2014410674201b102c211d0b201d450d0a2005ad21490b200241d8006a20512050428094ebdc03420010a005200241c8006a20022903582204200241d8006a41086a29030022104280ec94a37c427f109f05200241386a20042010204c4200109f05201d20144106746a220520533703102005204d3703082005204e370300200541186a2055370300200520022903a805370320200541286a200d290300370300200541306a200e290300370300200541386a2015290300370300200241013a009008200241033a008808200a2900002104200c290000211020002900002111200f290000211220024188086a41386a204d37030020352012370000203541086a2011370000203541106a2010370000203541186a20043700002002204e3703b8084101410020024188086a10cc01204942ffffffff0f83201441016aad4220868421490240024020022903382210205120022903487c204c7e428094ebdc038042ffffffff0f837c2204200241386a41086a2903002004201054ad7c221084500d00200f41d8006a28020022050d010b427f204b20507c204a20517c2210204a542205ad7c220420052004204b542004204b511b22051b214b427f201020051b214a0c0b0b200241286a200420512051200456205020105620502010511b22141b22542010205020141b224d2005ad420010a00520054105742114200f2802502105200241286a41086a29030021522002290328215620542112204d21420340200241186a2005205620122012205656204220525620422052511b220f1b220420522042200f1b221010d00120024188086a41106a2010200241186a41086a29030022437d20042002290318221154ad7d204320107d2011200454ad7d201120045820432010582043201051220f1b22151b3703002002200420117d201120047d20151b37039008200220112004562043201056200f1b220fad37038808204220107d21102012200454ad211102400240200f0d00200220133602b00f200241b00f6a109d010c010b200220133602b00f200241b00f6a109c010b201020117d2142201220047d2112200541206a2105201441606a22140d000b427f427f204b20427c204a20127c2210204a542205ad7c220420052004204b542004204b511b22051b22042050204d7d2051205454ad7d7c427f201020051b2210205120547d7c22112010542205ad7c22102005201020045420102004511b22051b214b427f201120051b214a0c0a0b41f8b0c0001032000b200a41041037000b200c41011037000b410141011037000b200541011037000b410141011037000b10d101000b10d201000b41acaac3001032000b201b41081037000b200b41e0006a210b203041016a2230201f490d000b2049422088a7210f2049a7210e0b024002400240024002400240411710282205450d002005410f6a41002900d3fe44370000200541086a41002900ccfe44370000200541002900c4fe4437000020054117412e102c2205450d012005203b360017200241f8056a41186a22144200370300200241f8056a41106a22154200370300200241f8056a41086a22064200370300200242003703f8052005411b200241f8056a1000200241a8056a41186a2014290300370300200241a8056a41106a2015290300370300200241a8056a41086a2006290300370300200220022903f8053703a8052005102a20024100360290082002420137038808200f20024188086a10b401200f450d02200f410674210a201d21050340200541206a20024188086a108f01200541086a29030021042005290300211002400240200228028c08221420022802900822156b4110490d00200228028808210f0c010b201541106a220f2015490d0920144101742215200f2015200f4b1b22064100480d090240024020140d0020061028210f0c010b20022802880820142006102c210f0b200f450d052002200636028c082002200f360288082002280290082115200621140b200f20156a22062004370008200620103700002002201541106a221536029008200541186a2903002104200541106a290300211002400240201420156b410f4d0d00201421060c010b201541106a22062015490d09201441017422152006201520064b1b22064100480d090240024020140d0020061028210f0c010b200f20142006102c210f0b200f450d062002200636028c082002200f3602880820022802900821150b200541c0006a2105200f20156a22142004370008201420103700002002201541106a221436029008200a41406a220a0d000c060b0b411741011037000b412e41011037000b2002280290082114200228028c082106200228028808210f0c020b200641011037000b200641011037000b200241a8056a4120200f2014100702402006450d00200f102a0b0240200e450d00201d102a0b20024188086a10d301200241086a20024188086a204a204b10d001200241c00f6a204b200241086a41086a29030022107d204a2002290308220454ad7d2010204b7d2004204a54ad7d2004204a582010204b582010204b5122051b220f1b3703002002204a20047d2004204a7d200f1b3703b80f20022004204a562010204b5620051b2205ad3703b00f200241b00f6a41086a210f0240024020050d002002200f3602b807200241b8076a109d010c010b2002200f3602b807200241b8076a109c010b02402029450d002038102a0b02402009450d00200941e0006c210f200841d4006a210503400240200541706a280200450d002005416c6a280200102a0b02402005280200450d002005417c6a280200102a0b200541e0006a2105200f41a07f6a220f0d000b0b02402023450d002008102a0b20022802b80320022802bc0320022802c00310ca0120012802082114024020012802102205450d00200541d0006c210f201441c0006a210503400240200541046a280200450d002005280200102a0b200541d0006a2105200f41b07f6a220f0d000b0b2001410c6a280200450d002014102a0b20024190106a24000f0b1031000b8c1501037f0240024002400240024002400240024002400240024002400240024002400240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00003a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00013a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00023a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00033a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00043a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0620012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00053a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0720012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00063a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0820012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00073a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0920012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00083a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0a20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00093a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0b20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000a3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0c20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000b3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0d20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000c3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0e20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000d3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d0f20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000e3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d11200241017422042003200420034b1b22044100480d110240024020020d002004102821030c010b200128020020022004102c21030b2003450d1020012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20002d000f3a00000f0b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b1031000bba0601087f230041d0006b220224000240024002400240024002400240411f10282203450d00200341176a41002900c9c740370000200341106a41002900c2c740370000200341086a41002900bac740370000200341002900b2c7403700002002429f808080f0033702242002200336022041a2c7c000200241206a10c6012002280228210420022802202103200241306a41186a22054200370300200241306a41106a22064200370300200241306a41086a220742003703002002420037033020032004200241306a1000200241186a2005290300370300200241106a2006290300370300200241086a20072903003703002002200229033037030002402002280224450d002003102a0b412010282203450d0120032002290300370000200341186a200241186a290300370000200341106a200241106a290300370000200341086a200241086a2903003700002001280208220441046a2205417f4c0d02200128020021070240024020050d00410121010c010b200510282201450d040b2002410036023820022005360234200220013602302004200241306a10b4010240024020022802342206200228023822016b2004490d00200228023021050c010b200120046a22052001490d06200641017422082005200820054b1b22084100480d060240024020060d002008102821050c010b200228023020062008102c21050b2005450d052002200836023420022005360230200821060b200520016a20072004109a051a200241306a41186a22074200370300200241306a41106a22084200370300200241306a41086a22094200370300200242003703302005200120046a200241306a1000200241186a2007290300370300200241106a2008290300370300200241086a20092903003703002002200229033037030002402006450d002005102a0b2003412041c000102c2203450d0620032002290300370020200341386a200241186a290300370000200341306a200241106a290300370000200341286a200241086a290300370000200042c0808080800837020420002003360200200241d0006a24000f0b411f41011037000b412041011037000b1036000b200541011037000b200841011037000b1031000b41c00041011037000bba0501037f02400240024002400240024002400240410110282202450d00200220002d00003a0000200241014102102c2202450d01200220002d00013a0001200241024104102c2202450d02200220002d00023a0002200220002d00033a0003200241044108102c2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102c2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102c2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f024002402001280200220041046a2802002203200041086a28020022016b4120490d00200028020021030c010b200141206a22042001490d08200341017422012004200120044b1b22014100480d080240024020030d002001102821030c010b200028020020032001102c21030b2003450d0720002003360200200041046a2001360200200041086a28020021010b200041086a200141206a360200200320016a220041186a200241186a290000370000200041106a200241106a290000370000200041086a200241086a290000370000200020022900003700002002102a0f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000b200141011037000b1031000b9705060a7f047e037f027e047f027e200128020821032001280204210420012802002105200241386a2106200241286a2107034002400240200441f8b9c000462208450d00410021094108210a4108210b0c010b20042f01062109200441086a220a210b0b200b200941d0006c6a210c2006290300210d2007290300210e2002290330210f2002290320211020022802482111200228024021124100210b0240024002400340200b21090240200a200c470d0002402008450d00410021090c030b20042f010621090c020b024002402002200a4120109c05220b450d00417f4101200b4100481b21130c010b417f2010200a290320221485200e200a41286a290300221585844200522010201454200e201554200e2015511b1b22130d00417f200f200a41306a290300221485200d200a41386a29030022158584420052200f201454200d201554200d2015511b1b22130d00200a41c8006a28020022162011201120164b1b2117200a280240210b417f21182012211903400240201841016a22182017490d00417f201120164720112016491b21130c020b0240201941106a200b41106a4120109c052213450d00417f410120134100481b21130c020b2019290300221a200b290300221b54201941086a2903002215200b41086a29030022145420152014511b0d03200b41306a210b201941306a211941012113201a201b85201520148584500d000b0b200941016a210b200a41d0006a210a0240201341016a0e03020001020b0b4100210a0c010b20050d014101210a410021050b200020053602042000200a360200200041106a20093602002000410c6a2003360200200041086a20043602000f0b2001200336020820012005417f6a22053602002001200420094102746a41f8066a28020022043602040c000b0bee0303047f017e017f02402001450d00034020002802f80621002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d004108200041086a200041f8b9c000461b200141d0006c6a22042802442105200441c0006a2802002106200141016a21010c010b02400240200028020022010d002003ad210741002104410021010c010b20003301044220862003ad842107410121040b2000102a2007a72103024002402007422088a7220820012f01064f0d00200121000c010b034002400240200128020022000d002003ad2107410021000c010b200441016a210420013301044220862003ad8421070b2001102a2007a72103200021012007422088a7220820002f01064f0d000b0b4108200041086a200041f8b9c000461b200841d0006c6a22012802442105200141c0006a2802002106200841027420006a41fc066a280200210002402004417f6a2201450d00034020002802f80621002001417f6a22010d000b0b410021010b2006450d012002417f6a210202402005450d002006102a0b20020d000b0b0240200041f8b9c000460d00200028020021012000102a2001450d00200128020021002001102a2000450d00024020002802002201450d0003402000102a2001210020012802002203210120030d000b0b2000102a0b0b9d0201057f230041106b220324000240024002400240200141046a2204417f4c0d000240024020040d00410121050c010b200410282205450d020b2003410036020820032004360204200320053602002001200310b4010240024020032802042206200328020822056b2001490d00200328020021040c010b200520016a22042005490d04200641017422072004200720044b1b22074100480d040240024020060d002007102821040c010b200328020020062007102c21040b2004450d032003200736020420032004360200200721060b200420056a20002001109a051a200228020020022802042004200520016a100702402006450d002004102a0b200341106a24000f0b1036000b200441011037000b200741011037000b1031000bcd1f03087f047e017f230041a0036b2203240020034100360288014188e8c200411020034188016a10062104024002402003280288012205417f460d002004450d00024020054104490d00200428000021062004102a410021070c020b41c4d1c300413320034188016a419cd9c3001038000b410121070b0240024002400240024002400240024002400240024020010d004101210841002105410021090c010b200141057422044100480d07200410282208450d012001410574220941606a410576210a2008210420002105034020034188016a41186a200541186a290000220b37030020034188016a41106a200541106a290000220c37030020034188016a41086a200541086a290000220d37030020032005290000220e37038801200441186a200b370000200441106a200c370000200441086a200d3700002004200e370000200441206a2104200541206a2105200941606a22090d000b200a41016a2109200121050b200341f4006a2006360200200320073602702003200241f000109a0522044180016a2009360200200441fc006a20053602002004200836027820044190026a41086a22054200370300200442003703900241eea0c600411120044190026a1008200441b0026a41086a200529030037030020042004290390023703b0022004410036028801200441b0026a411020044188016a10062105024002400240024002400240024002402004280288012203417f470d00410021080c010b024020050d00410021080c010b20034104490d01200528000021082005102a0b0240200841016a22032008490d0020044190026a41086a22054200370300200442003703900241eea0c600411120044190026a1008200441b0026a41086a2209200529030037030020042004290390023703b0022004200336028801200441b0026a411020044188016a4104100720044188016a2004418801109a051a20054200370300200442003703900241d4f2c200410d20044190026a10082009200529030037030020042004290390023703b0022004410036029002200441b0026a411020044190026a10062103024002402004280290022205417f460d002005210920030d010b2004410036028003200442083703f80220044100360298022004420137039002410020044190026a10b401200428029802210520042802940221092004280290022103200441f8026a10720b200420053602c802200420093602c402200420033602c002024002402005450d0020044190026a20032005410110d6022004280290024101470d0120042802c402450d0c20042802c002102a0c0c0b4101200441c0026a10b40120044188016a200441c0026a10aa030c090b200428029402210202402004419c026a280200220520044198026a2802002203460d0020042802c802200520036b6a22094188016a2207417f4c0d100240024020070d00410121060c010b200710282206450d040b200420073602d402200420063602d002200420093602d8022004200441d0026a36029002200220044190026a200510d70120092005490d0420042802d80222022009490d0520042802c80222022003490d0620042802d002210720042802c00221062004200920056b22093602dc022004200220036b22023602940320092002470d07200720056a200620036a2009109a051a20044188016a200441d0026a10aa0320042802d802210320042802d402210920042802d002210520042802c402450d0a20042802c002102a0c0a0b2004200441c0026a36029002200220044190026a200310d70120044188016a200441c0026a10aa030c080b200410ab030c0b0b41c4d1c300413320044188016a419cd9c3001038000b200741011037000b200520091044000b20092002103c000b200320021044000b200441f8026a41146a410836020020044184036a4125360200200441e0026a41146a4103360200200442033702e402200441c8afc6003602e002200441253602fc022004200441dc026a36029803200420044194036a36029c03200442043703a00220044201370294022004419cb0c600360290022004200441f8026a3602f002200420044190026a3602880320042004419c036a36028003200420044198036a3602f802200441e0026a41d8b0c600103e000b200441011037000b20042802c802210320042802c402210920042802c00221050b20050d010b20044188016a10ab030c010b200441b0026a411020052003100702402009450d002005102a0b20044188016a10ab0320044190026a41086a22054200370300200442003703900241d9efc200410d20044190026a1008200441b0026a41086a200529030037030020042004290390023703b0024100210f2004410036028801200441b0026a411020044188016a1006210502402004280288012203417f460d002005450d0020034104490d032005280000210f2005102a0b2001450d002001410574210a02400340200420083602d4022004200f3602d0020240024002400240024002400240024002400240024002400240024002400240411210282205450d00200541106a41002f00f1f2423b0000200541086a41002900e9f242370000200541002900e1f24237000020044188016a41186a2203420037030020044188016a41106a2209420037030020044188016a41086a2201420037030020044200370388012005411220044188016a100020044190026a41186a2202200329030037030020044190026a41106a2207200929030037030020044190026a41086a220620012903003703002004200429038801370390022005102a412010282205450d012005200429039002370000200541186a2002290300370000200541106a2007290300370000200541086a200629030037000020044188016a200010e0022005412041c000102c2205450d022005200429008801370020200541386a2003290000370000200541306a2009290000370000200541286a20012900003700002004410036028801200541c00020044188016a10062109024002402004280288012201417f460d00200121030c010b20044100360290012004420137038801410020044188016a10b4012004280290012103200428028c01210120042802880121090b200420033602b802200420013602b402200420093602b002024002400240024002402003450d0020044188016a20092003410110d6022004280288014101460d04200428028c01210220042802940122032004280290012209460d0320042802b802200320096b6a220141086a2207417f4c0d1a20070d01410121060c020b4101200441b0026a10b40120042802d00221010240024020042802b402220920042802b80222036b4104490d0020042802b00221090c010b200341046a22022003490d18200941017422032002200320024b1b22034100480d180240024020090d002003102821090c010b20042802b00220092003102c21090b2009450d08200420033602b402200420093602b00220042802b80221030b2004200341046a3602b802200920036a200136000020042802d40221010240024020042802b402220920042802b80222036b4104490d0020042802b00221090c010b200341046a22022003490d18200941017422032002200320024b1b22034100480d180240024020090d002003102821090c010b20042802b00220092003102c21090b2009450d09200420033602b402200420093602b00220042802b80221030b2004200341046a3602b802200920036a20013600000c120b200710282206450d080b200420073602e402200420063602e002200420013602e8022004200441e0026a36028801200220044188016a200310d70120012003490d0820042802e80222022001490d0920042802b80222022009490d0a20042802e002210720042802b00221062004200120036b2201360294032004200220096b22023602980320012002470d0b200720036a200620096a2001109a051a20042802d00221010240024020042802e402220920042802e80222036b4104490d0020042802e00221090c010b200341046a22022003490d16200941017422032002200320024b1b22034100480d160240024020090d002003102821090c010b20042802e00220092003102c21090b2009450d0d200420033602e402200420093602e00220042802e80221030b2004200341046a3602e802200920036a200136000020042802d40221010240024020042802e402220920042802e80222036b4104490d0020042802e00221090c010b200341046a22022003490d16200941017422032002200320024b1b22034100480d160240024020090d002003102821090c010b20042802e00220092003102c21090b2009450d0e200420033602e402200420093602e00220042802e80221030b2004200341046a3602e802200920036a200136000020042802e802210920042802e402210120042802e002210320042802b402450d1120042802b002102a0c110b2004200441b0026a36028801200220044188016a200910d70120042802d00221010240024020042802b402220920042802b80222036b4104490d0020042802b00221090c010b200341046a22022003490d15200941017422032002200320024b1b22034100480d150240024020090d002003102821090c010b20042802b00220092003102c21090b2009450d0e200420033602b402200420093602b00220042802b80221030b2004200341046a3602b802200920036a200136000020042802d40221010240024020042802b402220920042802b80222036b4104490d0020042802b00221090c010b200341046a22022003490d15200941017422032002200320024b1b22034100480d150240024020090d002003102821090c010b20042802b00220092003102c21090b2009450d0f200420033602b402200420093602b00220042802b80221030b2004200341046a3602b802200920036a20013600000c0f0b20042802b402450d1120042802b002102a0c110b411241011037000b412041011037000b41c00041011037000b200341011037000b200341011037000b200741011037000b200320011044000b20012002103c000b200920021044000b200441f8026a41146a410836020020044184036a412536020020044190026a41146a41033602002004420337029402200441c8afc60036029002200441253602fc02200420044194036a36029c03200420044198036a3602c00220044204370398012004420137028c012004419cb0c600360288012004200441f8026a3602a002200420044188016a360288032004200441c0026a3602800320042004419c036a3602f80220044190026a41d8b0c600103e000b200341011037000b200341011037000b200341011037000b200341011037000b20042802b802210920042802b402210120042802b00221030b2003450d01200541c00020032009100702402001450d002003102a0b200041206a21002005102a200a41606a220a0d000c020b0b2005102a0b200441a0036a24000f0b1031000b41c4d1c300413320044188016a419cd9c3001038000b1036000bcd0101047f200020014105746a210320002104024003400240200320046b41e0004b0d00024020042003460d00200020014105746a210503404101210620022004460d04200420024120109c05450d042005200441206a2204470d000b0b41000f0b4101210620042002460d01200420024120109c05450d01200441206a22052002460d01200520024120109c05450d01200441c0006a22052002460d01200520024120109c05450d01200441e0006a22052002460d0120044180016a2104200520024120109c050d000b0b20060bba0604017f017e047f027e230041c0006b2201240042002102200141186a41086a220342003703002001420037031841b1f0c200410d200141186a1008200141086a200329030037030020012001290318370300410021032001410036021820014110200141186a100621040240024002400240024020012802182205417f460d002001200536021420012004360210200141186a200141106a107620012802182206450d02200129021c210202402005450d002004102a0b2002422088a721032002a721050c010b41042106410021050b200141186a41206a200041206a280200360200200141186a41186a200041186a290200370300200141186a41106a200041106a290200370300200141186a41086a200041086a29020037030020012000290200370318024020032005470d00024020032002a7470d00200341016a22002003490d04200341017422052000200520004b1bad220742247e2208422088a70d042008a722004100480d040240024020030d002000102821060c010b2006200341246c2000102c21060b2006450d0320024280808080708320078421020b2002422088a721030b2006200341246c22056a22002001290318370200200041206a200141186a41206a280200360200200041186a200141186a41186a290300370200200041106a200141186a41106a290300370200200041086a200141186a41086a2200290300370200200042003703002001420037031841b1f0c200410d200141186a1008200141086a2000290300370300200120012903183703002001411036021c200120013602182006200341016a2200200141186a10e102024020002003490d00200541246a21002006210303400240024020032d0000220541034b0d0002400240024020050e0404000102040b2003410c6a280200450d03200341086a280200102a0c030b2003410c6a280200450d02200341086a280200102a0c020b2003410c6a280200450d01200341086a280200102a0c010b200341086a280200450d00200341046a280200102a0b200341246a21032000415c6a22000d000b0b02402002a7450d002006102a0b200141c0006a24000f0b41c4d1c3004133200141186a419cd9c3001038000b200041041037000b1031000b8c0702067f067e230041d0006b220424000240024002400240411410282205450d00200541002900cfe140370000200541106a41002800dfe140360000200541086a41002900d7e14037000020044294808080c002370224200420053602202001200441206a108f012004280228210520042802202106200441306a41186a22074200370300200441306a41106a22084200370300200441306a41086a220942003703002004420037033020062005200441306a1000200441186a2007290300370300200441106a2008290300370300200441086a20092903003703002004200429033037030002402004280224450d002004280220102a0b2004410036023020044120200441306a100621050240024020042802302206417f470d004200210a4200210b0c010b20064110490d02200541086a290000210b2005290000210a2005102a0b2001200a2002200a200a200256200b200356200b2003511b22051b220c7d200b2003200b20051b220d7d200a200c54ad7d108f02024002402002200c7d220b2003200d7d2002200c54ad7d220e8450450d004200210a4200210e0c010b411810282205450d03200541002900e3e140370000200541106a41002900f3e140370000200541086a41002900ebe140370000200442988080808003370224200420053602202001200441206a108f012004280228210520042802202106200441306a41186a22074200370300200441306a41106a22084200370300200441306a41086a220942003703002004420037033020062005200441306a1000200441186a2007290300370300200441106a2008290300370300200441086a20092903003703002004200429033037030002402004280224450d002004280220102a0b2004410036023020044120200441306a100621050240024020042802302206417f470d0042002102420021030c010b20064110490d05200541086a2900002103200529000021022005102a0b20012002200b20022002200b562003200e562003200e511b22051b220a7d2003200e200320051b220f7d2002200a54ad7d109002200e200f7d200b200a54ad7d210e200f200d7c200a200c7c2202200a54ad7c2103200b200a7d210a0b2000200a37031020002002370300200041186a200e37030020002003370308200441d0006a24000f0b411441011037000b41c4d1c3004133200441306a419cd9c3001038000b411841011037000b41c4d1c3004133200441306a419cd9c3001038000be20302067f027e230041d0006b2204240002400240411410282205450d00200541002900cfe140370000200541106a41002800dfe140360000200541086a41002900d7e14037000020044294808080c002370224200420053602202001200441206a108f012004280228210520042802202106200441306a41186a22074200370300200441306a41106a22084200370300200441306a41086a220942003703002004420037033020062005200441306a1000200441186a2007290300370300200441106a2008290300370300200441086a20092903003703002004200429033037030002402004280224450d002004280220102a0b2004410036023020044120200441306a100621050240024020042802302206417f470d004200210a4200210b0c010b20064110490d02200541086a290000210b2005290000210a2005102a0b200441306a2001200a20027c2202200b20037c2002200a54ad7c109401200441106a200441306a41106a290300220a370300200420042903382202370308200420042903302203370300024020034200510d002004200441086a360230200441306a109d01420021024200210a0b200020023703002000200a370308200441d0006a24000f0b411441011037000b41c4d1c3004133200441306a419cd9c3001038000b0a0041a8acc3001032000b0a0041b8abc3001032000bbf0301077f230041d0006b22012400024002400240024002400240410110282202450d00200241ed003a0000200241014102102c2202450d01200241ef003a0001200241024104102c2202450d02200241e4d8013b0002200241044108102c2202450d03200241f0f2bda107360004200241084110102c2203450d04200341f2e6c9cb07360008200141003a0048410c210220032104410021050340200141003a0008200141086a200420024100472206109a051a024020020d00200141003a00080b20022006490d06200141286a20056a20012d00083a00002001200541016a22073a0048200220066b2102200420066a21042007210520074120470d000b200141086a41186a2202200141286a41186a290300370300200141086a41106a2206200141286a41106a290300370300200141086a41086a2204200141286a41086a290300370300200120012903283703082003102a200041186a2002290300370000200041106a2006290300370000200041086a200429030037000020002001290308370000200141d0006a24000f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b200620021044000b940705017f047e087f057e017f23004180026b22022400200241c0006a2001109f01024002402002290340a7450d00200041003602200c010b200241c0006a41106a290300210320022903482104200241286a2001109f0102402002290328a7450d00200041003602200c010b200241286a41106a290300210520022903302106200241206a2001106c0240024002400240024020022802200d00200128020441306e220741306c2208417f4c0d02200228022421090240024020080d004108210a0c010b20081028220a450d040b02402009450d004100210b0340200241003a00f801200b220c41016a210b2001280204417f6a21084100210d024002400240024003402008417f460d01200241d8016a200d6a2001280200220e2d00003a0000200120083602042001200e41016a3602002002200d41016a220e3a00f8012008417f6a2108200e210d200e4120470d000b200241b8016a41186a2208200241d8016a41186a290300370300200241b8016a41106a220d200241d8016a41106a290300370300200241b8016a41086a220e200241d8016a41086a290300370300200220022903d8013703b801200241086a2001109f012002290308a70d01200241086a41106a290300210f20022903102110200241f8006a41086a200e2903002211370300200241f8006a41106a200d2903002212370300200241f8006a41186a20082903002213370300200241d8006a41086a220d2011370300200241d8006a41106a220e2012370300200241d8006a41186a22142013370300200220022903b8012211370378200220113703582007200c470d030240200c4101742208200b2008200b4b1b2207ad42307e2211422088a70d002011a7220841004e0d030b1031000b200d41ff0171450d00200241003a00f8010b200241f8006a41086a20024198016a41086a2903003703002007450d04200a102a0c040b02400240200c0d0020081028210a0c010b200a200c41306c2008102c210a0b200a450d070b200a200c41306c6a2208200f3703082008201037030020082002290358370310200841186a200d290300370300200841206a200e290300370300200841286a2014290300370300200b2009470d000b0b200a0d010b200041003602200c040b20002004370300200020073602242000200a3602202000200637031020002003370308200041286a2009360200200041186a20053703000c030b1036000b200841081037000b200841081037000b20024180026a24000b0a0041f0b8c0001032000b4d01017f230041206b22002400200041146a410136020020004201370204200041ccd1c5003602002000410436021c200041c4d1c5003602182000200041186a360210200041ccb9c000103e000b8d0301027f230041e0006b22032400200341003a0005024002402000413f4b0d0041012104200341013a0005200320004102743a00000c010b02400240200041808001490d0020004180808080044f0d0141042104200341043a0005200320004102744102723602000c020b41022104200341023a0005200320004102744101723b01000c010b41052104200341053a0005200341033a0000200320003600010b024002402001280200220028020822012002490d0020002802002100200320023602082003200436020c20042002470d01200020032002109a051a200341e0006a24000f0b20022001103c000b200341286a41146a4108360200200341346a4125360200200341106a41146a410336020020034203370214200341c8afc6003602102003412536022c2003200341086a36024020032003410c6a360244200342043703582003420137024c2003419cb0c6003602482003200341286a3602202003200341c8006a3602382003200341c4006a3602302003200341c0006a360228200341106a41d8b0c600103e000bb60201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210420034120710d012004ad41012001103f21000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000b20024180016a240020000f0b20044180011044000b20044180011044000b130020004102360204200041cc9dc6003602000b130020004101360204200041b8a8c3003602000b130020004103360204200041a8dcc0003602000b130020004103360204200041bcaac4003602000b130020004101360204200041d899c6003602000b13002000410b3602042000418082c5003602000b13002000410636020420004198e8c2003602000b130020004104360204200041d09ec1003602000b130020004105360204200041f8aec3003602000b130020004103360204200041ec91c6003602000b130020004105360204200041ac81c2003602000b130020004106360204200041f8d1c3003602000b130020004103360204200041a896c4003602000b13002000410136020420004190e0c0003602000b130020004101360204200041f896c6003602000b8b0701077f23004190026b2202240041002103200241003a002820012802042104417f210502400240034020042003460d01200241086a20036a200128020022062d00003a00002001200420056a3602042001200641016a3602002002200341016a22073a00282005417f6a21052007210320074120470d000b200241e8006a41086a200241086a41086a290300370300200241e8006a41106a200241086a41106a290300370300200241e8006a41186a200241086a41186a2903003703002002200229030837036841002103200241003a0028200420076b2108200420056a21050340024020082003470d000240200341ff0171450d00200241003a00280b200041013a00000c030b200241086a20036a200620036a220741016a2d00003a0000200120053602042001200741026a3602002002200341016a22073a00282005417f6a21052007210320074120470d000b20024188016a41086a200241086a41086a29030037030020024188016a41106a200241086a41106a29030037030020024188016a41186a200241086a41186a290300370300200220022903083703880141002103200241003a008802200620076a2106034002402005417f470d000240200341ff0171450d00200241003a0088020b200041013a00000c030b200241e8016a20036a200620036a220741016a2d00003a0000200120053602042001200741026a3602002002200341016a22073a0088022005417f6a21052007210320074120470d000b200241a8016a41086a2201200241e8016a41086a290300370300200241a8016a41106a2203200241e8016a41106a290300370300200241a8016a41186a2205200241e8016a41186a290300370300200241086a41086a200241e8006a41086a290300370300200241086a41106a200241e8006a41106a290300370300200241086a41186a200241e8006a41186a290300370300200220022903e8013703a80120022002290368370308200241c0006a20024188016a41186a290300370300200241386a20024188016a41106a290300370300200241306a20024188016a41086a2903003703002002200229038801370328200241e0006a2005290300370300200241d8006a2003290300370300200241d0006a2001290300370300200220022903a801370348200041016a200241086a41e000109a051a200041003a00000c010b0240200341ff0171450d00200241003a00280b200041013a00000b20024190026a24000bf90802067f047e230041d0026b220224000240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541034b0d0620050e0401020304010b200041053a00000c090b200241206a2001106d20022802200d03200041053a00000c080b200241c0006a20011081010240024020022802404113460d00200241c8016a200241c0006a418801109a051a418801102822050d0141880141081037000b200041053a00000c080b2005200241c8016a418801109a052105200041023a0000200020022f00103b0001200041036a200241106a41026a2d00003a0000200041046a2005360200200041086a2002290220370200200041106a200241206a41086a290200370200200041186a200241206a41106a290200370200200041206a200241206a41186a2902003702000c070b20022001106c20022802000d0520022802042105200241c0006a200110810120022802404113460d05200241c8016a200241c0006a418801109a051a41880110282201450d032001200241c8016a418801109a052101200041033a0000200020022f00103b0001200041036a200241126a2d00003a0000200041086a2001360200200041046a20053602002000410c6a2002290220370200200041146a200241206a41086a2902003702002000411c6a200241306a290200370200200041246a200241386a2802003602000c060b41002105200241003a00e8012003417f6a21062003417e6a21030340024020062005470d00200541ff0171450d05200241003a00e8010c050b200241c8016a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00e8012003417f6a21032007210520074120470d000b200241c0006a41186a200241c8016a41186a290300370300200241c0006a41106a200241c8016a41106a290300370300200241c0006a41086a200241c8016a41086a290300370300200220022903c801370340200241086a2001106c20022802080d0320012802042205450d03200228020c2103200128020022072d0000210420012005417f6a3602042001200741016a360200200241206a41086a200241c0006a41086a2903002208370300200241206a41106a200241c0006a41106a2903002209370300200241206a41186a200241c0006a41186a290300220a37030020022002290340220b370320200041043a00002000200b370001200041096a2008370000200041116a2009370000200041196a200a370000200041246a2003360200200041216a20043a00000c050b200241cb006a200241206a41086a28020036000020022002290320370043200041013a000020002002290040370001200041086a200241c7006a290000370000200041106a20022902c801370200200041186a200241c8016a41086a290200370200200041206a200241c8016a41106a2902003702000c040b200041053a00000c030b41880141081037000b200041053a00000c010b200041053a00000b200241d0026a24000bd50603057f0b7e057f230041106b21020240200128020422034104490d0020012802002204280000210520012003417c6a22063602042001200441046a36020020064108490d00200429000421072001200341746a220636020420012004410c6a36020020064108490d00200429000c210820012003416c6a22063602042001200441146a36020020064108490d00200429001421092001200341646a220636020420012004411c6a36020020064108490d00200429001c210a20012003415c6a22063602042001200441246a36020020064108490d002004290024210b2001200341546a220636020420012004412c6a36020020064108490d00200429002c210c20012003414c6a22063602042001200441346a36020020064108490d002004290034210d2001200341446a220636020420012004413c6a36020020064108490d00200429003c210e2001200341bc7f6a22063602042001200441c4006a36020020064108490d002004290044210f2001200341b47f6a22063602042001200441cc006a36020020064108490d00200429004c21102001200341ac7f6a22063602042001200441d4006a36020020064108490d00200429005421112001200341a47f6a22063602042001200441dc006a36020020064104490d00200428005c21122001200341a07f6a22063602042001200441e0006a36020020064104490d002004280060211320012003419c7f6a22063602042001200441e4006a36020020064104490d00200428006421142001200341987f6a22063602042001200441e8006a36020020064104490d00200428006821152001200341947f6a22063602042001200441ec006a22043602002006450d0020042d000021162001200341937f6a22063602042001200441016a36020020064104490d00200020163a00702000201536026820002014360264200020133602602000201236025c2000200536025820002011370350200020103703482000200f3703402000200e3703382000200d3703302000200c3703282000200b3703202000200a3703182000200937031020002008370308200020073703002004280001210620012003418f7f6a3602042001200441056a3602002000200636026c200041f4006a2002410c6a280000360000200020022800093600710f0b200041023a00700bfb910205057f017e067f017e017f230041206b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402000280200220341144b0d00024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e15000102030405060708090a0b0c0d0e0f1011121314000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d62200341017422052004200520044b1b22054100480d620240024020030d002005102821040c010b200128020020032005102c21040b2004450d1720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000280208417f6a220341054b0d1502400240024002400240024020030e06000102030405000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d67200341017422042000200420004b1b22044100480d670240024020030d002004102821000c010b200128020020032004102c21000b2000450d1d20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c1a0b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d66200341017422052004200520044b1b22054100480d660240024020030d002005102821040c010b200128020020032005102c21040b2004450d1d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200028020c2106200041146a2802002203200110b40102400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d66200441017422002005200020054b1b22004100480d660240024020040d002000102821040c010b200128020020042000102c21040b2004450d1e20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109a051a0c190b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d65200341017422052004200520044b1b22054100480d650240024020030d002005102821040c010b200128020020032005102c21040b2004450d1e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000290310210702400240200141046a2802002200200528020022036b4108490d00200128020021000c010b200341086a22042003490d65200041017422032004200320044b1b22034100480d650240024020000d002003102821000c010b200128020020002003102c21000b2000450d1f20012000360200200141046a2003360200200141086a28020021030b200141086a200341086a360200200020036a20073700000c180b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d64200341017422052004200520044b1b22054100480d640240024020030d002005102821040c010b200128020020032005102c21040b2004450d1f20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200028020c2106200041146a2802002203200110b40102400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d64200441017422002005200020054b1b22004100480d640240024020040d002000102821040c010b200128020020042000102c21040b2004450d2020012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109a051a0c170b200141086a2802002103200241043a0018024002402003200141046a280200460d00200128020021050c010b200341016a22042003490d63200341017422052004200520044b1b22044100480d630240024020030d002004102821050c010b200128020020032004102c21050b2005450d2020012005360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200520036a41043a0000200028020c2103200041146a2802002200200110b4012000450d162003200041186c6a2108200141046a2106034020032802002109200341086a2802002200200110b401024002402006280200220a200428020022056b2000490d002001280200210a0c010b200520006a220b2005490d64200a4101742205200b2005200b4b1b22054100480d6402400240200a0d0020051028210a0c010b2001280200200a2005102c210a0b200a450d222001200a36020020062005360200200428020021050b2004200520006a360200200a20056a20092000109a051a2003410c6a2802002109200341146a2802002200200110b401024002402006280200220a200428020022056b2000490d002001280200210a0c010b200520006a220b2005490d64200a4101742205200b2005200b4b1b22054100480d6402400240200a0d0020051028210a0c010b2001280200200a2005102c210a0b200a450d232001200a36020020062005360200200428020021050b2004200520006a360200200a20056a20092000109a051a200341186a22032008470d000c170b0b200241053a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d62200341017422052004200520044b1b22054100480d620240024020030d002005102821040c010b200128020020032005102c21040b2004450d2220012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41053a0000200028020c2104200041146a2802002203200110b4012003450d1520042003410c6c6a2108200141046a210903402004280200210a200441086a2802002203200110b4010240024020092802002205200628020022006b2003490d00200128020021050c010b200020036a220b2000490d6320054101742200200b2000200b4b1b22004100480d630240024020050d002000102821050c010b200128020020052000102c21050b2005450d242001200536020020092000360200200628020021000b2006200020036a360200200520006a200a2003109a051a2004410c6a22042008470d000c160b0b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d61200341017422042000200420004b1b22044100480d610240024020030d002004102821000c010b200128020020032004102c21000b2000450d2320012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41013a00000c130b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d60200341017422052004200520044b1b22054100480d600240024020030d002005102821040c010b200128020020032005102c21040b2004450d2320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d60200341017422052004200520044b1b22054100480d600240024020030d002005102821040c010b200128020020032005102c21040b2004450d2420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041086a200110a1010c130b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5f200341017422052004200520044b1b22054100480d5f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d2420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5f200341017422052004200520044b1b22054100480d5f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d2520012004360200200141046a2005360200200141086a28020021030b200141086a220a200341016a360200200420036a41003a00002000280204210c2000410c6a2802002203200110b4012003450d12200c200341f0006c6a210d200141046a210b034020022001360208200c41106a200241086a10c801200c200110a00120022001360208200c41306a200241086a10c80120022001360208200c41d0006a200241086a10c801200c2802042104200c28020c2203200110b40102402003450d00200341246c21090340200241086a200410ec012002280208210602400240200b2802002205200a28020022036b20022802102200490d00200128020021050c010b200320006a22082003490d62200541017422032008200320084b1b22034100480d620240024020050d002003102821050c010b200128020020052003102c21050b2005450d2920012005360200200b2003360200200a28020021030b200a200320006a360200200520036a20062000109a051a0240200228020c450d002006102a0b200441246a21042009415c6a22090d000b0b200c41f0006a220c200d470d000c130b0b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d5e200341017422042000200420004b1b22044100480d5e0240024020030d002004102821000c010b200128020020032004102c21000b2000450d2620012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41043a00000c100b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5d200341017422052004200520044b1b22054100480d5d0240024020030d002005102821040c010b200128020020032005102c21040b2004450d2620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a00002000280208417f6a220341024b0d10024002400240024020030e03000102000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d60200341017422052004200520044b1b22044100480d600240024020030d002004102821050c010b200128020020032004102c21050b2005450d2a20012005360200200141046a2004360200200141086a28020021030b200041306a2104200141086a200341016a360200200520036a41003a00002000410c6a200110a601200241146a21030c020b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d5f200341017422052004200520044b1b22044100480d5f0240024020030d002004102821050c010b200128020020032004102c21050b2005450d2a20012005360200200141046a2004360200200141086a28020021030b200041c0006a2104200141086a200341016a360200200520036a41013a00002000410c6a200110a6012002200041306a360218200241186a200110a3012002411c6a21030c010b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d5e200341017422052004200520044b1b22044100480d5e0240024020030d002004102821050c010b200128020020032004102c21050b2005450d2a20012005360200200141046a2004360200200141086a28020021030b200041d8006a2104200141086a200341016a360200200520036a41023a00002000410c6a200110a601200041306a200110a601200241086a21030b200320043602002003200110a3010c100b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c200341017422052004200520044b1b22054100480d5c0240024020030d002005102821040c010b200128020020032005102c21040b2004450d2920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a000020002d0008417f6a2203410c4b0d0f024002400240024002400240024002400240024002400240024020030e0d000102030405060708090a0b0c000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d68200341017422052004200520044b1b22054100480d680240024020030d002005102821040c010b200128020020032005102c21040b2004450d3620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000410c6a200110a6012002200041306a360208200241086a200110a30120002d0009220341024b0d1b02400240024020030e03000102000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d6a200341017422042000200420004b1b22044100480d6a0240024020030d002004102821000c010b200128020020032004102c21000b2000450d3920012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c1d0b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d69200341017422042000200420004b1b22044100480d690240024020030d002004102821000c010b200128020020032004102c21000b2000450d3920012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41013a00000c1c0b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d68200341017422042000200420004b1b22044100480d680240024020030d002004102821000c010b200128020020032004102c21000b2000450d3920012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41023a00000c1b0b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d67200341017422052004200520044b1b22054100480d670240024020030d002005102821040c010b200128020020032005102c21040b2004450d3920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002002200041106a360208200241086a200110a3010c1a0b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d66200341017422052004200520044b1b22054100480d660240024020030d002005102821040c010b200128020020032005102c21040b2004450d3920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002002200041106a360208200241086a200110a3010c190b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d65200341017422042000200420004b1b22044100480d650240024020030d002004102821000c010b200128020020032004102c21000b2000450d3920012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41033a00000c180b200141086a2802002103200241043a0018024002402003200141046a280200460d00200128020021040c010b200341016a22042003490d64200341017422052004200520044b1b22054100480d640240024020030d002005102821040c010b200128020020032005102c21040b2004450d3920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41043a00002002200041106a360208200241086a200110a3010c170b200241053a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d63200341017422052004200520044b1b22054100480d630240024020030d002005102821040c010b200128020020032005102c21040b2004450d3920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a0000200028020c2103200041146a2802002200200110b4012000450d16200041246c210003402003200110a601200341246a21032000415c6a22000d000c170b0b200241063a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d62200341017422042000200420004b1b22044100480d620240024020030d002004102821000c010b200128020020032004102c21000b2000450d3920012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41063a00000c150b200241073a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d61200341017422052004200520044b1b22054100480d610240024020030d002005102821040c010b200128020020032005102c21040b2004450d3920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a000020002d0009220341024b0d1402400240024020030e03000102000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d63200341017422042000200420004b1b22044100480d630240024020030d002004102821000c010b200128020020032004102c21000b2000450d3c20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c160b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d62200341017422042000200420004b1b22044100480d620240024020030d002004102821000c010b200128020020032004102c21000b2000450d3c20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41013a00000c150b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d61200341017422042000200420004b1b22044100480d610240024020030d002004102821000c010b200128020020032004102c21000b2000450d3c20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41023a00000c140b200141046a2802002104200241083a0018024002402004200141086a2802002203460d00200128020021040c010b200341016a22042003490d60200341017422052004200520044b1b22054100480d600240024020030d002005102821040c010b200128020020032005102c21040b2004450d3c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a00002000410c6a200110a6010c130b200241093a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5f200341017422052004200520044b1b22054100480d5f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d3c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a00002000410c6a200110a0010c120b2002410a3a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d5e200341017422042000200420004b1b22044100480d5e0240024020030d002004102821000c010b200128020020032004102c21000b2000450d3c20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a410a3a00000c110b2002410b3a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d5d200341017422042000200420004b1b22044100480d5d0240024020030d002004102821000c010b200128020020032004102c21000b2000450d3c20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a410b3a00000c100b2002410c3a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c200341017422052004200520044b1b22054100480d5c0240024020030d002005102821040c010b200128020020032005102c21040b2004450d3c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a0000200028020c2103200041146a2802002200200110b4012000450d0f20004105742100034020032001108f01200341206a2103200041606a22000d000c100b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102821040c010b200128020020032005102c21040b2004450d3c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41073a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102821040c010b200128020020032005102c21040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041106a2001108f01200041306a2001108f01200041d0006a2001108f01200028020421062000410c6a2802002203200110b40102400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d5b200441017422002005200020054b1b22004100480d5b0240024020040d002000102821040c010b200128020020042000102c21040b2004450d3e20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109a051a0c0e0b02400240200141046a2206280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d5a2003410174220a2005200a20054b1b220a4100480d5a0240024020030d00200a102821050c010b20012802002003200a102c21050b2005450d3e20012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41083a0000200041086a22052d0000417f6a220341104b0d0d0240024002400240024002400240024002400240024002400240024002400240024020030e11000102030405060708090a0b0c0d0e0f10000b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6a200341017422052004200520044b1b22054100480d6a0240024020030d002005102821040c010b200128020020032005102c21040b2004450d4f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200028020c200110eb012002200041106a360208200241086a200110a3010c1d0b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d69200341017422052004200520044b1b22054100480d690240024020030d002005102821040c010b200128020020032005102c21040b2004450d4f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a200110a0010c1c0b02400240200628020020042802002203460d00200128020021060c010b200341016a22062003490d682003410174220a2006200a20064b1b220a4100480d680240024020030d00200a102821060c010b20012802002003200a102c21060b2006450d4f20012006360200200141046a200a360200200141086a28020021030b200141086a220a200341016a360200200620036a41023a00002000410c6a200110a00120052d00012106200541026a2d0000210502400240200141046a280200200a2802002203460d00200128020021000c010b200341016a22002003490d682003410174220a2000200a20004b1b220a4100480d680240024020030d00200a102821000c010b20012802002003200a102c21000b2000450d5020012000360200200141046a200a360200200141086a28020021030b2004200341016a360200200020036a20064100474107742005723a00000c1b0b02400240200628020020042802002203460d00200128020021060c010b200341016a22062003490d672003410174220a2006200a20064b1b220a4100480d670240024020030d00200a102821060c010b20012802002003200a102c21060b2006450d5020012006360200200141046a200a360200200141086a28020021030b200141086a220a200341016a360200200620036a41033a00002000410c6a200110a00120052d00012106200541026a2d0000210502400240200141046a280200200a2802002203460d00200128020021000c010b200341016a22002003490d672003410174220a2000200a20004b1b220a4100480d670240024020030d00200a102821000c010b20012802002003200a102c21000b2000450d5120012000360200200141046a200a360200200141086a28020021030b2004200341016a360200200020036a20064100474107742005723a00000c1a0b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d662003410174220a2005200a20054b1b220a4100480d660240024020030d00200a102821050c010b20012802002003200a102c21050b2005450d5120012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41043a0000200028020c21050240024020062802002200200428020022036b4104490d00200128020021000c010b200341046a22062003490d66200041017422032006200320064b1b22034100480d660240024020000d002003102821000c010b200128020020002003102c21000b2000450d5220012000360200200141046a2003360200200141086a28020021030b2004200341046a360200200020036a20053600000c190b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d65200341017422052004200520044b1b22054100480d650240024020030d002005102821040c010b200128020020032005102c21040b2004450d5220012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a0000200028020c200110eb010c180b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d64200341017422052004200520044b1b22054100480d640240024020030d002005102821040c010b200128020020032005102c21040b2004450d5220012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a0000200028020c200110eb010c170b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d63200341017422052004200520044b1b22054100480d630240024020030d002005102821040c010b200128020020032005102c21040b2004450d5220012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a0000200028020c200110eb010c160b02400240200628020020042802002203460d002001280200210a0c010b200341016a220a2003490d6220034101742209200a2009200a4b1b22094100480d620240024020030d0020091028210a0c010b200128020020032009102c210a0b200a450d522001200a360200200141046a2009360200200141086a28020021030b200141086a2209200341016a360200200a20036a41083a000020022001360208200541016a200241086a10c801200028022c210a02400240200141046a2802002205200928020022036b4104490d00200128020021050c010b200341046a22092003490d62200541017422032009200320094b1b22034100480d620240024020050d002003102821050c010b200128020020052003102c21050b2005450d5320012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a200a360000200028023021050240024020062802002200200428020022036b4104490d00200128020021000c010b200341046a22062003490d62200041017422032006200320064b1b22034100480d620240024020000d002003102821000c010b200128020020002003102c21000b2000450d5420012000360200200141046a2003360200200141086a28020021030b2004200341046a360200200020036a20053600000c150b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d61200341017422042000200420004b1b22044100480d610240024020030d002004102821000c010b200128020020032004102c21000b2000450d5420012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41093a000020022001360208200541016a200241086a10c8010c140b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d60200341017422052004200520044b1b22054100480d600240024020030d002005102821040c010b200128020020032005102c21040b2004450d5420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a00002000410c6a200110a0010c130b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5f200341017422052004200520044b1b22054100480d5f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d5420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a00002000410c6a200110a001200041106a200110a001200041146a200110a0010c120b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5e200341017422042000200420004b1b22044100480d5e0240024020030d002004102821000c010b200128020020032004102c21000b2000450d5420012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a410c3a0000200541016a2001108f010c110b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5d200341017422052000200520004b1b22054100480d5d0240024020030d002005102821000c010b200128020020032005102c21000b2000450d5420012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a410d3a00000c100b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5c200341017422042000200420004b1b22044100480d5c0240024020030d002004102821000c010b200128020020032004102c21000b2000450d5420012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a410e3a0000200541016a2001108f010c0f0b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5b2003410174220a2000200a20004b1b220a4100480d5b0240024020030d00200a102821000c010b20012802002003200a102c21000b2000450d5420012000360200200141046a200a360200200141086a28020021030b200141086a200341016a360200200020036a410f3a0000200541016a2001108f0120052d0021220341064b0d0e0240024002400240024002400240024020030e0700010203040506000b410021000c060b410121000c050b410221000c040b410321000c030b410421000c020b410521000c010b410621000b200220003a001802400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5b200341017422062005200620054b1b22064100480d5b0240024020030d002006102821050c010b200128020020032006102c21050b2005450d5520012005360200200141046a2006360200200141086a28020021030b2004200341016a360200200520036a20003a00000c0e0b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5a200341017422052000200520004b1b22054100480d5a0240024020030d002005102821000c010b200128020020032005102c21000b2000450d5520012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41103a00000c0d0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d59200341017422052004200520044b1b22054100480d590240024020030d002005102821040c010b200128020020032005102c21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a0000200041046a200110ed010c0c0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d58200341017422052004200520044b1b22054100480d580240024020030d002005102821040c010b200128020020032005102c21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a0000200041046a200110ed010c0b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d57200341017422052004200520044b1b22054100480d570240024020030d002005102821040c010b200128020020032005102c21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a00002000280208417f6a220341094b0d0a024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d60200341017422052004200520044b1b22054100480d600240024020030d002005102821040c010b200128020020032005102c21040b2004450d5f20012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41003a0000200028020c2104200041146a280200220a200110b4010240200a450d00200141046a2109034002400240200928020020062802002203460d00200128020021050c010b200341016a22052003490dad012003410174220b2005200b20054b1b220b4100480dad010240024020030d00200b102821050c010b20012802002003200b102c21050b2005450d63200120053602002009200b360200200628020021030b2006200341016a360200200520036a20042d00003a0000200441016a2104200a417f6a220a0d000b0b200041186a200110a001200028021c210502400240200141046a2802002204200628020022036b4104490d00200128020021040c010b200341046a22062003490dab01200441017422032006200320064b1b22034100480dab010240024020040d002003102821040c010b200128020020042003102c21040b2004450d6220012004360200200141046a2003360200200141086a28020021030b200141086a2206200341046a360200200420036a2005360000200041286a29030021072000290320210e02400240200141046a2802002200200628020022036b4110490d00200128020021000c010b200341106a22042003490dab01200041017422032004200320044b1b22034100480dab010240024020000d002003102821000c010b200128020020002003102c21000b2000450d6320012000360200200141046a2003360200200141086a28020021030b200141086a200341106a360200200020036a220320073700082003200e3700000c130b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490daa01200341017422052004200520044b1b22054100480daa010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6320012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41013a0000200028020c2104200041146a280200220a200110b4010240200a450d00200141046a2109034002400240200928020020062802002203460d00200128020021050c010b200341016a22052003490dac012003410174220b2005200b20054b1b220b4100480dac010240024020030d00200b102821050c010b20012802002003200b102c21050b2005450d66200120053602002009200b360200200628020021030b2006200341016a360200200520036a20042d00003a0000200441016a2104200a417f6a220a0d000b0b200041186a200110a001200028021c210502400240200141046a2802002204200628020022036b4104490d00200128020021040c010b200341046a22062003490daa01200441017422032006200320064b1b22034100480daa010240024020040d002003102821040c010b200128020020042003102c21040b2004450d6520012004360200200141046a2003360200200141086a28020021030b200141086a2206200341046a360200200420036a2005360000200041286a29030021072000290320210e02400240200141046a2802002200200628020022036b4110490d00200128020021000c010b200341106a22042003490daa01200041017422032004200320044b1b22034100480daa010240024020000d002003102821000c010b200128020020002003102c21000b2000450d6620012000360200200141046a2003360200200141086a28020021030b200141086a200341106a360200200020036a220320073700082003200e3700000c120b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da901200341017422052004200520044b1b22054100480da9010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a200110a001200041106a200110a601200041346a200110a001200041386a200110a0010c110b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da801200341017422052004200520044b1b22054100480da8010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a00002000410c6a200110a0010c100b200141086a2802002103200241043a0018024002402003200141046a280200460d00200128020021040c010b200341016a22042003490da701200341017422052004200520044b1b22054100480da7010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41043a00002000410c6a200110a0010c0f0b200241053a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da601200341017422052004200520044b1b22054100480da6010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a00002000410c6a200110a6012002200041386a360208200241086a200110a301200041306a200110a0010c0e0b200241063a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da501200341017422052004200520044b1b22054100480da5010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a00002000410c6a200110a0010c0d0b200241073a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da401200341017422052004200520044b1b22054100480da4010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a00002000410c6a200110a6010c0c0b200141046a2802002104200241083a0018024002402004200141086a2802002203460d00200128020021040c010b200341016a22042003490da301200341017422052004200520044b1b22054100480da3010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a00002000410c6a200110a0010c0b0b200241093a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da201200341017422052004200520044b1b22054100480da2010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a00002000410c6a200110a0010c0a0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da101200341017422052004200520044b1b22054100480da1010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a0000200041046a22042d0000417f6a220341034b0d09024002400240024020030e0400010203000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490da401200341017422052000200520004b1b22054100480da4010240024020030d002005102821000c010b200128020020032005102c21000b2000450d6a20012000360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200020036a41003a0000200441016a2001108f010c0c0b200141086a2802002103200141046a2802002100200241013a00180240024020002003460d00200128020021000c010b200341016a22002003490da301200341017422052000200520004b1b22054100480da3010240024020030d002005102821000c010b200128020020032005102c21000b2000450d6a20012000360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200020036a41013a0000200441016a2001108f010c0b0b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490da201200341017422052000200520004b1b22054100480da2010240024020030d002005102821000c010b200128020020032005102c21000b2000450d6a20012000360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200020036a41023a0000200441016a2001108f01200441216a2001108f010c0a0b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da101200341017422052004200520044b1b22054100480da1010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a000020002802082103200041106a2802002200200110b4012000450d0920004105742100034020032001108f01200341206a2103200041606a22000d000c0a0b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da001200341017422052004200520044b1b22054100480da0010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410d3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490da001200341017422052004200520044b1b22054100480da0010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6b20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041046a200110a0010c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f01200341017422052004200520044b1b22054100480d9f010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410e3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d9f01200341017422052004200520044b1b22054100480d9f010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200028020421062000410c6a2802002203200110b40102400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9f01200441017422002005200020054b1b22004100480d9f010240024020040d002000102821040c010b200128020020042000102c21040b2004450d6d20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109a051a0c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e01200341017422052004200520044b1b22054100480d9e010240024020030d002005102821040c010b200128020020032005102c21040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410f3a00002000280208417f6a220341024b0d0602400240024020030e03000102000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da001200341017422052004200520044b1b22054100480da0010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002002200041306a360208200241086a200110a3012000410c6a200110a6010c080b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f01200341017422052004200520044b1b22054100480d9f010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a200110a0010c070b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e01200341017422052004200520044b1b22054100480d9e010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a200110a0010c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d01200341017422052004200520044b1b22054100480d9d010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41103a0000200041086a22042d0000417f6a220341044b0d050240024002400240024020030e050001020304000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da101200341017422052004200520044b1b22054100480da1010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041106a200110ee010c090b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da001200341017422052004200520044b1b22054100480da0010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041186a200110a101200028020c2106200041146a2802002203200110b40102400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490da001200441017422002005200020054b1b22004100480da0010240024020040d002000102821040c010b200128020020042000102c21040b2004450d7620012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109a051a0c080b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f01200341017422052004200520044b1b22054100480d9f010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000410c6a200110a6012002200041c0006a360208200241086a200110a301200041d0006a200110a10120002802302106200041386a2802002203200110b40102400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9f01200441017422002005200020054b1b22004100480d9f010240024020040d002000102821040c010b200128020020042000102c21040b2004450d7720012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109a051a0c070b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22052003490d9e01200341017422062005200620054b1b22064100480d9e010240024020030d002006102821050c010b200128020020032006102c21050b2005450d7720012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a41033a00002002200041386a360208200241086a200110a301200041c8006a200110a10120022001360208200441016a200241086a10c801200028022c2105200041346a2802002203200110b40102400240200141046a2802002204200628020022006b2003490d00200128020021040c010b200020036a22062000490d9e01200441017422002006200020064b1b22004100480d9e010240024020040d002000102821040c010b200128020020042000102c21040b2004450d7820012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20052003109a051a0c060b200141086a2802002103200241043a0018024002402003200141046a280200460d00200128020021000c010b200341016a22002003490d9d01200341017422052000200520004b1b22054100480d9d010240024020030d002005102821000c010b200128020020032005102c21000b2000450d7820012000360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200020036a41043a0000200441016a2001108f01024020042d00214101460d00200241003a001802400240200141046a28020020052802002203460d00200128020021000c010b200341016a22002003490d9e01200341017422042000200420004b1b22044100480d9e010240024020030d002004102821000c010b200128020020032004102c21000b2000450d7a20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c060b200241013a001802400240200141046a28020020052802002203460d00200128020021000c010b200341016a22002003490d9d01200341017422052000200520004b1b22054100480d9d010240024020030d002005102821000c010b200128020020032005102c21000b2000450d7a20012000360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200020036a41013a0000200441226a2001108f010c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c01200341017422052004200520044b1b22054100480d9c010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41113a00002000280204417f6a220341024b0d0402400240024020030e03000102000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e01200341017422052004200520044b1b22054100480d9e010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000280208200110eb010c060b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d01200341017422052004200520044b1b22054100480d9d010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041086a200110a6010c050b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c01200341017422052004200520044b1b22054100480d9c010240024020030d002005102821040c010b200128020020032005102c21040b2004450d7d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a0000200041086a200110a601200028022c200110eb010c040b02400240200141046a220a280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d9b01200441017422062005200620054b1b22064100480d9b010240024020040d002006102821050c010b200128020020042006102c21050b2005450d7d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a41123a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b01200441017422062005200620054b1b22064100480d9b010240024020040d002006102821050c010b200128020020042006102c21050b2005450d7e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a41003a00002000280204210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d9b01200541017422042009200420094b1b22044100480d9b010240024020050d002004102821050c010b200128020020052004102c21050b2005450d7f20012005360200200141046a2004360200200141086a28020021040b200141086a2209200441046a360200200520046a2006360000200041086a280200210b200041106a2802002204200110b40102400240200141046a2802002206200928020022056b2004490d00200128020021060c010b200520046a22092005490d9b01200641017422052009200520094b1b22054100480d9b010240024020060d002005102821060c010b200128020020062005102c21060b2006450d800120012006360200200141046a2005360200200141086a28020021050b200141086a2208200520046a360200200620056a200b2004109a051a200041146a28020021062000411c6a2802002204200110b40102402004450d0020062004410c6c6a210f200141046a210c03402006280200210b200641086a2802002204200110b40102400240200c2802002209200828020022056b2004490d00200128020021090c010b200520046a220d2005490d9d0120094101742205200d2005200d4b1b22054100480d9d010240024020090d002005102821090c010b200128020020092005102c21090b2009450d830120012009360200200c2005360200200828020021050b2003200520046a360200200920056a200b2004109a051a2006410c6a2206200f470d000b0b200041206a280200210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d9b01200541017422042009200420094b1b22044100480d9b010240024020050d002004102821050c010b200128020020052004102c21050b2005450d820120012005360200200141046a2004360200200141086a28020021040b2003200441046a360200200520046a2006360000200041246a280200210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d9b01200541017422042009200420094b1b22044100480d9b010240024020050d002004102821050c010b200128020020052004102c21050b2005450d830120012005360200200141046a2004360200200141086a28020021040b2003200441046a360200200520046a200636000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b01200441017422062005200620054b1b22064100480d9b010240024020040d002006102821050c010b200128020020042006102c21050b2005450d840120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a200041286a22042d00003a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d850120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00013a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d860120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d002a3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d870120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00033a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d880120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d002c3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d890120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00053a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d8a0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d002e3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d8b0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00073a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d8c0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00303a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d8d0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00093a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d8e0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00323a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d8f0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d000b3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d900120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00343a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d910120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d000d3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d920120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00363a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d930120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d000f3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d940120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00383a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d950120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00113a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d960120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d003a3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d970120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00133a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d980120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d003c3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d990120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00153a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490d9b01200541017422092006200920064b1b22094100480d9b010240024020050d002009102821060c010b200128020020052009102c21060b2006450d9a0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d003e3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450d9c0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00173a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450d9d0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00403a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450d9e0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00193a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450d9f0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00423a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da00120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d001b3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da10120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00443a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da20120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d001d3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da30120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00463a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da40120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d001f3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da50120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00483a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da60120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00213a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da70120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d004a3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da80120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00233a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450da90120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d004c3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450daa0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00253a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dab0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d004e3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dac0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00273a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dad0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00503a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dae0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00293a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450daf0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00523a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db00120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d002b3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db10120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00543a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db20120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d002d3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db30120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00563a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db40120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d002f3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db50120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00583a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db60120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00313a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db70120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d005a3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db80120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00333a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450db90120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d005c3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dba0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00353a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dbb0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d005e3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dbc0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00373a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dbd0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00603a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dbe0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d00393a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dbf0120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00623a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dc00120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20042d003b3a000002400240200a28020020032802002205460d00200128020021060c010b200541016a22062005490dc701200541017422092006200920064b1b22094100480dc7010240024020050d002009102821060c010b200128020020052009102c21060b2006450dc10120012006360200200141046a2009360200200141086a28020021050b2003200541016a360200200620056a20002d00643a000002400240200a28020020032802002200460d00200128020021050c010b200041016a22052000490dc701200041017422062005200620054b1b22064100480dc7010240024020000d002006102821050c010b200128020020002006102c21050b2005450dc20120012005360200200141046a2006360200200141086a28020021000b2003200041016a360200200520006a20042d003d3a000002400240200a28020020032802002200460d00200128020021050c010b200041016a22052000490dc701200041017422062005200620054b1b22064100480dc7010240024020000d002006102821050c010b200128020020002006102c21050b2005450dc30120012005360200200141046a2006360200200141086a28020021000b2003200041016a360200200520006a20042d003e3a000002400240200a28020020032802002200460d00200128020021050c010b200041016a22052000490dc701200041017422062005200620054b1b22064100480dc7010240024020000d002006102821050c010b200128020020002006102c21050b2005450dc40120012005360200200141046a2006360200200141086a28020021000b2003200041016a360200200520006a20042d003f3a00000c030b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490dc601200341017422042000200420004b1b22044100480dc6010240024020030d002004102821000c010b200128020020032004102c21000b2000450dc40120012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41133a00000c010b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490dc501200341017422042000200420004b1b22044100480dc5010240024020030d002004102821000c010b200128020020032004102c21000b2000450dc40120012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41143a00000b200110c4010b200241206a24000f0b200541011037000b200441011037000b200541011037000b200041011037000b200541011037000b200341011037000b200541011037000b200041011037000b200441011037000b200541011037000b200541011037000b200541011037000b200041011037000b200441011037000b200541011037000b200541011037000b200541011037000b200541011037000b200341011037000b200441011037000b200541011037000b200441011037000b200441011037000b200441011037000b200541011037000b200541011037000b200441011037000b200441011037000b200441011037000b200541011037000b200541011037000b200441011037000b200541011037000b200541011037000b200441011037000b200541011037000b200441011037000b200441011037000b200441011037000b200541011037000b200541011037000b200441011037000b200441011037000b200541011037000b200541011037000b200541011037000b200041011037000b200a41011037000b200541011037000b200541011037000b200a41011037000b200a41011037000b200a41011037000b200a41011037000b200a41011037000b200341011037000b200541011037000b200541011037000b200541011037000b200941011037000b200341011037000b200341011037000b200441011037000b200541011037000b200541011037000b200441011037000b200541011037000b200441011037000b200a41011037000b200641011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b1031000b200b41011037000b200341011037000b200341011037000b200541011037000b200b41011037000b200341011037000b200341011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200041011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200041011037000b200541011037000b200041011037000b200641011037000b200041011037000b200541011037000b200441011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200641011037000b200641011037000b200441011037000b200541011037000b200541011037000b200441011037000b200441011037000b200641011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b1031000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200941011037000b200641011037000b200641011037000b200641011037000b200441011037000b200441011037000b1031000bb31601067f230041106b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e050003010204000b2002410036020820024201370300410110282203450d05200242818080801037020420022003360200200341023a00002002200236020c200141016a2002410c6a10c8010c040b2002410036020820024201370300410110282203450d05200242818080801037020420022003360200200341043a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a200341017422052004200520044b1b22054100480d1a0240024020030d002005102821040c010b200228020020032005102c21040b2004450d0720022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a200341017422052004200520044b1b22054100480d1a0240024020030d002005102821040c010b200228020020032005102c21040b2004450d0820022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a200341017422052004200520044b1b22054100480d1a0240024020030d002005102821040c010b200228020020032005102c21040b2004450d0920022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a200341017422052004200520044b1b22054100480d1a0240024020030d002005102821040c010b200228020020032005102c21040b2004450d0a20022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210b4010240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d1a200441017422072006200720064b1b22064100480d1a0240024020040d002006102821040c010b200228020020042006102c21040b2004450d0b20022006360204200220043602000b2002200320016a360208200420036a20052001109a051a0c030b2002410036020820024201370300410110282203450d0a200242818080801037020420022003360200200341053a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d19200341017422052004200520044b1b22054100480d190240024020030d002005102821040c010b200228020020032005102c21040b2004450d0c20022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d19200341017422052004200520044b1b22054100480d190240024020030d002005102821040c010b200228020020032005102c21040b2004450d0d20022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d19200341017422052004200520044b1b22054100480d190240024020030d002005102821040c010b200228020020032005102c21040b2004450d0e20022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d19200341017422052004200520044b1b22054100480d190240024020030d002005102821040c010b200228020020032005102c21040b2004450d0f20022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210b4010240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d19200441017422072006200720064b1b22064100480d190240024020040d002006102821040c010b200228020020042006102c21040b2004450d1020022006360204200220043602000b2002200320016a360208200420036a20052001109a051a0c020b2002410036020820024201370300410110282203450d0f200242818080801037020420022003360200200341063a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d18200341017422052004200520044b1b22054100480d180240024020030d002005102821040c010b200228020020032005102c21040b2004450d1120022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d18200341017422052004200520044b1b22054100480d180240024020030d002005102821040c010b200228020020032005102c21040b2004450d1220022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d18200341017422052004200520044b1b22054100480d180240024020030d002005102821040c010b200228020020032005102c21040b2004450d1320022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d18200341017422052004200520044b1b22054100480d180240024020030d002005102821040c010b200228020020032005102c21040b2004450d1420022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210b4010240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d18200441017422072006200720064b1b22064100480d180240024020040d002006102821040c010b200228020020042006102c21040b2004450d1520022006360204200220043602000b2002200320016a360208200420036a20052001109a051a0c010b2002410036020820024201370300410110282203450d14200242818080801037020420022003360200200341003a0000200141046a28020021052001410c6a2802002201200210b4010240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d17200441017422072006200720064b1b22064100480d170240024020040d002006102821040c010b200228020020042006102c21040b2004450d1620022006360204200220043602000b2002200320016a360208200420036a20052001109a051a0b200020022201290200370200200041086a200141086a280200360200200241106a24000f0b410141011037000b410141011037000b200541011037000b200541011037000b200541011037000b200541011037000b200641011037000b410141011037000b200541011037000b200541011037000b200541011037000b200541011037000b200641011037000b410141011037000b200541011037000b200541011037000b200541011037000b200541011037000b200641011037000b410141011037000b200641011037000b1031000b800801047f230041106b22022400024002400240024002400240024020002d0000417f6a220341034b0d00024002400240024020030e0400010203000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0a200341017422052004200520044b1b22054100480d0a0240024020030d002005102821040c010b200128020020032005102c21040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200028020421032000410c6a2802002200200110b4012000450d0320004105742100034020032001108f01200341206a2103200041606a22000d000c040b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d09200341017422052004200520044b1b22054100480d090240024020030d002005102821040c010b200128020020032005102c21040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000280204200110eb010c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d08200341017422052004200520044b1b22054100480d080240024020030d002005102821040c010b200128020020032005102c21040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a0000200041046a200110a0012000280208200110eb010c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d07200341017422052004200520044b1b22054100480d070240024020030d002005102821040c010b200128020020032005102c21040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a00002002200136020c200041016a2002410c6a10c801200041246a200110a00102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d07200341017422052004200520044b1b22054100480d070240024020030d002005102821040c010b200128020020032005102c21040b2004450d0620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00213a00000b200241106a24000f0b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b1031000bf71802047f017e20002802582102024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2802002203200141086a28020022046b4104490d00200128020021030c010b200441046a22052004490d13200341017422042005200420054b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0120012003360200200141046a2004360200200141086a28020021040b200141086a2205200441046a360200200320046a20023600002000290300210602400240200141046a2802002203200528020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0220012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290308210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0320012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290310210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0420012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290318210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0520012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290320210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0620012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290328210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0720012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290330210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0820012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290338210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0920012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290340210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0a20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290348210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0b20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290350210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0c20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a2006370000200028025c210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0d20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280260210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0e20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280264210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d0f20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280268210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d13200341017422042002200420024b1b22044100480d130240024020030d002004102821030c010b200128020020032004102c21030b2003450d1020012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a200536000002400240200141046a28020020022802002204460d00200128020021030c010b200441016a22032004490d13200441017422022003200220034b1b22024100480d130240024020040d002002102821030c010b200128020020042002102c21030b2003450d1120012003360200200141046a2002360200200141086a28020021040b200141086a2202200441016a360200200320046a20002d00703a0000200028026c210302400240200141046a2802002204200228020022006b4104490d00200128020021040c010b200041046a22022000490d13200441017422002002200020024b1b22004100480d130240024020040d002000102821040c010b200128020020042000102c21040b2004450d1220012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a20033600000f0b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200241011037000b200041011037000b1031000bb90201057f230041106b2203240020034100360208200342013703002001200310b4010240024002402001450d00200141b0016c2104034020004188016a28020021050240024020032802042206200328020822016b4104490d00200328020021060c010b200141046a22072001490d04200641017422012007200120074b1b22014100480d040240024020060d002001102821060c010b200328020020062001102c21060b2006450d032003200136020420032006360200200328020821010b2003200141046a360208200620016a20053600002000200310eb012000418c016a2003108f01200041b0016a2100200441d07e6a22040d000b0b2003280204210020022802002002280204200328020022012003280208100702402000450d002001102a0b200341106a24000f0b200141011037000b1031000bee1405177f017e017f027e047f230041206b220224000240024020014115490d0002402001410176220341ffffff3f712003470d0020034105742204417f4c0d0041012105024002402004450d00200410282205450d010b200041606a2106200041a07f6a210741002108410021094104210a4100210b2001210c034002400240200c220d417f6a220e0d004101210f4100210c0c010b0240024002400240024002402000200e4105746a200d410574221020006a41406a4120109c054100480d004102200d6b210e200720106a21044101210f03400240200e200f6a4101470d004100210c200d210f0c080b200f41016a210f200441206a20044120109c052111200441606a21042011417f4a0d000b200d200f6b210e0c010b200720106a2104024003400240200e4101470d004100210e0c020b200e417f6a210e200441206a20044120109c052111200441606a210420114100480d000b0b200d200e490d01200d20014b0d03200d200e6b220f4101762212450d00200620106a21042000200e4105746a21110340200241186a2210201141186a2213290000370300200241106a2214201141106a2215290000370300200241086a2216201141086a221729000037030020022011290000370300200441086a22182900002119200441106a221a290000211b200441186a220c290000211c201120042900003700002013201c3700002015201b37000020172019370000200c2010290300370000201a20142903003700002018201629030037000020042002290300370000200441606a2104201141206a21112012417f6a22120d000b0b0240200e0d00200e210c0c050b0240200f41094d0d00200e210c0c050b200d20014b0d01200d200e6b21122000200e4105746a21100340200d200e417f6a220c490d040240200d200c6b220f4102490d002000200e4105746a22042000200c4105746a220e4120109c05417f4a0d00200e2900002119200e2004290000370000200241186a2216200e41186a2211290000370300200241106a2217200e41106a2213290000370300200241086a2218200e41086a22142900003703002014200441086a2900003700002013200441106a2900003700002011200441186a29000037000020022019370300410121150240200f4103490d00200e41c0006a20024120109c05417f4a0d00410221112010210402400340200441186a200441386a290000370000200441106a200441306a290000370000200441086a200441286a2900003700002004200441206a221329000037000020122011460d01200441c0006a21142011211520132104201141016a2111201420024120109c05417f4a0d020c000b0b201121150b200e20154105746a22042002290300370000200441186a2016290300370000200441106a2017290300370000200441086a20182903003700000b200c450d05201041606a2110201241016a2112200c210e200f410a4f0d050c000b0b200e200d1044000b200d200e417f6a220c490d010b200d2001103c000b200c200d1044000b024002400240200b2009470d0002400240200941016a22042009490d00200941017422112004201120044b1b220441ffffffff01712004470d002004410374221141004e0d010b1031000b0240024020090d0020111028210a0c010b200a20094103742011102c210a0b200a450d01200421092008210b0b200a200b4103746a2204200f3602042004200c360200200841016a220b2108200b4102490d01024003400240024002400240200a200b417f6a22084103746a2204280200450d00200b410374200a6a220f41746a280200220e200428020422114d0d000240200b41024b0d00200b21084102210b0c080b200a200b417d6a22164103746a28020422042011200e6a4d0d010240200b41034b0d00200b21084103210b0c080b200f41646a2802002004200e6a4d0d01200b21080c070b200b4103490d0120042802042111200a200b417d6a22164103746a28020421040b20042011490d010b200b417e6a21160b024002400240024002400240200b201641016a221d4b221e450d00200b20164b221f450d01200a20164103746a2217280204222020172802006a2204200a201d4103746a2218280200221a490d02200420014b0d032000201a4105746a22142018280204221541057422116a210f2004410574210e2004201a6b220d20156b220420154f0d042005200f20044105742211109a05221320116a21120240024020154101480d00200441014e0d010b200f2104201321110c060b2006200e6a210e200f21040340200e200441606a220f201241606a220d200d200f4120109c0541004822101b2211290000370000200e41186a201141186a290000370000200e41106a201141106a290000370000200e41086a201141086a2900003700002012200d20101b211202402014200f200420101b2204490d00201321110c070b200e41606a210e2013211120132012490d000c060b0b41b8dbc000201d200b1034000b41b8dbc0002016200b1034000b201a20041044000b20042001103c000b200520142011109a05221320116a21120240024020154101480d00200d20154a0d010b20142104201321110c010b2000200e6a2110201321112014210403402004200f2011200f20114120109c05410048220d1b220e290000370000200441186a200e41186a290000370000200441106a200e41106a290000370000200441086a200e41086a2900003700002011201141206a200d1b2111200441206a2104200f41206a200f200d1b220f20104f0d01201220114b0d000b0b20042011201220116b416071109a051a0240201f450d002017201a360200201741046a202020156a360200201e450d022018201841086a200b201d417f736a410374109b051a2008210b200841014d0d040c010b0b41c8dbc0002016200b1034000b41b0b1c0001032000b201141041037000b200c0d000b02402009450d00200a102a0b2003450d032005102a0c030b200441011037000b1036000b20014102490d002001417f6a2111200141057420006a41206a2110410121120340024002400240024020112204417f6a221120014b0d00200120116b220e4102490d03200020044105746a2204200020114105746a220d4120109c05417f4a0d03200d2900002119200d2004290000370000200241186a2214200d41186a220f290000370300200241106a220b200d41106a2213290000370300200241086a2215200d41086a220a290000370300200a200441086a2900003700002013200441106a290000370000200f200441186a2900003700002002201937030041012104200e4103490d02200d41c0006a20024120109c05417f4a0d0241002113201021040340200441406a220e200441606a220f290000370000200e41186a200f41186a290000370000200e41106a200f41106a290000370000200e41086a200f41086a29000037000020122013220e460d02200e417f6a2113200420024120109c05210f200441206a2104200f417f4a0d020c000b0b201120011044000b4102200e6b21040b200d20044105746a22042002290300370000200441186a2014290300370000200441106a200b290300370000200441086a20152903003700000b201041606a21102012417f6a211220110d000b0b200241206a24000ba3950103057f027e027f230041106b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00000e10000102030405060708090a0b0c0d0e0f000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c200341017422052004200520044b1b22054100480d5c0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200141046a28020021042005280200210302402000410c6a2d000022054102470d000240024020042003460d00200128020021000c010b200341016a22002003490d5d200341017422042000200420004b1b22044100480d5d0240024020030d002004102821000c010b200128020020032004102c21000b2000450d1320012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c100b0240024020042003460d00200128020021040c010b200341016a22042003490d5c200341017422062004200620044b1b22064100480d5c0240024020030d002006102821040c010b200128020020032006102c21040b2004450d1320012004360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200420036a41013a00000240024020054101460d0002400240200141046a28020020062802002203460d00200128020021040c010b200341016a22042003490d5e200341017422052004200520044b1b22054100480d5e0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00000c010b02400240200141046a28020020062802002203460d00200128020021040c010b200341016a22042003490d5d200341017422052004200520044b1b22054100480d5d0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5d200341017422052004200520044b1b22054100480d5d0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d000d3a00000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c200341017422052004200520044b1b22054100480d5c0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d000e3a00000c0f0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041086a2001108f012000280204210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d5b200341017422002005200020054b1b22004100480d5b0240024020030d002000102821030c010b200128020020032000102c21030b2003450d1920012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0e0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a200341017422052004200520044b1b22054100480d5a0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a000020002d0008220341024b0d0d02400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c200341017422052004200520044b1b22054100480d5c0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041096a2001108f01200041386a29030021072000290330210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5c200341017422002004200020044b1b22004100480d5c0240024020030d002000102821030c010b200128020020032000102c21030b2003450d1d20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c0f0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041096a2001108f010c0e0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a200341017422052004200520044b1b22054100480d5a0240024020030d002005102821040c010b200128020020032005102c21040b2004450d1d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a0000200041096a2001108f01200041296a2001108f01200041d8006a29030021072000290350210802400240200141046a2802002204200528020022036b4110490d00200128020021040c010b200341106a22052003490d5a200441017422032005200320054b1b22034100480d5a0240024020040d002003102821040c010b200128020020042003102c21040b2004450d1e20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341106a360200200420036a2203200737000820032008370000200041e8006a29030021072000290360210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5a200341017422002004200020044b1b22004100480d5a0240024020030d002000102821030c010b200128020020032000102c21030b2003450d1f20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c0d0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d59200341017422052004200520044b1b22054100480d590240024020030d002005102821040c010b200128020020032005102c21040b2004450d1f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a000020002d0008220341024b0d0c02400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b200341017422052004200520044b1b22054100480d5b0240024020030d002005102821040c010b200128020020032005102c21040b2004450d2220012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041186a29030021072000290310210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5b200341017422002004200020044b1b22004100480d5b0240024020030d002000102821030c010b200128020020032000102c21030b2003450d2320012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c0e0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a200341017422052004200520044b1b22054100480d5a0240024020030d002005102821040c010b200128020020032005102c21040b2004450d2320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041096a2001108f01200041386a29030021072000290330210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5a200341017422002004200020044b1b22004100480d5a0240024020030d002000102821030c010b200128020020032000102c21030b2003450d2420012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c0d0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d59200341017422052004200520044b1b22054100480d590240024020030d002005102821040c010b200128020020032005102c21040b2004450d2420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a0000200028020c210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d59200341017422002005200020054b1b22004100480d590240024020030d002000102821030c010b200128020020032000102c21030b2003450d2520012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0c0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d58200341017422052004200520044b1b22054100480d580240024020030d002005102821040c010b200128020020032005102c21040b2004450d2520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d58200341017422052004200520044b1b22054100480d580240024020030d002005102821040c010b200128020020032005102c21040b2004450d2620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280204210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d58200341017422002005200020054b1b22004100480d580240024020030d002000102821030c010b200128020020032000102c21030b2003450d2720012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0b0b02400240200141046a2206280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d57200341017422092005200920054b1b22094100480d570240024020030d002009102821050c010b200128020020032009102c21050b2005450d2720012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41053a000020002d00082203410a4b0d0a0240024002400240024002400240024002400240024020030e0b000102030405060708090a000b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d61200341017422092005200920054b1b22094100480d610240024020030d002009102821050c010b200128020020032009102c21050b2005450d3220012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41003a0000200028020c21090240024020062802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d6120054101742203200a2003200a4b1b22034100480d610240024020050d002003102821050c010b200128020020052003102c21050b2005450d3320012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a2009360000200041186a2903002107200029031021080240024020062802002203200428020022006b4110490d00200128020021030c010b200041106a22052000490d61200341017422002005200020054b1b22004100480d610240024020030d002000102821030c010b200128020020032000102c21030b2003450d3420012003360200200141046a2000360200200141086a28020021000b2004200041106a360200200320006a22012007370008200120083700000c140b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d60200341017422092005200920054b1b22094100480d600240024020030d002009102821050c010b200128020020032009102c21050b2005450d3420012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41013a0000200028020c21090240024020062802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d6020054101742203200a2003200a4b1b22034100480d600240024020050d002003102821050c010b200128020020052003102c21050b2005450d3520012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a2009360000200041286a2903002107200029032021080240024020062802002205200428020022036b4110490d00200128020021040c010b200341106a22042003490d60200541017422032004200320044b1b22034100480d600240024020050d002003102821040c010b200128020020052003102c21040b2004450d3620012004360200200141046a2003360200200141086a28020021030b200141086a200341106a360200200420036a220320073700082003200837000020002802102103200041186a2802002200200110b4012000450d1320004105742100034020032001108f01200341206a2103200041606a22000d000c140b0b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5f200041017422052003200520034b1b22054100480d5f0240024020000d002005102821030c010b200128020020002005102c21030b2003450d3620012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41023a00000c120b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5e200341017422092005200920054b1b22094100480d5e0240024020030d002009102821050c010b200128020020032009102c21050b2005450d3620012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41033a0000200028020c21090240024020062802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d5e20054101742203200a2003200a4b1b22034100480d5e0240024020050d002003102821050c010b200128020020052003102c21050b2005450d3720012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a200936000020002d0009220041024b0d1102400240024020000e03000102000b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d60200041017422052003200520034b1b22054100480d600240024020000d002005102821030c010b200128020020002005102c21030b2003450d3a20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41003a00000c130b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5f200041017422052003200520034b1b22054100480d5f0240024020000d002005102821030c010b200128020020002005102c21030b2003450d3a20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41013a00000c120b02400240200628020020042802002200460d00200128020021030c010b200041016a22032000490d5e200041017422052003200520034b1b22054100480d5e0240024020000d002005102821030c010b200128020020002005102c21030b2003450d3a20012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41023a00000c110b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5d200341017422092005200920054b1b22094100480d5d0240024020030d002009102821050c010b200128020020032009102c21050b2005450d3a20012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41043a0000200028020c21050240024020062802002203200428020022006b4104490d00200128020021030c010b200041046a22062000490d5d200341017422002006200020064b1b22004100480d5d0240024020030d002000102821030c010b200128020020032000102c21030b2003450d3b20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c100b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5c200341017422092005200920054b1b22094100480d5c0240024020030d002009102821050c010b200128020020032009102c21050b2005450d3b20012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41053a0000200028020c21050240024020062802002203200428020022006b4104490d00200128020021030c010b200041046a22062000490d5c200341017422002006200020064b1b22004100480d5c0240024020030d002000102821030c010b200128020020032000102c21030b2003450d3c20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0f0b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5b200341017422092005200920054b1b22094100480d5b0240024020030d002009102821050c010b200128020020032009102c21050b2005450d3c20012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41063a0000200028020c21050240024020062802002203200428020022006b4104490d00200128020021030c010b200041046a22062000490d5b200341017422002006200020064b1b22004100480d5b0240024020030d002000102821030c010b200128020020032000102c21030b2003450d3d20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0e0b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5a200341017422092005200920054b1b22094100480d5a0240024020030d002009102821050c010b200128020020032009102c21050b2005450d3d20012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41073a0000200028020c21090240024020062802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d5a20054101742203200a2003200a4b1b22034100480d5a0240024020050d002003102821050c010b200128020020052003102c21050b2005450d3e20012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a200936000002400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5a200341017422062005200620054b1b22064100480d5a0240024020030d002006102821050c010b200128020020032006102c21050b2005450d3f20012005360200200141046a2006360200200141086a28020021030b2004200341016a360200200520036a20002d00093a00000c0d0b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d59200341017422052004200520044b1b22054100480d590240024020030d002005102821040c010b200128020020032005102c21040b2004450d3f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a0000200041096a2001108f01200041296a2001108f010c0c0b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d58200341017422052004200520044b1b22054100480d580240024020030d002005102821040c010b200128020020032005102c21040b2004450d3f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a0000200041096a2001108f010c0b0b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d57200341017422062005200620054b1b22064100480d570240024020030d002006102821050c010b200128020020032006102c21050b2005450d3f20012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a410a3a0000200041096a2001108f0120022001360208200041296a200241086a10c801200028024c210502400240200141046a2802002203200628020022006b4104490d00200128020021030c010b200041046a22062000490d57200341017422002006200020064b1b22004100480d570240024020030d002000102821030c010b200128020020032000102c21030b2003450d4020012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0a0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d56200341017422052004200520044b1b22054100480d560240024020030d002005102821040c010b200128020020032005102c21040b2004450d4020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a0000200041046a200110f2010c090b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d55200341017422052004200520044b1b22054100480d550240024020030d002005102821040c010b200128020020032005102c21040b2004450d4020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a0000200041046a200110f2010c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d54200341017422052004200520044b1b22054100480d540240024020030d002005102821040c010b200128020020032005102c21040b2004450d4020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41083a0000024002400240024020002d00040e0400010203000b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d57200341017422052004200520044b1b22054100480d570240024020030d002005102821040c010b200128020020032005102c21040b2004450d4420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041056a2001108f01200041256a2001108f010c0a0b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d56200341017422052004200520044b1b22054100480d560240024020030d002005102821040c010b200128020020032005102c21040b2004450d4420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041056a2001108f010c090b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d55200341017422052004200520044b1b22054100480d550240024020030d002005102821040c010b200128020020032005102c21040b2004450d4420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000280208210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d55200341017422002005200020054b1b22004100480d550240024020030d002000102821030c010b200128020020032000102c21030b2003450d4520012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c080b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d54200341017422052004200520044b1b22054100480d540240024020030d002005102821040c010b200128020020032005102c21040b2004450d4520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a000020002802082103200041106a2802002204200110b40102402004450d0020044105742104034020032001108f01200341206a2103200441606a22040d000b0b200028021421032000411c6a2802002200200110b4012000450d0720004105742100034020032001108f01200341206a2103200041606a22000d000c080b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d53200341017422052004200520044b1b22054100480d530240024020030d002005102821040c010b200128020020032005102c21040b2004450d4520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a000020002d0001220041044b0d060240024002400240024020000e050001020304000b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d57200041017422042003200420034b1b22044100480d570240024020000d002004102821030c010b200128020020002004102c21030b2003450d4a20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41003a00000c0a0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d56200041017422042003200420034b1b22044100480d560240024020000d002004102821030c010b200128020020002004102c21030b2003450d4a20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a00000c090b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d55200041017422042003200420034b1b22044100480d550240024020000d002004102821030c010b200128020020002004102c21030b2003450d4a20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41023a00000c080b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d54200041017422042003200420034b1b22044100480d540240024020000d002004102821030c010b200128020020002004102c21030b2003450d4a20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41033a00000c070b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d53200041017422042003200420034b1b22044100480d530240024020000d002004102821030c010b200128020020002004102c21030b2003450d4a20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41043a00000c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d52200341017422052004200520044b1b22054100480d520240024020030d002005102821040c010b200128020020032005102c21040b2004450d4a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a00002000280204220341024b0d0502400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d54200341017422052004200520044b1b22054100480d540240024020030d002005102821040c010b200128020020032005102c21040b2004450d4d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a000020002802082103200041106a2802002200200110b4012000450d072003200041286c6a210a200141046a2106034020032001108f01200341206a29030021070240024020062802002204200528020022006b4108490d00200128020021040c010b200041086a22092000490d55200441017422002009200020094b1b22004100480d550240024020040d002000102821040c010b200128020020042000102c21040b2004450d4f2001200436020020062000360200200528020021000b2005200041086a360200200420006a2007370000200a200341286a2203470d000c080b0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d53200041017422042003200420034b1b22044100480d530240024020000d002004102821030c010b200128020020002004102c21030b2003450d4e20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a00000c060b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d52200041017422042003200420034b1b22044100480d520240024020000d002004102821030c010b200128020020002004102c21030b2003450d4e20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41023a00000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d51200341017422052004200520044b1b22054100480d510240024020030d002005102821040c010b200128020020032005102c21040b2004450d4e20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a000020002d0008220341044b0d040240024002400240024020030e050001020304000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d55200341017422052004200520044b1b22054100480d550240024020030d002005102821040c010b200128020020032005102c21040b2004450d5320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200028020c210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d55200341017422002005200020054b1b22004100480d550240024020030d002000102821030c010b200128020020032000102c21030b2003450d5420012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d74200341017422052004200520044b1b22054100480d740240024020030d002005102821040c010b200128020020032005102c21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041186a29030021072000290310210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d74200341017422002004200020044b1b22004100480d740240024020030d002000102821030c010b200128020020032000102c21030b2003450d5620012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d73200341017422052004200520044b1b22054100480d730240024020030d002005102821040c010b200128020020032005102c21040b2004450d5620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a0000200028022c210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d73200441017422032005200320054b1b22034100480d730240024020040d002003102821040c010b200128020020042003102c21040b2004450d5720012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a2006360000200041386a29030021072000290330210802400240200141046a2802002204200528020022036b4110490d00200128020021040c010b200341106a22052003490d73200441017422032005200320054b1b22034100480d730240024020040d002003102821040c010b200128020020042003102c21040b2004450d5820012004360200200141046a2003360200200141086a28020021030b200141086a200341106a360200200420036a2203200737000820032008370000200041096a2001108f010c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d72200341017422052004200520044b1b22054100480d720240024020030d002005102821040c010b200128020020032005102c21040b2004450d5820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200041186a29030021072000290310210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d72200341017422002004200020044b1b22004100480d720240024020030d002000102821030c010b200128020020032000102c21030b2003450d5920012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d71200341017422052004200520044b1b22054100480d710240024020030d002005102821040c010b200128020020032005102c21040b2004450d5920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a0000200041186a29030021072000290310210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d71200341017422002004200020044b1b22004100480d710240024020030d002000102821030c010b200128020020032000102c21030b2003450d5a20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d70200341017422052004200520044b1b22054100480d700240024020030d002005102821040c010b200128020020032005102c21040b2004450d5a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a000020002d0008220341054b0d0302400240024002400240024020030e06000102030405000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d75200341017422052004200520044b1b22054100480d750240024020030d002005102821040c010b200128020020032005102c21040b2004450d6020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041096a2001108f01200041296a2001108f01200041d8006a29030021072000290350210802400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d75200341017422002004200020044b1b22004100480d750240024020030d002000102821030c010b200128020020032000102c21030b2003450d6120012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012007370008200120083700000c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d74200341017422052004200520044b1b22054100480d740240024020030d002005102821040c010b200128020020032005102c21040b2004450d6120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041096a2001108f01200041296a2001108f010c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d73200341017422052004200520044b1b22054100480d730240024020030d002005102821040c010b200128020020032005102c21040b2004450d6120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002002200136020c200041096a2002410c6a10c8010c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d72200341017422052004200520044b1b22054100480d720240024020030d002005102821040c010b200128020020032005102c21040b2004450d6120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200028020c210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d72200341017422002005200020054b1b22004100480d720240024020030d002000102821030c010b200128020020032000102c21030b2003450d6220012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d71200341017422052004200520044b1b22054100480d710240024020030d002005102821040c010b200128020020032005102c21040b2004450d6220012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a0000200041096a2001108f0102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d71200341017422052004200520044b1b22054100480d710240024020030d002005102821040c010b200128020020032005102c21040b2004450d6320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00293a00000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d70200341017422052004200520044b1b22054100480d700240024020030d002005102821040c010b200128020020032005102c21040b2004450d6320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41053a0000200041096a2001108f01200028022c2106200041346a2802002200200110b40102400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d70200441017422032005200320054b1b22034100480d700240024020040d002003102821040c010b200128020020042003102c21040b2004450d6420012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a20062000109a051a0c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6f200341017422052004200520044b1b22054100480d6f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d6420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410d3a000020002d0001220341024b0d0202400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d71200341017422052004200520044b1b22054100480d710240024020030d002005102821040c010b200128020020032005102c21040b2004450d6720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d71200341017422052004200520044b1b22054100480d710240024020030d002005102821040c010b200128020020032005102c21040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00023a00000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d70200341017422052004200520044b1b22054100480d700240024020030d002005102821040c010b200128020020032005102c21040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041026a2001108f010c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6f200341017422052004200520044b1b22054100480d6f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d6f200341017422052004200520044b1b22054100480d6f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00023a00000c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6e200341017422052004200520044b1b22054100480d6e0240024020030d002005102821040c010b200128020020032005102c21040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410e3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d6e200341017422052004200520044b1b22054100480d6e0240024020030d002005102821040c010b200128020020032005102c21040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041016a2001108f010c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6d200341017422052004200520044b1b22054100480d6d0240024020030d002005102821040c010b200128020020032005102c21040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410f3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d6d200341017422052004200520044b1b22054100480d6d0240024020030d002005102821040c010b200128020020032005102c21040b2004450d6b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041106a200110c601200028020421062000410c6a2802002200200110b40102400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d6d200441017422032005200320054b1b22034100480d6d0240024020040d002003102821040c010b200128020020042003102c21040b2004450d6c20012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a20062000109a051a0b200241106a24000f0b200541011037000b200441011037000b200641011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200041011037000b200541011037000b200541011037000b200041011037000b200541011037000b200541011037000b200341011037000b200041011037000b200541011037000b200541011037000b200041011037000b200541011037000b200041011037000b200541011037000b200041011037000b200541011037000b200541011037000b200041011037000b200941011037000b200941011037000b200341011037000b200041011037000b200941011037000b200341011037000b200341011037000b200541011037000b200941011037000b200341011037000b200541011037000b200541011037000b200541011037000b200941011037000b200041011037000b200941011037000b200041011037000b200941011037000b200041011037000b200941011037000b200341011037000b200641011037000b200541011037000b200541011037000b200641011037000b200041011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200041011037000b200541011037000b200541011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200541011037000b200541011037000b200041011037000b200441011037000b200441011037000b200541011037000b200541011037000b200041011037000b1031000b200541011037000b200041011037000b200541011037000b200341011037000b200341011037000b200541011037000b200041011037000b200541011037000b200041011037000b200541011037000b200541011037000b200041011037000b200541011037000b200541011037000b200541011037000b200041011037000b200541011037000b200541011037000b200541011037000b200341011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200341011037000b1031000bfd1201057f230041106b2202240002400240024002400240024002400240024002400240024002400240024020002d0000220341054b0d0002400240024002400240024020030e06000102030405000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d14200341017422052004200520044b1b22054100480d140240024020030d002005102821040c010b200128020020032005102c21040b2004450d0720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041016a2001108f012000280244210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d14200441017422032005200320054b1b22034100480d140240024020040d002003102821040c010b200128020020042003102c21040b2004450d0820012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a20063600002002200136020c200041216a2002410c6a10c8012000280248210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d14200341017422002005200020054b1b22004100480d140240024020030d002000102821030c010b200128020020032000102c21030b2003450d0920012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d13200341017422052004200520044b1b22054100480d130240024020030d002005102821040c010b200128020020032005102c21040b2004450d0920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041016a2001108f012002200136020c200041216a2002410c6a10c80102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d13200341017422052004200520044b1b22054100480d130240024020030d002005102821040c010b200128020020032005102c21040b2004450d0a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20002d00413a00002000280244210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d13200441017422032005200320054b1b22034100480d130240024020040d002003102821040c010b200128020020042003102c21040b2004450d0b20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a20063600002000280248210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d13200341017422002005200020054b1b22004100480d130240024020030d002000102821030c010b200128020020032000102c21030b2003450d0c20012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d12200341017422052004200520044b1b22054100480d120240024020030d002005102821040c010b200128020020032005102c21040b2004450d0c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002002200136020c200041016a2002410c6a10c8010c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d11200341017422052004200520044b1b22054100480d110240024020030d002005102821040c010b200128020020032005102c21040b2004450d0c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a00002002200136020c200041016a2002410c6a10c8010c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d10200341017422052004200520044b1b22054100480d100240024020030d002005102821040c010b200128020020032005102c21040b2004450d0c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a00002002200136020c200041016a2002410c6a10c80102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d10200341017422052004200520044b1b22054100480d100240024020030d002005102821040c010b200128020020032005102c21040b2004450d0d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00213a00000c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0f200341017422052004200520044b1b22054100480d0f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d0d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41053a00002002200136020c200041016a2002410c6a10c80102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d0f200341017422052004200520044b1b22054100480d0f0240024020030d002005102821040c010b200128020020032005102c21040b2004450d0e20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00213a00000b200241106a24000f0b200541011037000b200341011037000b200041011037000b200541011037000b200541011037000b200341011037000b200041011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b1031000bf40501027f4190ce0021024100210302400240024002400240024002400240024002400240024002400240024020012802000e15000e08080e01020304050607090e0e0a0e0c0e0e0e000b417f2102200141086a280200417f6a220141054b0d0a41012103024020010e060e0b0d000d0d0e0b41c09a0c21020c0d0b200141086a280200417f6a220141024b0d0941c0843d210241002103024020010e030d000d0d0b4101210341d0860321020c0c0b200141086a2d0000417f6a2201410c4b0d0841a0c21e21024100210302400240024020010e0d0e0e000001010e0e01020808080e0b4180b5182102410021030c0d0b41b0e32d2102410021030c0c0b4101210341f0930921020c0b0b41f093092102410021030c0a0b200141086a2d0000417f6a220141104b0d0641c096b102210241002103024002400240024020010e110d0d0101000d0d0d0101070702020203030d0b4101210341a0c21e21020c0c0b41c09a0c2102410021030c0b0b41a08d062102410021030c0a0b41a0c21e2102410021030c090b20012d0004417f6a220141034b0d054101210341a08d0621020240024020010e040a0a00010a0b41c096b10221020c090b41c09a0c21020c080b20012d0004417f6a220141034b0d044101210341a08d0621020240024020010e0409090001090b41c096b10221020c080b41c09a0c21020c070b200141086a280200417f6a220141094b0d0341a0cb98012102410021030240024020010e0a08080800080102020202080b41d0a5cc002102410021030c070b4180ade2042102410021030c060b410121030c040b41d086034190ce0020012d0004411d7441808080807e6a411d75417f4a1b2102410021030c040b200141086a280200417f6a220141024b0d0041a0c21e210241002103024020010e03040000040b4101210341a08d0621020c030b4190ce002102410021030c020b02402001280204417f6a220141024b0d00410121034100210220010e03020002020b410021030b4190ce0021020b200020033a0004200020023602000be6fe0109017f017e067f017e047f017e0a7f037e177f230041d0076b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e15000102031e1c1b1a191817160f0e0d0c0b0a090807000b200141106a29030021042001410c6a280200210520022d0001210620022d000021020240024002400240024002400240200141086a28020022070e0700060102030405000b200341d4066a4101360200200342013702c406200341ccd1c5003602c006200341043602e405200341c4d1c5003602e0052003200341e0056a3602d006200341c0066a4188a6c300103e000b2004a7210702400240200241ff01710d00200641ff01714101460d010b2007450d2d2005102a0c2d0b2007450d2a2005102a0c2a0b200220067241ff01710d2a410810282202450d09200220043700004198a6c300410a2002410810072002102a0c290b2004a721070240200220067241ff0171450d002007450d2a2005102a0c2a0b41a2a6c300410520052004422088a710072007450d282005102a0c280b2004422088a721082004a721090240200220067241ff0171450d0002402008450d00200841186c21062005210203400240200241046a280200450d002002280200102a0b0240200241106a280200450d002002410c6a280200102a0b200241186a2102200641686a22060d000b0b410121064100210a4105210820090d260c270b0240200841186c2202450d00200520026a21062005210203402002280200200241086a2802002002410c6a280200200241146a2802001007200241186a22022006470d000b0b02402008450d00200841186c21062005210203400240200241046a280200450d002002280200102a0b0240200241106a280200450d002002410c6a280200102a0b200241186a2102200641686a22060d000b0b410121064100210a4107210820090d250c260b2004422088a721082004a721090240200220067241ff0171450d0002402008450d002008410c6c21062005210203400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b410021064101210a410521082009450d260c250b02402008410c6c2202450d00200520026a21062005210203402002280200200241086a28020010092002410c6a22022006470d000b0b02402008450d002008410c6c21062005210203400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b410021064101210a4107210820090d240c250b200220067241ff01710d260c250b10f501000b024020022d00000d0020022d000141ff01714102470d00200141086a290300210420034180056a41086a22024200370300200342003703800541d8a1c600411320034180056a1008200341b8026a41086a2206200229030037030020032003290380053703b8020240200341b8026a41104101410041001003417f470d0020024200370300200342003703800541feb3c300410d20034180056a10082006200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a100621020240024020032802c0062206417f460d002002450d0020064108490d012002290000210b2002102a200b500d004200210b20034180056a41086a22024200370300200342003703800541feb3c300410d20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a10062102024020032802c0062206417f460d002002450d0020064108490d072002290000210b2002102a0b200b42dc0b7c2004560d050b20034180056a41086a22024200370300200342003703800541feb3c300410d20034180056a1008200341b8026a41086a2206200229030037030020032003290380053703b802200320043703c006200341b8026a4110200341c0066a4108100741012105200341013a00c00620024200370300200342003703800541d8a1c600411320034180056a10082006200229030037030020032003290380053703b802200341b8026a4110200341c0066a41011007200041023a0008410121060c2b0b41c4d1c3004133200341c8076a419cd9c3001038000b41c8adc3001032000b20004181043b01082000410f360204200041ea9fc6003602002000410a6a41003a00000c1a0b2001410c6a2802002105200141086a280200210c2001280204210d41ea9fc600210e410f210f20022d00000d1e20022d000141ff01714102470d1e20034180056a41086a22024200370300200342003703800541c8fbc500411720034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a10062102024002400240024020032802c0062206417f460d002002450d002006450d0120022d000021062002102a20064102460d002006410171450d0041a4cdc200210e411c210f0c220b200341013a00c00620034180056a41086a22024200370300200342003703800541c8fbc500411720034180056a1008200341b8026a41086a2206200229030037030020032003290380053703b802200341b8026a4110200341c0066a4101100710980121082002420037030020034200370380054193cdc200411120034180056a10082006200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a1006210202400240024020032802c0062206417f460d002002450d0020032006360294012003200236029001200341c0066a20034190016a107b20032802c0062207450d0520032902c406210402402006450d002002102a0b200320073602980302402004422088220ba722022004a7470d00200341c0066a21060c020b200341c0066a21060c020b4104210720034104360298034200210441002102200341c0066a21060b024020022004a7470d00200241016a220a2002490d1120024101742209200a2009200a4b1bad220b42c4007e2210422088a70d112010a7220a4100480d110240024020020d00200a102821070c010b2007200241c4006c200a102c21070b2007450d032003200736029803200442808080807083200b8421040b2004422088220ba721020b2007200241c4006c6a22022008360204200241003a000020022006290200370208200241106a200641086a290200370200200241186a200641106a290200370200200241206a200641186a290200370200200241286a200641206a290200370200200241306a200641286a290200370200200241386a200641306a290200370200200241c0006a200641386a280200360200200b422086200442ffffffff0f83844280808080107c2104200d200541f0006c6a2108024020050d00200d21070c200b200341e0056a417f6a210a20034193046a2111200341d7046a21122003419b056a2113200341c0066a41106a2114200341c0066a41086a211520034180056a41186a2116200d2107024003402007280204210220072802002106200341c0066a200741086a41e800109a051a200741f0006a21072002450d2120034190016a200341c0066a41e800109a051a200320023602c406200320063602c006201520034190016a41e800109a051a20032802980321171098012102200341e0056a200341c0066a10f60102400240024020032802c00622060d0041d6cdc200210e4110210f0c010b0240200620024d0d00411a210f41e6cdc200210e0c010b20034198046a2006417f6a10f701024020034198046a20144120109c05450d004119210f4180cec200210e0c010b024020032802c006221841002002417b6a2206200620024b1b4f0d004126210f4199cec200210e0c010b20172004422088220ba7220941c4006c22196a21052017210202400240201941cd01490d00201721020340024020022d00004101470d00200241016a2106200a2002460d032006200341e0056a4120109c05450d030b0240200241c4006a2d00004101470d00200241c5006a210620132002460d032006200341e0056a4120109c05450d030b024020024188016a2d00004101470d0020024189016a210620122002460d032006200341e0056a4120109c05450d030b0240200241cc016a2d00004101470d00200241cd016a210620112002460d032006200341e0056a4120109c05450d030b200520024190026a22026b41cc014b0d000b0b024020022005460d000340024020022d00004101470d00200241016a2106200a2002460d032006200341e0056a4120109c05450d030b2005200241c4006a2202470d000b0b410021060b20034198046a201810f70120034198046a200341e0056a4120109c052102200341b8036a41086a221a20034180056a41086a2205290200370300200341b8036a41106a20034180056a41106a221829020037030020032003290280053703b80341c0cdc200210e4116210f20060d2220020d010c220b200341b8036a41086a20034180056a41086a290200370300200341b8036a41106a20034180056a41106a29020037030020032003290280053703b8030c210b200341b8026a410e6a2206200341b8036a410e6a290100370100200341b8026a41086a220e201a290300370300200320032903b8033703b80220034198046a200341c0066a10f6012016420037030020184200370300200542003703002003420037038005024041c80010282202450d0020034198026a10f8012002410236022020024101360244200241186a20034198026a41186a290300370200200241106a20034198026a41106a290300370200200241086a20034198026a41086a290300370200200220032903980237020020022003290380053700242002412c6a2005290300370000200241346a20182903003700002002413c6a2016290300370000200320023602e00520034282808080203702e405200341e0056a10f901200341f8016a41086a220520034198046a41086a290300370300200341f8016a41106a221820034198046a41106a290300370300200341f8016a41186a220f20034198046a41186a290300370300200341e0056a41086a221a200e290300370300200341e0056a410e6a220e200629010037010020032003290398043703f801200320032903b8023703e0050240024020092004a7460d00200421100c010b200941016a22022009490d13200ba74101742206200220022006491bad221042c4007e220b422088a70d13200ba722064100480d130240024020090d002006102821020c010b201720192006102c21020b2002450d0320032002360298032004422088220ba721090b200328029803200941c4006c6a220241013a0000200f29030021042018290300211b2005290300211c20032903f801211d20024116360028200241c0cdc200360024200241003a00212002413a6a200e290100370000200241346a201a290300370000200220032903e00537002c2002201d370001200241096a201c370000200241116a201b370000200241196a2004370000201042ffffffff0f832104200b422086210b024020032802cc062206450d0020032802c4062102200641246c210603400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a280200102a0c030b2002410c6a280200450d02200241086a280200102a0c020b2002410c6a280200450d01200241086a280200102a0c010b200241086a280200450d00200241046a280200102a0b200241246a21022006415c6a22060d000b0b200b2004842104024020032802c806450d0020032802c406102a0b20044280808080107c210420072008470d010c230b0b41c80041041037000b200641041037000b41c4d1c3004133200341c8076a419cd9c3001038000b200a41041037000b41c4d1c3004133200341c8076a419cd9c3001038000b4190aec3001032000b41c4d1c3004133200341c8076a419cd9c3001038000b410841011037000b10d601000b10fa01000b200141246a280200211a200141206a280200210f2001411c6a280200210a200141186a2802002118200141146a2802002109200141106a28020021132001410c6a280200210e200141086a280200211920022d0001210620022d000021022001280204210820034190016a41386a200141e0006a29000037030020034190016a41306a200141d8006a29000037030020034190016a41286a200141d0006a29000037030020034190016a41206a200141c8006a29000037030020034190016a41186a200141c0006a29000037030020034190016a41106a200141386a29000037030020034190016a41086a200141306a2900003703002003200141286a2900003703900141ea9fc6002105410f21070240024020020d00200641ff01714102470d00024010fb01200f460d0041fb91c1002105411c21070c010b200341c0066a200f201a10fc0120032802c006220220032802c80641014100410010032106024020032802c406450d002002102a0b20034180056a41086a22024200370300200342003703800541c2e1c000410d20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a1006210202400240024002400240024002400240024002400240024020032802c0062205417f460d002002450d002003200536029c042003200236029804200341c0066a20034198046a107c20032802c006220c450d0220032902c40621042005450d012002102a0c010b420021044101210c0b02402006417f460d0041b392c1002105411521070c030b200c201a4105746a4100201a2004422088a7491b22120d0141c892c1002105411821070c020b41c4d1c3004133200341c8076a419cd9c3001038000b200341003602c806200342013703c00602400240024002400240410410282202450d0020034284808080c0003702c406200320023602c006200220083600002013200341c0066a10b4010240024020032802c406220620032802c80622026b2013490d0020032802c00621060c010b200220136a22052002490d16200641017422072005200720054b1b22054100480d160240024020060d002005102821060c010b20032802c00620062005102c21060b2006450d02200320053602c406200320063602c0060b2003200220136a3602c806200620026a20192013109a051a200a200341c0066a10b4012009200a410c6c6a2116200a450d0220092106034020062802002117200641086a2802002202200341c0066a10b4010240024020032802c406220720032802c80622056b2002490d0020032802c00621080c010b200520026a22082005490d172007410174220d2008200d20084b1b220d4100480d170240024020070d00200d102821080c010b20032802c0062007200d102c21080b2008450d052003200d3602c406200320083602c006200d21070b2003200520026a220d3602c806200820056a20172002109a051a2006410c6a22062016470d000c050b0b410441011037000b200541011037000b20032802c406210720032802c806210d0c010b200d41011037000b024002402007200d6b4104490d0020032802c00621020c010b200d41046a2202200d490d11200741017422062002200620024b1b22064100480d110240024020070d002006102821020c010b20032802c00620072006102c21020b2002450d03200320063602c406200320023602c006200621070b2003200d41046a22063602c8062002200d6a200f36000002400240200720066b41034d0d00200721050c010b200641046a22052006490d11200741017422082005200820054b1b22054100480d110240024020070d002005102821020c010b200220072005102c21020b2002450d04200320053602c406200320023602c0060b200220066a201a3600002002200d41086a20034190016a2012100a210602402005450d002002102a0b2006450d01419792c1002105411c21070b2004a7450d07200c102a0c070b201241086a290000210b201241106a29000021102012290000211b20034198026a41186a201241186a290000221c37030020034198026a41106a201037030020034198026a41086a200b3703002003201b37039802200341c9066a200b370000200341d1066a2010370000200341d9066a201c3700002003410e3a00c0062003201b3700c10641014100200341c0066a10cc01200341003602c806200342013703c0062013200341c0066a10b4010240024020032802c406220620032802c80622026b2013490d0020032802c00621060c010b200220136a22052002490d0f200641017422072005200720054b1b22054100480d0f0240024020060d002005102821060c010b20032802c00620062005102c21060b2006450d03200320053602c406200320063602c0060b2003200220136a3602c806200620026a20192013109a051a200a200341c0066a10b401200a450d0320092106034020062802002117200641086a2802002202200341c0066a10b4010240024020032802c406220820032802c80622056b2002490d0020032802c00621070c010b200520026a22072005490d102008410174220d2007200d20074b1b220d4100480d100240024020080d00200d102821070c010b20032802c0062008200d102c21070b2007450d062003200d3602c406200320073602c006200d21080b2003200520026a220d3602c806200720056a20172002109a051a2006410c6a22062016470d000c060b0b200641011037000b200541011037000b200541011037000b20032802c806210d20032802c406210820032802c00621070c010b200d41011037000b200341c0066a200f201a10fc0120032802c0062102200320032802c80636029c0420032002360298042007200d20034198046a10cb01024020032802c406450d002002102a0b02402008450d002007102a0b02402004a7450d00200c102a0b0240200e450d002019102a0b0240200a450d00200a410c6c21062009210203400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b02402018450d002009102a0b200041023a0008410021160c010b0240200e450d002019102a0b0240200a450d00200a410c6c21062009210203400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b02402018450d002009102a0b20004181243b01082000200736020420002005360200410021162000410a6a41003a00000b410121054101210641012107410121084101210a41012109410121174101210d410121184101210e4101210f410121190c2b0b2002411a6a2901002104200241196a2d00002119200241186a2d00002116200241166a2f0100211a200241156a2d00002113200241146a2d0000210c200241126a2f01002112200241116a2d00002111200241106a2d000021092002410e6a2f010021172002410d6a2d0000210d2002410c6a2d000021182002410a6a2f0100210e200241096a2d0000210f200241086a2d00002106200241066a2f01002105200241056a2d00002107200241046a2d00002115200241026a2f01002114200141216a290000210b200141206a2d0000211e2001411d6a2f0000211f2001411c6a2d00002120200141196a2f00002121200141186a2d00002122200141156a2f00002123200141146a2d00002124200141116a2f00002125200141106a2d000021262001410c6a2802002127200141086a280200210a20022d0001210820022d0000210220012d001f212820012d001b212920012d0017212a20012d0013212b024002400240024002400240024002400240024020012802040e0400010203000b200341c0066a41146a4101360200200342013702c406200341ccd1c5003602c006200341043602e405200341c4d1c5003602e0052003200341e0056a3602d006200341c0066a41b49dc400103e000b410420054108742006411874722007724104200841ff017141014622061b200241ff017122021b21050240024020020d0020060d010b410f210641ea9fc600210202400240024002400240024020050e070001020304050a000b200e410874200f7220184118747221022017410874200d7220094118747221060c090b410e210641dc9fc60021020c080b410c210641d09fc60021020c070b4109210641c79fc60021020c060b4113210641b49fc60021020c050b4111210641a39fc60021020c040b200320043703b004200320193a00af04200320163a00ae042003201a3b01ac04200320133a00ab042003200c3a00aa04200320123b01a804200320113a00a704200320093a00a604200320173b01a4042003200d3a00a304200320183a00a2042003200e3b01a0042003200f3a009f042003200536009b04200320153a009a04200320143b01980420034180056a41086a22024200370300200342003703800541e69dc400410820034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341c0066a200341b8026a411010fd010240024020032d00c0064101460d00200341a8016a420037030020034190016a41106a420037030020034190016a41086a420037030020034200370390010c010b200320032f00c1063b019001200320032d00c3063a009201200320032802c406360093012003200341c0066a41086a2d00003a0097012003200341d9066a2900003703a8012003200341c9066a290000370398012003200341d1066a2900003703a0010b024020034198046a20034190016a4120109c05450d0041c49dc4002102412221060c040b200341c0066a200a418801109a051a200341003b019001200341e0056a200341c0066a20034190016a10f40141012102024020032d00e80522064102460d00200341e9056a310000210b20033100ea05210420032802e405210720032802e005210541f19ec600410d100b02402006450d00200b100c0b2004100c410021022005450d0020052007100b0b200320023a00c2062003410d3b01c00641014100200341c0066a10cc01200a102a0c060b410420054108742006411874722007724104200841ff017141014622061b200241ff017122021b21050240024020020d0020060d010b410f210641ea9fc600210202400240024002400240024020050e070001020304050a000b200e410874200f7220184118747221022017410874200d7220094118747221060c090b410e210641dc9fc60021020c080b410c210641d09fc60021020c070b4109210641c79fc60021020c060b4113210641b49fc60021020c050b4111210641a39fc60021020c040b200320043703b004200320193a00af04200320163a00ae042003201a3b01ac04200320133a00ab042003200c3a00aa04200320123b01a804200320113a00a704200320093a00a604200320173b01a4042003200d3a00a304200320183a00a2042003200e3b01a0042003200f3a009f042003200536009b04200320153a009a04200320143b01980420034180056a41086a22024200370300200342003703800541e69dc400410820034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341c0066a200341b8026a411010fd010240024020032d00c0064101460d00200341a8016a420037030020034190016a41106a420037030020034190016a41086a420037030020034200370390010c010b200320032f00c1063b019001200320032d00c3063a009201200320032802c406360093012003200341c0066a41086a2d00003a0097012003200341d9066a2900003703a8012003200341c9066a290000370398012003200341d1066a2900003703a0010b024020034198046a20034190016a4120109c05450d0041ee9dc4002102413121060c050b0240200a41ff01714101460d00200a4118762105200a41087621070c020b200341c0066a202741067610fe0120032802c00621060240024020032802c8062027413f7122024b0d00410021020c010b200620024105746a2202290018210b20022d0017211e20022d0016212820022f0014211f20022d0013212020022d0012212920022f0010212120022d000f212220022d000e212a20022f000c212320022d000b212420022d000a212b20022f0008212520022d000721262002280003212720022d0002210520022f00002107410121020b024020032802c406450d002006102a0b20020d0141dc9fc6002102410e21060c040b2001412c6a280200212c410420054108742007722006411874724104200841ff017141014622061b200241ff017122021b210502400240024020020d0020060d010b410f210641ea9fc600210202400240024002400240024020050e0700010203040507000b200e410874200f7220184118747221022017410874200d7220094118747221060c060b410e210641dc9fc60021020c050b410c210641d09fc60021020c040b4109210641c79fc60021020c030b4113210641b49fc60021020c020b4111210641a39fc60021020c010b200320043703b004200320193a00af04200320163a00ae042003201a3b01ac04200320133a00ab042003200c3a00aa04200320123b01a804200320113a00a704200320093a00a604200320173b01a4042003200d3a00a304200320183a00a2042003200e3b01a0042003200f3a009f042003200536009b04200320153a009a04200320143b01980420034180056a41086a22024200370300200342003703800541e69dc400410820034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341c0066a200341b8026a411010fd010240024020032d00c0064101460d00200341a8016a420037030020034190016a41106a420037030020034190016a41086a420037030020034200370390010c010b200320032f00c1063b019001200320032d00c3063a009201200320032802c406360093012003200341c0066a41086a2d00003a0097012003200341d9066a2900003703a8012003200341c9066a290000370398012003200341d1066a2900003703a0010b024020034198046a20034190016a4120109c05450d0041c49dc4002102412221060c010b4101210602400240200a41ff01714101460d00200a4118762105200a41087621020c010b200341c0066a202741067610fe0120032802c00621070240024020032802c8062027413f7122024b0d00410021080c010b200720024105746a2202290018210b20022d0017211e20022d0016212820022f0014211f20022d0013212020022d0012212920022f0010212120022d000f212220022d000e212a20022f000c212320022d000b212420022d000a212b20022f0008212520022d000721262002280003212720022d0002210520022f00002102410121080b024020032802c406450d002007102a0b20080d0041dc9fc6002102410e21060c010b200341c0066a202c418801109a051a200341aa016a200b370100200341a9016a201e3a0000200341a8016a20283a0000200341a6016a201f3b0100200341a5016a20203a0000200341a4016a20293a0000200341a2016a20213b0100200341a1016a20223a0000200341a0016a202a3a00002003419e016a20233b010020034190016a410d6a20243a00002003419c016a202b3a00002003419a016a20253b010020034190016a41096a20263a00002003202736009501200320053a009401200320023b01920120034180023b019001200341e0056a200341c0066a20034190016a10f401024020032d00e80522024102460d00200341e0056a41096a310000210b20033100ea05210420032802e405210720032802e005210541f19ec600410d100b02402002450d00200b100c0b2004100c410021062005450d0020052007100b0b200320063a00c2062003418d043b01c00641014100200341c0066a10cc01202c102a0c050b202c106a202c102a0c020b20034180056a41086a22064200370300200342003703800541e69dc400410820034180056a1008200341b8026a41086a2208200629030037030020032003290380053703b802200341c0066a200341b8026a411010fd01200341c0066a41086a2d0000210a200341c9066a22092f00002117200341cb066a2d0000210d200341cc066a22182d0000210e200341cd066a220f2f00002119200341cf066a2d00002116200341c0066a41106a221a2d00002113200341d1066a220c2f00002112200341d3066a2d00002111200341d4066a22152d00002114200341d5066a222c2f0000212d200341d7066a2d0000212e200341d8066a222f2d0000213020032f00c106213120032d00c306213220032802c4062133200341da066a200341d9066a2234290000420020032d00c00641014622021b37010020342030410020021b3a0000202f202e410020021b3a0000200341d6066a202d410020021b3b0100202c2014410020021b3a000020152011410020021b3a0000200341d2066a2012410020021b3b0100200c2013410020021b3a0000201a2016410020021b3a0000200341ce066a2019410020021b3b0100200f200e410020021b3a00002018200d410020021b3a0000200341ca066a2017410020021b3b01002009200a410020021b3a000020032033410020021b3600c50620032032410020021b3a00c40620032031410020021b3b01c2062003418d023b01c00641014100200341c0066a10cc012003200b3703d8062003201e3a00d706200320283a00d6062003201f3b01d406200320203a00d306200320293a00d206200320213b01d006200320223a00cf062003202a3a00ce06200320233b01cc06200320243a00cb062003202b3a00ca06200320253b01c806200320263a00c706200320273600c306200320053a00c206200320073b01c00620064200370300200342003703800541e69dc400410820034180056a10082008200629030037030020032003290380053703b80220034110360294012003200341b8026a36029001200341c0066a20034190016a10ff010c030b200a106a200a102a0b2002450d010b20004181223b01082000200636020420002002360200410021192000410a6a41003a00000c010b200041023a0008410021190b410121054101210641012107410121084101210a41012109410121174101210d410121184101210e4101210f0c290b200341c0066a200141086a418001109a051a20034190016a41206a200241206a29020037030020034190016a41186a200241186a29020037030020034190016a41106a200241106a29020037030020034190016a41086a200241086a290200370300200320022902003703900120034188016a200341c0066a20034190016a1080020240024020032802880122020d00200041023a00084100210f0c010b200328028c01210620004181203b0108200020023602004100210f2000410a6a41003a0000200020063602040b410121054101210641012107410121084101210a41012109410121174101210d410121184101210e410121190c280b200341b8036a41086a22092001411c6a290200370300200341b8036a41106a2217200141246a290200370300200341b8036a41186a220d2001412c6a2802003602002003200141146a2902003703b803200241086a28020021062001410c6a280200210a410e2105200241046a280200210820022d000021070240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141086a2802000e0400010203000b200341c0066a41146a4101360200200342013702c406200341ccd1c5003602c006200341043602e405200341c4d1c5003602e0052003200341e0056a3602d006200341c0066a41e4c4c200103e000b200641107621182006410876210e200141386a290300210b200141306a29030021042002411a6a2901002110200241196a2d00002113200241186a2d0000210c200241166a2f01002112200241156a2d00002111200241146a2d00002115200241126a2f01002114200241116a2d00002127200241106a2d0000210f2002410e6a2f010021192002410d6a2d000021162002410c6a2d0000211a200241026a2f0100211e200141106a280200210520022d0001210220034198046a41186a200d28020036020020034198046a41106a201729030037030020034198046a41086a2009290300370300200320032903b80337039804410420084108762006411874724104200241014622091b200741ff017122021b21060240024020020d0020090d010b410f210541ea9fc600210202400240024002400240024020060e0700010203040516000b200e41ff0171201841087472201a4118747221022019410874201672200f4118747221050c150b410e210541dc9fc60021020c140b410c210541d09fc60021020c130b4109210541c79fc60021020c120b4113210541b49fc60021020c110b4111210541a39fc60021020c100b200320103703a801200320133a00a7012003200c3a00a601200320123b01a401200320113a00a301200320153a00a201200320143b01a001200320273a009f012003200f3a009e01200320193b019c01200320163a009b012003201a3a009a01200320183b0198012003200e3a0097012003200636009301200320083a0092012003201e3b019001200341c0066a41186a220220034198046a41186a280200360200200341c0066a41106a220720034198046a41106a290300370300200341c0066a41086a220820034198046a41086a29030037030020032003290398043703c0060240200a41ff01714101460d00200a4108762106200341e0056a41186a20022d00003a0000200341e0056a41106a2007290300370300200341e0056a41086a2008290300370300200320032903c0063703e0050c0f0b20034198026a200541067610fe0120032802980221070240024020032802a0022005413f7122024b0d00410021020c010b200341e8056a200720024105746a2202410f6a290000370300200341e0056a41106a200241176a290000370300200341f8056a2002411f6a2d00003a0000200320022900073703e00520022f0000200241026a2d000041107472210620022800032105410121020b0240200328029c02450d002007102a0b20020d0e200341b8026a41086a20034180056a41086a290000370300200341b8026a41106a20034180056a41106a29000037030041dc9fc6002102410e21050c0f0b41a6f5c5002102200741ff01714101470d0f20064102490d0f200841ff01710d0f411210282202450d01200241106a41002f008086423b0000200241086a41002900f88542370000200241002900f08542370000200241124124102c2202450d022002200a36001220034198026a41186a2206420037030020034198026a41106a2205420037030020034198026a41086a2207420037030020034200370398022002411620034198026a1000200341f8016a41186a2006290300370300200341f8016a41106a2005290300370300200341f8016a41086a200729030037030020032003290398023703f8012002102a200341003602c006200341f8016a4120200341c0066a1006210220032802c0062206417f460d092002450d09200320063602bc02200320023602b802200341c0066a200341b8026a10810220032903c0064201510d0320032802c806210520034198046a200341cc066a41dc00109a051a02402006450d002002102a0b200341c0066a20034198046a41dc00109a051a200341f8016a41201009410121020c0a0b41a6f5c5002102200741ff01714101470d0e20064104490d0e200841ff01710d0e411210282202450d03200241106a41002f008086423b0000200241086a41002900f88542370000200241002900f08542370000200241124124102c2202450d042002200a36001220034198026a41186a2206420037030020034198026a41106a2205420037030020034198026a41086a2207420037030020034200370398022002411620034198026a1000200341f8016a41186a2006290300370300200341f8016a41106a2005290300370300200341f8016a41086a200729030037030020032003290398023703f8012002102a200341f8016a41204101410041001003417f460d0a20034180056a41086a2202420037030020034200370380054181a2c600411220034180056a1008200341b8026a41086a200229030037030020032003290380053703b80241002102200341003602c006200341b8026a4110200341c0066a100621060240024020032802c0062205417f470d000c010b024020060d000c010b20032005360294012003200636029001200341c0066a20034190016a10820120032802c0062202450d0620032902c40621042005450d002006102a0b2002410420021b210d02402004420020021b2204422088220ba722022004a7470d00200241016a22062002490d19200ba722074101742205200620062005491b220641ffffffff03712006470d19200641027422054100480d190240024020020d0020051028210d0c010b200d20074102742005102c210d0b200d450d072004422088220ba721022006ad21040b200d20024102746a200a36020020034180056a41086a2202420037030020034200370380054181a2c600411220034180056a1008200341b8026a41086a200229030037030020032003290380053703b8020240200d0d00200341b8026a411010090c100b200341003602c806200342013703c006200ba741016a2206200341c0066a10b4010240024020060d0020032802c806210a20032802c406210820032802c00621060c010b410020032802c80622026b2105200d20064102746a211720032802c4062108200d210703402007280200210902400240200820056a4104490d0020032802c00621060c010b200241046a22062002490d1b2008410174220a2006200a20064b1b220a4100480d1b0240024020080d00200a102821060c010b20032802c0062008200a102c21060b2006450d0a2003200a3602c406200320063602c006200a21080b2003200241046a220a3602c806200620026a20093600002005417c6a2105200a21022017200741046a2207470d000b0b2004a72102200341b8026a41102006200a100702402008450d002006102a0b2002450d0f200d102a0c0f0b411241011037000b412441011037000b41c4d1c3004133200341c8076a419cd9c3001038000b411241011037000b412441011037000b41c4d1c3004133200341c8076a419cd9c3001038000b200541041037000b200a41011037000b410021020b200341e0056a200341c0066a41dc00109a051a200341c0066a200341e0056a41dc00109a051a20020d010b418ec5c2002102411921050c030b20034180056a200341c0066a41dc00109a051a200320053602900120034190016a41047220034180056a41dc00109a051a200341f8006a200341b0016a20032903a001200341a8016a29030010820220032903782104200320034180016a2903003703c806200320043703c0062003200341c0066a3602980420034198046a109d010c030b200341e0006a2004200b42c0843d420010a005200341d0006a20032903602210200341e0006a41086a290300221b42c0fb42427f109f05200341c0006a2010201b42d086034200109f0520034198036a41086a200341e0056a41086a29030037030020034198036a41106a200341e0056a41106a29030037030020034198036a41186a200341e0056a41186a2d00003a0000200320032903e00522103703b8022003201037039803200341f0006a20034190016a2003290340221b200420032903507c42148042ffffffff0f837c2210428080e983b1de162010428080e983b1de1656200341c0006a41086a2903002010201b54ad7c22104200522010501b22021b221b2010420020021b221010830202402003280270450d0041f4c4c2002102411a21050c010b20034180056a41086a22024200370300200342003703800541eba1c600411620034180056a1008200341b8026a41086a200229030037030020032003290380053703b80241002107200341003602c006200341b8026a4110200341c0066a10062102024020032802c0062208417f460d002002450d0020084104490d04200228000021072002102a0b20034180056a41086a22024200370300200342003703800541eba1c600411620034180056a1008200341b8026a41086a200229030037030020032003290380053703b8022003200741016a3602c006200341b8026a4110200341c0066a41041007200341f8066a20034190016a41186a290300370300200341f0066a20034190016a41106a290300370300200341e8066a20034190016a41086a29030037030020034183076a200536000020034187076a2003290398033700002003418f076a20034198036a41086a29030037000020034197076a20034198036a41106a2903003700002003419f076a20034198036a41186a2d00003a0000200320063b01800720034182076a20064110763a00002003200b3703c806200320043703c00620032003290390013703e006200341c0066a41186a20103703002003201b3703d006411210282202450d04200241106a41002f008086423b0000200241086a41002900f88542370000200241002900f08542370000200241124124102c2202450d052002200736001220034198026a41186a2206420037030020034198026a41106a2205420037030020034198026a41086a2208420037030020034200370398022002411620034198026a1000200341f8016a41186a2006290300370300200341f8016a41106a2005290300370300200341f8016a41086a200829030037030020032003290398023703f8012002102a200341003602e805200342013703e005200341e0066a200341e0056a108f01200341c0066a41086a290300210420032903c006210b0240024020032802e405220620032802e80522026b4110490d0020032802e00521060c010b200241106a22052002490d0c200641017422022005200220054b1b22024100480d0c0240024020060d002002102821060c010b20032802e00520062002102c21060b2006450d07200320023602e405200320063602e00520032802e80521020b200620026a220620043700082006200b3700002003200241106a3602e80520034180076a200341e0056a108f01200341d8066a290300210420032903d006210b0240024020032802e405220520032802e80522066b4110490d0020032802e00521020c010b200641106a22022006490d0c200541017422062002200620024b1b22084100480d0c0240024020050d002008102821020c010b20032802e00520052008102c21020b2002450d08200320083602e405200320023602e00520032802e8052106200821050b200220066a220820043700082008200b370000200341f8016a41202002200641106a100702402005450d002002102a0b200341cc066a200736020041002102200341c8066a41003a00002003410b3a00c00641014100200341c0066a10cc010b2002450d010b200041811e3b010820002005360204200020023602002000410a6a41003a00000c160b200041023a00080c150b41c4d1c3004133200341c8076a419cd9c3001038000b411241011037000b412441011037000b200241011037000b200841011037000b200141086a28020021062001280204210502400240024020022d00000d0020022d000141ff01714101460d010b02402006450d002005102a0b200041811c3b010820004113360204200041b49fc6003602004100210e2000410a6a41003a00000c010b02402006450d002005102a0b200041023a00084100210e0b410121054101210641012107410121084101210a41012109410121174101210d410121180c250b02400240024020022d00000d0020022d000141ff01714102470d002001280204210220034180056a41086a220642003703002003420037038005418194c100411020034180056a1008200341b8026a41086a200629030037030020032003290380053703b802200341b8026a41104101410041001003417f470d011098012002490d0220034180056a41086a220642003703002003420037038005418194c100411020034180056a1008200341b8026a41086a200629030037030020032003290380053703b802200320023602c006200341b8026a4110200341c0066a41041007200041023a00080c110b200041811a3b01082000410f360204200041ea9fc6003602002000410a6a41003a00000c100b41a894c1001032000b41bc95c1001032000b200341b8036a41026a2205200141076a2d00003a000020034190016a41086a22072001411c6a29020037030020034190016a41106a220a200141246a29020037030020034190016a41186a2001412c6a290200370300200341b0016a200141346a290200370300200341b8016a2001413c6a290200370300200341c0016a200141c4006a2d00003a0000200320012f00053b01b8032003200141146a29020037039001200141086a28020021082001410c6a2802002109200141106a280200210620022f0001200241036a2d000041107472210d2002410c6a2802002118200241086a280200210e200241046a280200210f20022d0000210202400240024002400240024002400240024002400240024020012d000422170e050001020304000b200341c0066a41146a4101360200200342013702c406200341ccd1c5003602c006200341043602e405200341c4d1c5003602e0052003200341e0056a3602d006200341c0066a41e8cfc300103e000b200341af046a2007290300370000200341b7046a200a2d00003a0000200320032f01b8033b019804200320063600a3042003200936009f042003200836009b0420032003290390013700a704200320052d00003a009a04024002402002417f6a220641024b0d00024020060e03000102000b200e41017420184d0d00200f41ff0171450d010b2002200d7241ff0171450d0041a3d0c3002105410a2118410021060c0e0b20034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a1006210202400240024002400240024002400240024020032802c0062206417f460d002002450d00200320063602e405200320023602e005200341c0066a200341e0056a106d20032802c006220a450d0c20032902c406210420032802c406211802402006450d002002102a0b2003200a3602e0052004a7210e410021022004422088a7220d41014b0d02200d0e020103010b4101210a200341013602e005410021184100210e0b200341f8016a41186a20034198046a41186a290300370300200341f8016a41106a20034198046a41106a290300370300200341f8016a41086a20034198046a41086a29030037030020032003290398043703f8014100210d200341f8016a2106410021050c020b200d210603402006410176220520026a22072002200a20074105746a20034198046a4120109c054101481b2102200620056b220641014b0d000b0b0240200a20024105746a20034198046a4120109c0522060d004193d0c3002105200e450d05200a102a0c050b200341f8016a41186a20034198046a41186a290300370300200341f8016a41106a20034198046a41106a290300370300200341f8016a41086a20034198046a41086a29030037030020032003290398043703f8012006411f7620026a2205200d4b0d01200341f8016a21060b200d200e460d012018210e0c020b41f8b0c0001032000b02402018200d460d002018210e0c010b201841016a22022018490d0c201841017422072002200720024b1b220e41ffffff3f71200e470d0c200e41057422024100480d0c0240024020180d0020021028210a0c010b200a20184105742002102c210a0b200a450d062003200a3602e0050b200a20054105746a220241206a2002200d20056b410574109b051a200241186a200641186a290000370000200241106a200641106a290000370000200241086a200641086a2900003700002002200629000037000020034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b80220032802e0052102200341003602c806200342013703c006200d41016a2207200341c0066a10b40102402007200d490d00200d41057441206a210603402002200341c0066a108f01200241206a2102200641606a22060d000b0b20032802c4062102200341b8026a411020032802c006220620032802c806100702402002450d002006102a0b200341c0066a41186a20034198046a41186a290300370300200341c0066a41106a20034198046a41106a290300370300200341c0066a41086a20034198046a41086a29030037030020032003290398043703c006410021054101410020032802e00522022007108402200341093b01c00641014100200341c0066a10cc01200e450d002002102a0b41102118410021060c0d0b200341af046a2007290300370000200341b7046a200a2d00003a0000200320032f01b8033b019804200320063600a3042003200936009f042003200836009b0420032003290390013700a704200320052d00003a009a04024002402002417f6a220641024b0d00024020060e03000102000b200e41017420184d0d00200f41ff0171450d010b2002200d7241ff0171450d0041a3d0c3002105410a2118410021060c0d0b20034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a100621020240024020032802c0062206417f460d002002450d00200320063602e405200320023602e005200341c0066a200341e0056a106d20032802c006220a450d0620032902c40621042006450d012002102a0c010b420021044101210a0b41002102024002400240024002402004422088a7220d41014b0d00200d0e020201020b200d210603402006410176220520026a22072002200a20074105746a20034198046a4120109c054101481b2102200620056b220641014b0d000b0b200a20024105746a20034198046a4120109c05450d010b41add0c3002105410c21182004a7450d01200a102a410021060c0e0b2002200d4f0d06200a20024105746a2206200641206a2002417f73200d6a410574109b051a20034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c806200342013703c006200d417f6a2205200341c0066a10b40102402005450d00200d41057441606a2106200a210203402002200341c0066a108f01200241206a2102200641606a22060d000b0b20032802c4062102200341b8026a411020032802c006220620032802c806100702402002450d002006102a0b200341c0066a41186a20034198046a41186a290300370300200341c0066a41106a20034198046a41106a290300370300200341c0066a41086a20034198046a41086a29030037030020032003290398043703c006200341c0066a4101200a200510840220034189023b01c0064100210541014100200341c0066a10cc0102402004a7450d00200a102a0b0b410021060c0c0b200341f7056a2007290300370000200341ff056a200a2d00003a0000200320032f01b8033b01e005200320063600eb05200320093600e705200320083600e30520032003290390013700ef05200320052d00003a00e20520034198046a41186a200341b9016a29000037030020034198046a41106a200341b1016a29000037030020034198046a41086a200341a9016a290000370300200320032900a10137039804024002402002417f6a220641024b0d00024020060e03000102000b200e41017420184d0d00200f41ff0171450d010b2002200d7241ff0171450d0041a3d0c3002105410a2118410021060c0c0b02400240200341e0056a20034198046a4120109c050d00410021050c010b20034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a100621020240024020032802c0062206417f460d002002450d0020032006360284052003200236028005200341c0066a20034180056a106d20032802c006220d450d0820032902c40621042006450d012002102a0c010b4101210d420021040b41add0c3002105410c211841002102024002402004422088a7220e41014b0d00200e0e020c010c0b200e210603402006410176220720026a220a2002200d200a4105746a200341e0056a4120109c054101481b2102200620076b220641014b0d000b0b200d20024105746a2206200341e0056a4120109c050d0a20034198026a41186a220520034198046a41186a29030037030020034198026a41106a220720034198046a41106a29030037030020034198026a41086a220a20034198046a41086a2903003703002003200329039804370398022002200e4f0d072006200329039802370000200641186a2005290300370000200641106a2007290300370000200641086a200a290300370000410021020240200e4101460d0041002102200e210603402006410176220520026a22072002200d20074105746a20034198046a4120109c054101481b2102200620056b220641014b0d000b0b0240200d20024105746a20034198046a4120109c050d004193d0c3002105411021180c0b0b200d200e10f00120034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c806200342013703c006200e200341c0066a10b4010240200e450d00200e4105742106200d210203402002200341c0066a108f01200241206a2102200641606a22060d000b0b20032802c4062102200341b8026a411020032802c006220620032802c806100702402002450d002006102a0b200341c0066a41186a200341e0056a41186a290300370300200341c0066a41106a200341e0056a41106a290300370300200341c0066a41086a200341e0056a41086a290300370300200320032903e0053703c006200341c0066a4101200d200e10840220034189043b01c0064100210541014100200341c0066a10cc012004a7450d00200d102a0b0c0a0b024002402002417f6a220541024b0d00024020050e03000102000b200e41017420184d0d00200f41ff0171450d010b2002200d7241ff0171450d0002402009450d002008102a0b41a3d0c3002105410a21180c0c0b2008200610f00120034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c006200341b8026a4110200341c0066a100621050240024020032802c0062207417f460d002005450d002003200736029c042003200536029804200341c0066a20034198046a106d20032802c0062202450d0820032902c40621042007450d012005102a0c010b42002104410121020b2008200620022004422088a710850202402004a7450d002002102a0b20034180056a41086a22024200370300200342003703800541f8cfc300411b20034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341003602c806200342013703c0062006200341c0066a10b40102402006450d00200641057421062008210203402002200341c0066a108f01200241206a2102200641606a22060d000b0b20032802c4062102200341b8026a411020032802c006220620032802c806100702402002450d002006102a0b02402009450d002008102a0b20034189063b01c006410021054101210641014100200341c0066a10cc010c0a0b41c4d1c3004133200341c8076a419cd9c3001038000b200241011037000b41c4d1c3004133200341c8076a419cd9c3001038000b41b0b1c0001032000b41c4d1c3004133200341c8076a419cd9c3001038000b41bcd0c3002002200e1034000b41c4d1c3004133200341c8076a419cd9c3001038000b1031000b2004a7450d00200d102a410021060c010b410021060b0240024002402017417f6a220241034b0d00024020020e0403030300030b200620094572450d010c020b20174104490d012009450d010b2008102a0b20050d00200041023a0008410021180c010b20004181183b01082000201836020420002005360200410021182000410a6a41003a00000b410121054101210641012107410121084101210a41012109410121174101210d0c1c0b200341c0066a41386a200141c0006a290300370300200341c0066a41306a200141386a290300370300200341c0066a41286a200141306a290300370300200341c0066a41206a200141286a290300370300200341c0066a41186a200141206a290300370300200341c0066a41106a200141186a290300370300200341c0066a41086a200141106a2903003703002003200141086a2903003703c00620034190016a41206a200241206a29020037030020034190016a41186a200241186a29020037030020034190016a41106a200241106a29020037030020034190016a41086a200241086a2902003703002003200229020037039001200341386a200341c0066a20034190016a10860202400240200328023822020d00200041023a00084100210d0c010b200328023c210620004181163b0108200020023602004100210d2000410a6a41003a0000200020063602040b410121054101210641012107410121084101210a41012109410121170c1a0b20034190016a41206a200141246a29020037030020034190016a41186a2001411c6a29020037030020034190016a41106a200141146a29020037030020034190016a41086a2001410c6a2902003703002003200129020437039001200341c0066a41206a200241206a290200370300200341c0066a41186a200241186a290200370300200341c0066a41106a200241106a290200370300200341c0066a41086a200241086a290200370300200320022902003703c006200341306a20034190016a200341c0066a10870202400240200328023022020d00200041023a0008410021170c010b2003280234210620004181143b010820002002360200410021172000410a6a41003a0000200020063602040b410121054101210641012107410121084101210a410121090c180b20034190016a41206a200141246a29020037030020034190016a41186a2001411c6a29020037030020034190016a41106a200141146a29020037030020034190016a41086a2001410c6a2902003703002003200129020437039001200341c0066a41206a200241206a290200370300200341c0066a41186a200241186a290200370300200341c0066a41106a200241106a290200370300200341c0066a41086a200241086a290200370300200320022902003703c006200341286a20034190016a200341c0066a10880202400240200328022822020d00200041023a0008410021090c010b200328022c210620004181123b010820002002360200410021092000410a6a41003a0000200020063602040b410121054101210641012107410121084101210a0c160b200341c0066a41286a200141306a290300370300200341c0066a41206a200141286a290300370300200341c0066a41186a200141206a290300370300200341c0066a41106a200141186a290300370300200341c0066a41086a200141106a2903003703002003200141086a2903003703c00620034190016a41206a200241206a29020037030020034190016a41186a200241186a29020037030020034190016a41106a200241106a29020037030020034190016a41086a200241086a2902003703002003200229020037039001200341206a200341c0066a20034190016a10890202400240200328022022020d00200041023a00084100210a0c010b2003280224210620004181103b0108200020023602004100210a2000410a6a41003a0000200020063602040b410121054101210641012107410121080c140b200141086a28020021162001280204211a200341c0066a2001410c6a41e400109a051a2002411a6a2901002104200241196a2d00002118200241186a2d0000210e200241166a2f0100210f200241156a2d00002119200241146a2d00002113200241126a2f0100210c200241116a2d00002112200241106a2d000021072002410e6a2f010021082002410d6a2d0000210a2002410c6a2d000021092002410a6a2f01002117200241096a2d0000210d200241046a2d00002111200241026a2f01002115200241056a280000210520022d0000210620022d00012102200341b8026a200341c0066a41046a41e000109a051a410420054104200241014622021b20061b21050240024002400240024020060d0020020d010b410f210641ea9fc600210202400240024002400240024020050e0700010203040507000b2017410874200d7220094118747221022008410874200a7220074118747221060c060b410e210641dc9fc60021020c050b410c210641d09fc60021020c040b4109210641c79fc60021020c030b4113210641b49fc60021020c020b4111210641a39fc60021020c010b2003200437039805200320183a0097052003200e3a0096052003200f3b019405200320193a009305200320133a0092052003200c3b019005200320123a008f05200320073a008e05200320083b018c052003200a3a008b05200320093a008a05200320173b0188052003200d3a0087052003200536008305200320113a008205200320153b018005024002400240024002400240410e10282202450d002002410029008aaf44370000200241066a4100290090af443700002003428e808080e00137029401200320023602900120034180056a20034190016a108f012003280298012102200328029001210620034198026a41186a2205420037030020034198026a41106a2207420037030020034198026a41086a2208420037030020034200370398022006200220034198026a1000200341f8016a41186a2005290300370300200341f8016a41106a2007290300370300200341f8016a41086a200829030037030020032003290398023703f8010240200328029401450d00200328029001102a0b2003410036029001200341f8016a412020034190016a100621022003280290012206417f460d022002450d022003200636029c02200320023602980220034190016a20034198026a108a0220032802b0012217450d0120034198046a41086a2205200341c0016a29030037030020034198046a41106a2207200341c8016a29030037030020034198046a41186a2208200341d0016a29030037030020034198046a41206a220a200341d8016a2802003602002003200341b8016a2903003703980420032802b401210902402006450d002002102a0b200341e0056a41086a20052903002204370300200341e0056a41106a2007290300220b370300200341e0056a41186a20082903002210370300200341e0056a41206a200a28020022023602002003200329039804221b3703e00520034190016a41106a200b37030020034190016a41086a200437030020034190016a41186a201037030020034190016a41206a2002360200200341f8016a41086a2003419c016a290200370300200341f8016a41106a200341a4016a290200370300200341f8016a41186a200341ac016a2902003703002003201b3703900120032003290294013703f80102402009450d002017102a0b20034198036a41086a200341f8016a41086a29030037030020034198036a41106a200341f8016a41106a29030037030020034198036a41186a200341f8016a41186a290300370300200320032903f80137039803200341b8036a200341b8026a41e000109a051a20034198026a20034198036a108b0220032802a0022106200328029802210220034100360290012002200620034190016a100621062003280290012205417f460d042006450d042003200536028405200320063602800520034190016a20034180056a10e80120032d0090014101460d03200341e0056a20034190016a41017241e000109a051a02402005450d002006102a0b20034180056a200341e0056a41e000109a051a20034190016a20034180056a41e000109a051a200341013a00980420034198046a41017220034190016a41e000109a051a0c050b410e41011037000b41c4d1c3004133200341c8076a419cd9c3001038000b41a5c4c2002102412721060c030b41c4d1c3004133200341c8076a419cd9c3001038000b20034190016a20034180056a41e000109a051a200341003a0098040b0240200328029c02450d002002102a0b200341b9046a2112200341d9046a2111200341b8036a41206a2113200341f8036a210c20034198046a410172211520034190016a41017221054104210741e7e485f30621060240024003400240024002400240200641e9dabdf30646220f0d000240200641e7e485f306470d00200341b8036a210a0c020b200641e2c289ab06470d022013210a0c010b200c210a0b41202102410021084120102822090d01412041011037000b41012108410021024101210a410121090b2009200a2002109a052109200320023602a402200320023602a0022003200936029c022003200636029802200341f8016a20034198026a108c0220034190016a20032802f801221720032802800210fd0120034180056a41086a220d200541086a29000037030020034180056a41106a2218200541106a29000037030020034180056a41186a220e200541186a29000037030020032005290000370380050240024020032d0090014101470d00200341e0056a41186a2219200e290300370300200341e0056a41106a220e2018290300370300200341e0056a41086a2218200d29030037030020032003290380053703e005024020032802fc01450d002017102a0b024020080d002009102a0b20034190016a41186a201929030037030020034190016a41106a200e29030037030020034190016a41086a2018290300370300200320032903e0053703900120034190016a20034198036a4120109c05450d0141ccc4c2002102411821060c050b024020032802fc01450d002017102a0b20080d002009102a0b0240024020032d0098044101470d00024002400240200641e2c289ab06460d00200f0d010240200641e7e485f306460d0041002109410121170c030b41202109201521170c020b41202109201221170c010b41202109201121170b024020022009470d00200a2017460d02200a20172002109c05450d020b0240024020090d004100210d410121180c010b2009210d200910282218450d040b201820172009109a0521172003200936029c012003200d3602980120032017360294012003200636029001200341e0056a20034190016a108c0220032802e005220920032802e8051009024020032802e405450d002009102a0b200d450d002017102a0b41012109024020080d00200210282209450d040b2009200a2002109a05210a2003200236029c0120032002360298012003200a360294012003200636029001200341e0056a20034190016a108c0220032802e0052102200320032802e80536028405200320023602800520034198036a20034180056a10ff01024020032802e405450d002002102a0b20080d00200a102a0b02402007410c460d00200741f8c8c0006a2800002106200741046a21070c010b0b200341e0056a20034198036a108b0220032802e805210620032802e005210220034100360298012003420137039001200341b8036a20034190016a108f01201320034190016a108f01200c20034190016a108f012003280294012105200220062003280290012207200328029801100702402005450d002007102a0b024020032802e405450d002002102a0b2016450d03201a102a0c030b200941011037000b200241011037000b02402016450d00201a102a0b2002450d00200041810e3b01082000200636020420002002360200410021082000410a6a41003a00000c010b200041023a0008410021080b4101210541012106410121070c120b200341c0066a41306a200141386a290300370300200341c0066a41286a200141306a290300370300200341c0066a41206a200141286a290300370300200341c0066a41186a200141206a290300370300200341c0066a41106a200141186a290300370300200341c0066a41086a200141106a2903003703002003200141086a2903003703c00620034190016a41206a200241206a29020037030020034190016a41186a200241186a29020037030020034190016a41106a200241106a29020037030020034190016a41086a200241086a2902003703002003200229020037039001200341186a200341c0066a20034190016a108d0202400240200328021822020d00200041023a0008410021070c010b200328021c2106200041810c3b010820002002360200410021072000410a6a41003a0000200020063602040b41012105410121060c100b200141256a2900002110200141246a2d0000211a200141216a2f00002113200141206a2d0000210c2001411d6a2f000021122001411c6a2d00002111200141196a2f00002109200141186a2d00002117200141156a2f0000210d200141146a2d00002118200141106a28020021052001410d6a2f0000210e2001410c6a2d00002127200141086a2802002107200141306a2903002104200141386a290300210b20012d0023211520012d001f211420012d001b210f20012d0017211920012d000f211620034198046a41106a200141d0006a2d00003a000020034198046a41086a221e200141c8006a2903003703002003200141c0006a290300370398044111210620022d0001210820022d0000210a02400240024002400240024002400240024002400240024002400240024020070e0400010203000b200341c0066a41146a4101360200200342013702c406200341ccd1c5003602c006200341043602e405200341c4d1c5003602e0052003200341e0056a3602d006200341c0066a41e092c100103e000b200241106a2d0000211e2002410e6a2f0100211f2002410d6a2d000021202002410c6a2d000021212002410a6a2f01002122200241096a2d000021234104200241056a2800004104200841ff017141014622081b200a41ff017122061b21070240024020060d0020080d010b410f210641ea9fc600210202400240024002400240024020070e0700010203040511000b20224108742023722021411874722102201f410874202072201e4118747221060c100b410e210641dc9fc60021020c0f0b410c210641d09fc60021020c0e0b4109210641c79fc60021020c0d0b4113210641b49fc60021020c0c0b4111210641a39fc60021020c0b0b200241196a2d00002106200241186a2d00002108200241166a2f0100210a200241156a2d00002124200241146a2d00002125200241126a2f01002126200241116a2d00002128200241046a2d00002129200241026a2f0100212a20032002411a6a2901003703a801200320063a00a701200320083a00a6012003200a3b01a401200320243a00a301200320253a00a201200320263b01a001200320283a009f012003201e3a009e012003201f3b019c01200320203a009b01200320213a009a01200320223b019801200320233a0097012003200736009301200320293a0092012003202a3b01900102400240202741ff01714101470d00200341e0056a200541067610fe0120032802e00521060240024020032802e8052005413f7122024b0d00410021020c010b200620024105746a2202290018211020022d0017211a20022d0016211520022f0014211320022d0013210c20022d0012211420022f0010211220022d000f211120022d000e210f20022f000c210920022d000b211720022d000a211920022f0008210d20022d000721182002280003210520022d0002211620022f0000210e410121020b024020032802e405450d002006102a0b20020d00410121020c010b410021020b20032010370390022003201a3a008f02200320153a008e02200320133b018c022003200c3a008b02200320143a008a02200320123b018802200320113a0087022003200f3a008602200320093b018402200320173a008302200320193a0082022003200d3b018002200320183a00ff01200320053600fb01200320163a00fa012003200e3b01f80120020d09200341c0066a41186a200341f8016a41186a290300370300200341c0066a41106a200341f8016a41106a290300370300200341c0066a41086a200341f8016a41086a290300370300200320032903f8013703c006200341086a20034190016a200341c0066a2004200b108e0220032802082202450d0b200328020c21060c0a0b41a39fc60021022008200a7241ff01710d0b201e290300211b200329039804211c0240202741ff01714101470d0020034190016a200541067610fe012003280290012106024002402003280298012005413f7122024b0d00410021020c010b200620024105746a2202290018211020022d0017211a20022d0016211520022f0014211320022d0013210c20022d0012211420022f0010211220022d000f211120022d000e210f20022f000c210920022d000b211720022d000a211920022f0008210d20022d000721182002280003210520022d0002211620022f0000210e410121020b0240200328029401450d002006102a0b2002450d080b200320103703d8062003201a3a00d706200320153a00d606200320133b01d4062003200c3a00d306200320143a00d206200320123b01d006200320113a00cf062003200f3a00ce06200320093b01cc06200320173a00cb06200320193a00ca062003200d3b01c806200320183a00c706200320053600c306200320163a00c2062003200e3b01c006411410282202450d01200241002900cfe140370000200241106a41002800dfe140360000200241086a41002900d7e14037000020034294808080c002370294012003200236029001200341c0066a20034190016a108f012003280298012102200328029001210620034198026a41186a2205420037030020034198026a41106a2207420037030020034198026a41086a2208420037030020034200370398022006200220034198026a1000200341f8016a41186a2005290300370300200341f8016a41106a2007290300370300200341f8016a41086a200829030037030020032003290398023703f8010240200328029401450d00200328029001102a0b2003410036029001200341f8016a412020034190016a100621022003280290012206417f460d052002450d0520064110490d02200241086a29000021102002290000211d2002102a0c060b41a39fc60021022008200a7241ff01710d0a200141e0006a290300211c200141d8006a290300211d20032900a104211b20032d00a004210720032d009f04210820032f009d04210a20032d009c04211e20032d009b04211f20032f009904212020032d00980421210240202741ff01714101470d00200341c0066a200541067610fe0120032802c00621060240024020032802c8062005413f7122024b0d00410021020c010b200620024105746a2202290018211020022d0017211a20022d0016211520022f0014211320022d0013210c20022d0012211420022f0010211220022d000f211120022d000e210f20022f000c210920022d000b211720022d000a211920022f0008210d20022d000721182002280003210520022d0002211620022f0000210e410121020b024020032802c406450d002006102a0b2002450d070b2004422088a72106200320103703a8012003201a3a00a701200320153a00a601200320133b01a4012003200c3a00a301200320143a00a201200320123b01a001200320113a009f012003200f3a009e01200320093b019c01200320173a009b01200320193a009a012003200d3b019801200320183a0097012003200536009301200320163a0092012003200e3b01900102402004a741ff01714101460d00200ba72118200b423888a7210f200b422888a72109200b422088a72117200b421888a72119200b420888a7210d2004421888a721162004420888a7210e0c030b200341e0056a2004422688a710fe0120032802e00521050240024020032802e8052006413f7122024b0d00410021022013210a200c211e2014211f201221202011212120152108201a21072010211b0c010b200520024105746a2202290018211b20022d0017210720022d0016210820022f0014210a20022d0013211e20022d0012211f20022f0010212020022d000f212120022d000e210f20022f000c210920022d000b211720022d000a211920022f0008210d20022d000721182002280003210620022d0002211620022f0000210e410121020b024020032802e405450d002005102a0b20020d02410121020c030b411441011037000b41c4d1c3004133200341c8076a419cd9c3001038000b410021020b2003201b37039002200320073a008f02200320083a008e022003200a3b018c022003201e3a008b022003201f3a008a02200320203b018802200320213a0087022003200f3a008602200320093b018402200320173a008302200320193a0082022003200d3b018002200320183a00ff01200320063600fb01200320163a00fa012003200e3b01f80120020d03200341c0066a41186a200341f8016a41186a290300370300200341c0066a41106a200341f8016a41106a290300370300200341c0066a41086a200341f8016a41086a290300370300200320032903f8013703c006200341106a20034190016a200341c0066a201d201c108e0220032802102202450d05200328021421060c040b4200211d420021100b02400240201d20045422062010200b542010200b5122021b0d00201d2004562010200b5620021b450d012003201d20047d3703900120032010200b7d2006ad7d37039801200320034190016a3602e005200341e0056a109d010c010b20032004201d7d370390012003200b20107d2004201d54ad7d37039801200320034190016a3602e005200341e0056a109c010b200341c0066a2004200b108f020240024002400240411810282202450d00200241002900e3e140370000200241106a41002900f3e140370000200241086a41002900ebe140370000200342988080808003370294012003200236029001200341c0066a20034190016a108f012003280298012102200328029001210620034198026a41186a2205420037030020034198026a41106a2207420037030020034198026a41086a2208420037030020034200370398022006200220034198026a1000200341f8016a41186a2005290300370300200341f8016a41106a2007290300370300200341f8016a41086a200829030037030020032003290398023703f8010240200328029401450d00200328029001102a0b2003410036029001200341f8016a412020034190016a100621022003280290012206417f460d022002450d0220064110490d01200241086a29000021042002290000210b2002102a0c030b411841011037000b41c4d1c3004133200341c8076a419cd9c3001038000b4200210b420021040b02400240200b201c5422062004201b542004201b5122021b0d00200b201c562004201b5620021b450d012003200b201c7d3703900120032004201b7d2006ad7d37039801200320034190016a3602e005200341e0056a109d010c010b2003201c200b7d370390012003201b20047d201c200b54ad7d37039801200320034190016a3602e005200341e0056a109c010b200341c0066a201c201b1090020c030b41dc9fc6002102410e21060c030b41dc9fc6002102410e21060b20020d010b200041023a00080c010b200041810a3b010820002006360204200020023602002000410a6a41003a00000b41012105410121060c0d0b109102000b024020032802cc062206450d0020032802c4062102200641246c210603400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a280200102a0c030b2002410c6a280200450d02200241086a280200102a0c020b2002410c6a280200450d01200241086a280200102a0c010b200241086a280200450d00200241046a280200102a0b200241246a21022006415c6a22060d000b0b024020032802c806450d0020032802c406102a0b024020072008460d0003402007280204220a450d01200741086a280200210902402007410c6a2802002202450d00200241246c2106200a210203400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a280200102a0c030b2002410c6a280200450d02200241086a280200102a0c020b2002410c6a280200450d01200241086a280200102a0c010b200241086a280200450d00200241046a280200102a0b200241246a21022006415c6a22060d000b0b200741f0006a210702402009450d00200a102a0b20072008470d000b0b0240200c450d00200d102a0b2004a7450d032017102a0c030b20072008460d0003402007280204220a450d01200741086a280200210902402007410c6a2802002202450d00200241246c2106200a210203400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a280200102a0c030b2002410c6a280200450d02200241086a280200102a0c020b2002410c6a280200450d01200241086a280200102a0c010b200241086a280200450d00200241046a280200102a0b200241246a21022006415c6a22060d000b0b200741f0006a210702402009450d00200a102a0b20072008470d000b0b0240200c450d00200d102a0b20034180056a41086a2202420037030020034200370380054193cdc200411120034180056a1008200341b8026a41086a200229030037030020032003290380053703b802200341c0066a20032802980322022004422088a7109202200341b8026a411020032802c006220620032802c8061007024020032802c406450d002006102a0b02402004a7450d002002102a0b200041023a000841002106410121050c090b02402005450d00200d200541f0006c6a2108200d2107034002402007410c6a2802002206450d0020072802042102200641246c210603400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a280200102a0c030b2002410c6a280200450d02200241086a280200102a0c020b2002410c6a280200450d01200241086a280200102a0c010b200241086a280200450d00200241046a280200102a0b200241246a21022006415c6a22060d000b0b200741f0006a21020240200741086a280200450d002007280204102a0b2002210720022008470d000b0b200c450d00200d102a0b20004181063b01082000200f3602042000200e360200410021062000410a6a41003a0000410121050c070b2005102a0b0240024002402007417f6a220241054b0d00024002400240024020020e06060006010203060b41000d052004a70d040c050b41000d042004a70d030c040b200a450d0302402004422088a72202450d00200241186c21062005210203400240200241046a280200450d002002280200102a0b0240200241106a280200450d002002410c6a280200102a0b200241186a2102200641686a22060d000b0b2004a70d020c030b2006450d0202402004422088a72202450d002002410c6c21062005210203400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b2004a70d010c020b02402004422088a72202450d002002410c6c21062005210203400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b2004a7450d010b2005102a0b410f210241ea9fc6002105410621072008417c6a0e0402010300020b200041023a0008410121060c030b4111210241a39fc6002105410521070c010b4113210241b49fc6002105410421070b41012106200041013b010820002002360204200020053602002000410a6a20073a00000b410021050b410121070b410121080b4101210a0b410121090b410121170b4101210d0b410121180b4101210e0b4101210f410121190b410121160b02402001280200220241124b0d00024002400240024002400240024002400240024002400240024020020e13000d0d010d0d020304050607080d090d0a0b0c000b2005450d0c0240200141086a280200220241054b0d0002400240024020020e06101000100102100b200141106a280200450d0f2001410c6a280200102a0c0f0b200141106a280200450d0e2001410c6a280200102a0c0e0b0240200141146a2802002206450d002001410c6a2802002102200641186c210603400240200241046a280200450d002002280200102a0b0240200241106a280200450d002002410c6a280200102a0b200241186a2102200641686a22060d000b0b200141106a280200450d0d200128020c102a0c0d0b0240200141146a2802002206450d002001410c6a28020021022006410c6c210603400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b200141106a280200450d0c200128020c102a0c0c0b2006450d0b02402001410c6a2802002202450d0020012802042200200241f0006c6a2107034002402000410c6a2802002206450d0020002802042102200641246c210603400240024020022d0000220541034b0d0002400240024020050e0404000102040b2002410c6a280200450d03200241086a280200102a0c030b2002410c6a280200450d02200241086a280200102a0c020b2002410c6a280200450d01200241086a280200102a0c010b200241086a280200450d00200241046a280200102a0b200241246a21022006415c6a22060d000b0b200041f0006a21020240200041086a280200450d002000280204102a0b2002210020022007470d000b0b200141086a280200450d0b2001280204102a0c0b0b2007450d0a0240200141086a2d00002202410c4b0d0020024106470d0b200141106a280200450d0b2001410c6a280200102a0c0b0b200141106a280200450d0a2001410c6a280200102a0c0a0b2008450d09200141086a280200450d092001280204102a0c090b200a450d08200141086a2d0000417f6a220241074b0d08024002400240024020020e08000c0c0c0c010203000b2001410c6a2202280200106a2002280200102a0c0b0b2001410c6a2202280200106a2002280200102a0c0a0b2001410c6a2202280200106a2002280200102a0c090b2001410c6a2202280200106a2002280200102a0c080b2009450d0720012d0004417f6a220241024b0d0702400240024020020e03000102000b2001410c6a280200450d09200141086a280200102a0c090b200141086a2202280200106a2002280200102a0c080b2001410c6a2202280200106a2002280200102a0c070b2017450d0620012d0004417f6a220241024b0d0602400240024020020e03000102000b2001410c6a280200450d08200141086a280200102a0c080b200141086a2202280200106a2002280200102a0c070b2001410c6a2202280200106a2002280200102a0c060b200d450d05200141086a280200417f6a220241014b0d050240024020020e020001000b200141106a280200450d062001410c6a280200102a0c060b200141106a280200450d052001410c6a280200102a0c050b2018450d0420012d00044104490d042001410c6a280200450d04200141086a280200102a0c040b200e450d03200141086a280200450d032001280204102a0c030b200f450d02200141086a2d0000417e6a220241024b0d0202400240024020020e03000102000b200141106a280200450d042001410c6a280200102a0c040b200141346a280200450d03200141306a280200102a0c030b200141306a280200450d022001412c6a280200102a0c020b2019450d0102402001280204220241024b0d00024020020e03030003030b200141086a2202280200106a2002280200102a0c020b2001412c6a2202280200106a2002280200102a0c010b2016450d0002402001410c6a280200450d00200141086a280200102a0b02402001411c6a2802002206450d00200141146a28020021022006410c6c210603400240200241046a280200450d002002280200102a0b2002410c6a2102200641746a22060d000b0b200141186a280200450d002001280214102a0b200341d0076a24000b4d01017f230041206b22002400200041146a410136020020004201370204200041ccd1c5003602002000410436021c200041c4d1c5003602182000200041186a360210200041a8c6c200103e000bfa0301077f230041306b22022400200241003602082002420137030020022002360210200141106a200241106a10c8012001200210a00120022002360210200141306a200241106a10c80120022002360210200141d0006a200241106a10c801200128020421032001410c6a2802002201200210b4010240024002402001450d00200141246c21040340200241106a200310ec01200228021021050240024020022802042206200228020822016b20022802182207490d00200228020021060c010b200120076a22082001490d04200641017422012008200120084b1b22014100480d040240024020060d002001102821060c010b200228020020062001102c21060b2006450d032002200136020420022006360200200228020821010b2002200120076a360208200620016a20052007109a051a02402002280214450d002005102a0b200341246a21032004415c6a22040d000b0b200228020421072002280208210320022802002101200241106a41186a22064200370300200241106a41106a22054200370300200241106a41086a220442003703002002420037031020012003200241106a1000200041186a2006290300370000200041106a2005290300370000200041086a20042903003700002000200229031037000002402007450d002001102a0b200241306a24000f0b200141011037000b1031000ba80301047f230041f0006b2202240002400240411010282203450d00200341086a41002900c6f042370000200341002900bef042370000200341104120102c2203450d0120032001360010200241086a41186a22014200370300200241086a41106a22044200370300200241086a41086a220542003703002002420037030820034114200241086a1000200241306a41186a2001290300370300200241306a41106a2004290300370300200241306a41086a2005290300370300200220022903083703302003102a200241086a200241306a412010a703200241d0006a41086a200241116a290000370300200241d0006a41106a2203200241196a290000370300200241d0006a41186a2201200241216a290000370300200220022900093703500240024020022d00084101460d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20002002290350370000200041186a2001290300370000200041106a2003290300370000200041086a200241d0006a41086a2903003700000b200241f0006a24000f0b411041011037000b412041011037000bd50c04077f017e027f017e230041b0016b22012400200141306a41086a220242003703002001420037033041afc5c2004111200141306a1008200141086a200229030037030020012001290330370300200141c0006a2001411010fd0120012d00402103200141106a41186a2204200141d9006a290000370300200141106a41106a2205200141c0006a41116a290000370300200141106a41086a2206200141c9006a290000370300200120012900413703100240024020034101470d0020002001290310370000200041186a2004290300370000200041106a2005290300370000200041086a20062903003700000c010b200141c0006a41086a220342003703002001420037034041b1f0c200410d200141c0006a1008200220032903003703002001200129034037033020014100360240200141306a4110200141c0006a1006210202400240024020012802402203417f460d002002450d002001200336021420012002360210200141c0006a200141106a107620012802402207450d02200129024421082003450d012002102a0c010b41042107420021080b20072008422088a7220941246c6a2104200721020240024002400240034002400240200420026b41ed00490d0003400240200222032d00004101470d00200341246a210a200341106a2105200341086a2106200341016a21020c030b0240200341246a2d00004101470d00200341c8006a210a200341346a21052003412c6a2106200341256a21020c030b0240200341c8006a2d00004101470d00200341ec006a210a200341d8006a2105200341d0006a2106200341c9006a21020c030b0240200341ec006a2d00004101470d0020034190016a210a200341fc006a2105200341f4006a2106200341ed006a21020c030b200420034190016a22026b41ec004b0d000b20034190016a21020b20022004460d020240034020022d00004101460d012004200241246a2202460d040c000b0b200241246a210a200241106a2105200241086a2106200241016a21020b200228000021022006280200210320012005280200360214200120033602100240200241c28289aa04460d00200a21020c010b0b200141c0006a200141106a10ba0220012d004022024102460d00200141a4016a28020021062001280244210a4200210b200141306a41086a220342003703002001420037033041c785c2004112200141306a1008200141c0006a41086a20032903003703002001200129033037034020014100360210200141c0006a4110200141106a100621050240024020012802102203417f460d002001200336023420012005360230200141106a200141306a106d20012802102204450d052001290214210b2003450d012005102a0c010b410121040b410021030240200a200620024101711b2202200b422088a74f0d00200420024105746a2202450d00200141106a41186a200241186a290000370300200141106a41106a200241106a290000370300200141106a41086a200241086a29000037030020012002290000370310410121030b0240200ba7450d002004102a0b20030d010b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b200141c0006a41186a2202200141106a41186a290300370300200141c0006a41106a2203200141106a41106a290300370300200141c0006a41086a2204200141106a41086a29030037030020012001290310370340200141306a41086a220542003703002001420037033041afc5c2004111200141306a1008200141086a2005290300370300200120012903303703002001411036023420012001360230200141c0006a200141306a10ff01200041186a2002290300370000200041106a2003290300370000200041086a2004290300370000200020012903403700000b02402009450d00200941246c21032007210203400240024020022d0000220441034b0d0002400240024020040e0404000102040b2002410c6a280200450d03200241086a280200102a0c030b2002410c6a280200450d02200241086a280200102a0c020b2002410c6a280200450d01200241086a280200102a0c010b200241086a280200450d00200241046a280200102a0b200241246a21022003415c6a22030d000b0b2008a7450d022007102a0c020b41c4d1c30041332001419cd9c3001038000b41c4d1c30041332001419cd9c3001038000b200141b0016a24000b860c07057f017e047f027e037f027e047f230041c0006b22012400200141106a41086a220242003703002001420037031041f09cc600411e200141106a1008200141086a2203200229030037030020012001290310370300200141106a200110de03200128021021042001280214210520012903182106200028020821072000280204210820002802002109200242003703002001420037031041a5afc4004116200141106a100820032002290300370300200120012903103703002001410036021020014110200141106a100621000240024002400240024002400240024020012802102202417f460d002000450d002001200236023420012000360230200141106a200141306a106d2001280210220a450d022001290214210b2002450d012000102a0c010b4101210a4200210b0b2006420020051b210c2004410020051b21042005410420051b210d02402007450d002009200741246c6a210e200a200b422088a74105746a21032009210203402002280220210f200241086a2900002106200241106a290000211020022900002111200141106a41186a200241186a290000370300200141106a41106a2010370300200141106a41086a200637030020012011370310200241246a2102200a2105410021000240024003400240200320056b41e0004b0d0020052003460d030340200141106a2005460d0320002005200141106a4120109c0522074100476a21002007450d032003200541206a2205470d000c040b0b200141106a2005460d0120002005200141106a4120109c0522074100476a21002007450d01200541206a2207200141106a460d0120002007200141106a4120109c0522074100476a21002007450d01200541c0006a2207200141106a460d0120002007200141106a4120109c0522074100476a21002007450d01200541e0006a2207200141106a460d0120054180016a210520002007200141106a4120109c0522074100476a210020070d000b0b2004200f6a22072004490d000240200041016a2204200c422088a722054d0d000240200ca7221220056b20042005200420054b1b221320056b22044f0d00200520046a22142005490d0a201241017422152014201520144b1b221441ffffffff03712014470d0a201441027422154100480d0a0240024020120d0020151028210d0c010b200d20124102742015102c210d0b200d450d062014ad210c0b200d20054102746a21120240024020044102490d002012410020132005417f736a22044102741099051a200d200520136a20056b4102746a417c6a2112200420056a21050c010b2004450d010b20124100360200200541016a21050b200520004d0d05200d20004102746a22002000280200200f6a360200200c42ffffffff0f832005ad42208684210c200721040b2002200e470d000b0b02402008450d002009102a0b0240200ba7450d00200a102a0b200141106a41086a220542003703002001420037031041f09cc600411e200141106a1008200141086a20052903003703002001200129031037030002400240200d0d002001411010090c010b2001410036021820014201370310410410282205450d042005200436000020014284808080c00037021420012005360210200c422088a72205200141106a10b4010240024020050d002001280218210420012802142103200128021021000c010b2005410274210f4100200128021822056b210220012802142103200d210703402007280200210a02400240200320026a4104490d00200128021021000c010b200541046a22002005490d09200341017422042000200420004b1b22044100480d090240024020030d002004102821000c010b200128021020032004102c21000b2000450d082001200436021420012000360210200421030b200741046a21072001200541046a2204360218200020056a200a3600002002417c6a210220042105200f417c6a220f0d000b0b200ca721052001411020002004100702402003450d002000102a0b2005450d00200d102a0b200141c0006a24000f0b41c4d1c3004133200141386a419cd9c3001038000b201541041037000b41ac9bc600200020051034000b410441011037000b200441011037000b1031000b4d01017f230041206b22002400200041146a410136020020004201370204200041ccd1c5003602002000410436021c200041c4d1c5003602182000200041186a3602102000419896c400103e000ba70101047f230041206b22002400200041106a41086a2201420037030020004200370310419499c6004114200041106a1008200041086a200129030037030020002000290310370300410021022000410036021020004110200041106a100621010240024020002802102203417f460d002001450d0020034104490d01200128000021022001102a0b200041206a240020020f0b41c4d1c3004133200041106a419cd9c3001038000b9d0401067f230041d0006b220324000240024002400240411b10282204450d00200441176a41002800d89646360000200441106a41002900d19646370000200441086a41002900c99646370000200441002900c196463700002004411b4136102c2204450d012004200136001b200341306a41186a22014200370300200341306a41106a22054200370300200341306a41086a22064200370300200342003703302004411f200341306a1000200341086a41186a22072001290300370300200341086a41106a2005290300370300200341086a41086a2006290300370300200320032903303703082004102a412010282204450d0220042003290308370000200441186a2007290300370000200441106a200341086a41106a2205290300370000200441086a200341086a41086a22062903003700002003200236022c20014200370300200341306a41106a22024200370300200341306a41086a22084200370300200342003703302003412c6a4104200341306a1000200720012903003703002005200229030037030020062008290300370300200320032903303703082004412041c000102c2204450d0320042003290308370020200441386a200341206a290300370000200441306a2005290300370000200441286a2006290300370000200042c0808080800837020420002004360200200341d0006a24000f0b411b41011037000b413641011037000b412041011037000b41c00041011037000bcb0201047f230041d0006b220324002003410036022820012002200341286a1006210402400240024020032802282205417f460d0020040d010b200041003a00000c010b41002101200341003a00480340024020052001470d000240200141ff0171450d00200341003a00480b41c4d1c3004133200341286a419cd9c3001038000b200341286a20016a200420016a2d00003a00002003200141016a22023a00482002210120024120470d000b200341086a41186a2201200341286a41186a290300370300200341086a41106a2202200341286a41106a290300370300200341086a41086a2206200341286a41086a2903003703002003200329032837030802402005450d002004102a0b20002003290308370001200041013a0000200041196a2001290300370000200041116a2002290300370000200041096a20062903003700000b200341d0006a24000bec0202047f017e230041d0006b22022400024002400240410f10282203450d00200341076a4100290092b4433700002003410029008bb4433700002003410f411e102c2203450d012003200136000f200241286a41186a22014200370300200241286a41106a22044200370300200241286a41086a220542003703002002420037032820034113200241286a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903283703002003102a2002410036022820024120200241286a100621010240024020022802282203417f460d002002200336022420022001360220200241286a200241206a106d20022802282204450d04200229022c210602402003450d002001102a0b20002006370204200020043602000c010b20004100360208200042013702000b200241d0006a24000f0b410f41011037000b411e41011037000b41c4d1c3004133200241c8006a419cd9c3001038000bdf0301017f024002400240024002400240410110282202450d00200220002d00003a0000200241014102102c2202450d01200220002d00013a0001200241024104102c2202450d02200220002d00023a0002200220002d00033a0003200241044108102c2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102c2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102c2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f200128020020012802042002412010072002102a0f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000bf54606077f027e0f7f047e117f017e230041800a6b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e06000102030405000b200341cc026a4101360200200342013702bc02200341ccd1c5003602b802200341043602b406200341c4d1c5003602b0062003200341b0066a3602c802200341b8026a41e893c400103e000b200141e0006a2802002104200341b0066a200141086a41d800109a051a20034198056a200141fc006a28020036020020034190056a200141f4006a29020037030020034180056a41086a200141ec006a2902003703002003200141e4006a29020037038005024020022d000120022d000072450d0041a39fc600210541112104410121060c120b200341b8026a10f70302402003280290032004490d0041f893c400210541352104410121060c120b200341b8026a41086a41033a00002003410c3a00b802200341b8026a410c6a20043602004100210541014100200341b8026a10cc01200341b8026a200341b0066a41d800109a051a2003419c036a20034180056a41086a290300370200200341a4036a20034180056a41106a290300370200200341ac036a20034180056a41186a2802003602002003200436029003200320032903800537029403200341c0086a41086a22024200370300200342003703c00841c0fec5004118200341c0086a100820034180046a41086a2002290300370300200320032903c00837038004200341003602c808200342013703c008200341b8026a200341c0086a10ee0120032802c408210220034180046a411020032802c008220420032802c80810072002450d0f2004102a0c0f0b2001410c6a2802002107200141086a280200210841042104200141046a2802002109200141106a290300210a2002411a6a290100210b200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d000021132002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241096a2d00002118200241046a2d00002119200241026a2f0100211a0240024020022d00000d0020022d00014101470d00200241056a2d00002104200241066a2f01002105200241086a2d00002102410021060c010b4101210641002102410021050b200541ffff0371410874200241187472200441ff017172210202402006450d0041ea9fc6002105410f210402400240024002400240024020020e0700010203040513000b20174108742018722016411874722105201441087420157220134118747221040c120b41dc9fc6002105410e21040c110b41d09fc6002105410c21040c100b41c79fc6002105410921040c0f0b41b49fc6002105411321040c0e0b41a39fc6002105411121040c0d0b2003200b370398042003200c3a0097042003200d3a0096042003200e3b0194042003200f3a009304200320103a009204200320113b019004200320123a008f04200320133a008e04200320143b018c04200320153a008b04200320163a008a04200320173b018804200320183a0087042003200236008304200320193a0082042003201a3b018004200341e8006a10f603024002402003290368220b200341e8006a41086a290300221b8450450d004200211c4200211d0c010b200341c8006a201b4200200a4200109f05200341d8006a200b4200200a4200109f05200341386a42004200200b4200109f0502402003290350200329034084420052200341e0006a290300221c200329034820032903387c7c221d201c5472450d0041a6b5c0002105412721040c0e0b2003290358211c0b200341b8026a20034180046a201c201d4108109802024020032802b8024101470d0020032802c002210420032802bc0221050c0d0b200341c8026a290300211c20032903c002211d200341b8026a10f703200341286a20032903b80242002007ad4200109f050240200a427f200329032820032903304200521b7d221e200a562205450d0041fdbfc2002102412c21040c0b0b200341b0066a20092007200341b8026a10f802024020032802b0064101470d00200341b8066a280200210420032802b40621020c0b0b200341c8096a41186a2206200341b0066a410472220241186a280200360200200341c8096a41106a2216200241106a290200370300200341c8096a41086a2217200241086a290200370300200320022902003703c80920034180056a41186a2213420037030020034180056a41106a2214420037030020034180056a41086a2215420037030020034200370380052009200720034180056a1000200341da016a221820032d0082053a000020034198026a41086a220c20034180056a41136a290000370300200341a5026a220d2013290000370000200320032f0180053b01d8012003200329008b053703980220032800830521022003280087052104200341e0076a41186a2006280200360200200341e0076a41106a2016290300370300200341e0076a41086a2017290300370300200320032903c8093703e007200320043600b706200320023600b306200320182d00003a00b206200320032f01d8013b01b006200341b0066a41136a200c290300370000200341b0066a41186a200d29000037000020032003290398023700bb06411410282206450d03200641002900ddd843370000200641106a41002800edd843360000200641086a41002900e5d84337000020034294808080c0023702fc01200320063602f8012003200341f8016a36028005200341b0066a20034180056a10c80120032802f8012106200328028002211620134200370300201442003703002015420037030020034200370380052006201620034180056a1000200341c0086a41186a2013290300370300200341c0086a41106a2014290300370300200341c0086a41086a201529030037030020032003290380053703c008024020032802fc01450d0020032802f801102a0b200341203602b4062003200341c0086a3602b006200341e0076a200341b0066a10f9020240200341f0076a280200450d0020032802ec07102a0b200341c3066a20034198026a41086a290300370000200341b0066a41186a20034198026a410d6a2900003700002003200341da016a2d00003a00b206200320032f01d8013b01b006200320043600b706200320023600b30620032003290398023700bb06411510282206450d04200641002900c8d8433700002006410d6a41002900d5d843370000200641086a41002900d0d84337000020034295808080d0023702e407200320063602e0072003200341e0076a36028005200341b0066a20034180056a10c80120032802e007210620032802e807211320034180056a41186a2214420037030020034180056a41106a2215420037030020034180056a41086a2216420037030020034200370380052006201320034180056a1000200341c0086a41186a2014290300370300200341c0086a41106a2015290300370300200341c0086a41086a201629030037030020032003290380053703c008024020032802e407450d0020032802e007102a0b200341203602b4062003200341c0086a3602b00620092007200341b0066a10cb0102402008450d002009102a0b200341f8016a41026a200341d8016a41026a2d000022063a000020034180056a41086a221320034198026a41086a29030037030020034180056a410d6a220820034198026a410d6a290000370000200320032f01d80122093b01f801200320032903980237038005200341b0066a41086a41023a0000200341b9066a20093b0000200341bb066a20063a0000200341c0066a20043602002003410c3a00b006200341b0066a410c6a2002360200200341c4066a200329038005370200200341cc066a2013290300370200200341d1066a20082900003700004100211341014100200341b0066a10cc010c0b0b200141c0006a290300210b200141386a290300211d2002411a6a290100211c200241196a2d0000211f200241186a2d00002120200241166a2f01002121200241156a2d00002122200241146a2d00002123200241126a2f01002124200241116a2d00002125200241106a2d000021262002410e6a2f010021272002410d6a2d000021282002410c6a2d000021292002410a6a2f0100212a200241096a2d0000212b41042104200241046a2d0000212c200241026a2f0100212d200141306a280200212e2001412c6a2802002108200141286a28020021092001411d6a290000210a2001411c6a2d000021142001411b6a2d00002115200141196a2f00002116200141186a2d00002117200141176a2d00002118200141156a2f0000210c200141146a2d0000210d200141136a2d0000210e200141116a2f0000210f200141106a2d000021102001410f6a2d000021112001410d6a2f000021122001410c6a2d00002119200141086a2802002105200141076a2d0000211a200141056a2f00002107200141046a2d0000212f200141c8006a290300211b0240024020022d00000d0020022d00014101470d00200241056a2d00002104200241066a2f01002106200241086a2d00002102410021130c010b4101211341002102410021060b200641ffff0371410874200241187472200441ff01717221060240024002402013450d0041ea9fc6002105410f21040240024002400240024020060e0700060102030410000b202a410874202b722029411874722105202741087420287220264118747221040c0f0b41d09fc6002105410c21040c0e0b41c79fc6002105410921040c0d0b41b49fc6002105411321040c0c0b41a39fc6002105411121040c0b0b202f41ff01714101470d01200341b8026a200541067610fe0120032802b80221040240024020032802c0022005413f7122024b0d00410021020c010b200420024105746a2202290018210a20022d0017211420022d0016211520022f0014211620022d0013211720022d0012211820022f0010210c20022d000f210d20022d000e210e20022f000c210f20022d000b211020022d000a211120022f0008211220022d000721192002280003210520022d0002211a20022f00002107410121020b024020032802bc02450d002004102a0b20020d010b41dc9fc6002105410e21040c090b2003201c3703c8062003201f3a00c706200320203a00c606200320213b01c406200320223a00c306200320233a00c206200320243b01c006200320253a00bf06200320263a00be06200320273b01bc06200320283a00bb06200320293a00ba062003202a3b01b8062003202b3a00b706200320063600b3062003202c3a00b2062003202d3b01b0062003200a3703d002200320143a00cf02200320153a00ce02200320163b01cc02200320173a00cb02200320183a00ca022003200c3b01c8022003200d3a00c7022003200e3a00c6022003200f3b01c402200320103a00c302200320113a00c202200320123b01c002200320193a00bf02200320053600bb022003201a3a00ba02200320073b01b8022003202e3602c808200320083602c408200320093602c00820034180056a200341b0066a200341b8026a201d200b201b200341c0086a10f5030240024002402003280280054101460d00024020034188056a280200450d00200328028405102a0b41002113410121060c010b4101210620032802840522050d01410021130b41012108410021050c110b20034188056a2802002104024020034190056a280200450d002003418c056a280200102a0b41002113410121080c100b200141386a290300211c200141306a290300211b200141c0006a290300210a200341d8016a41186a200141196a290000370300200341d8016a41106a200141116a290000370300200341d8016a41086a200141096a290000370300200320012900013703d8012002411a6a290100210b200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d000021092002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241096a2d0000211841042104200241046a2d00002119200241026a2f0100211a2001412c6a2802002107200141286a2802002106200141246a28020021080240024020022d00000d0020022d00014101470d00200241056a2d00002104200241066a2f01002105200241086a2d00002102410021130c010b4101211341002105410021020b200541ffff0371410874200441ff017172200241187472210202402013450d00410f210441ea9fc6002105024002400240024002400240024020020e0700010203040506000b20174108742018722016411874722105201441087420157220094118747221040c050b410e210441dc9fc60021050c040b410c210441d09fc60021050c030b4109210441c79fc60021050c020b4113210441b49fc60021050c010b4111210441a39fc60021050b2006450d072008102a0c070b2003200b370390022003200c3a008f022003200d3a008e022003200e3b018c022003200f3a008b02200320103a008a02200320113b018802200320123a008702200320093a008602200320143b018402200320153a008302200320163a008202200320173b018002200320183a00ff01200320023600fb01200320193a00fa012003201a3b01f801200341c8016a10f603024002400240024020032903c801220b200341c8016a41086a29030022308450450d004200211e4200211d0c010b200341a8016a20304200200a4200109f05200341b8016a200b4200200a4200109f0520034198016a42004200200b4200109f05024020032903b00120032903a00184420052200341c0016a290300221e20032903a8012003290398017c7c221d201e5472450d004127210441a6b5c00021050c020b20032903b801211e0b200341b8026a200341f8016a201e201d410810980220032802b8024101470d0120032802c002210420032802bc0221050b2006450d072008102a0c070b200341b8026a41106a290300211e20032903c002211d20034198026a41186a20303703002003200b3703a8022003200a3703a0022003200a37039802200341b8026a10f703200341b8036a4200370300200341e8036a4200370300200341d8036a4200370300200341c8036a42003703002003428080e983b1de163703b00320034280a094a58d1d3703e00320034280a094a58d1d3703d00320034280a094a58d1d3703c003200342808880808080103703f0032003200341b8026a3602f8032003200341b8026a3602fc03200341b0066a41186a2204200341f8016a41186a290300370300200341b0066a41106a2202200341f8016a41106a290300370300200341b0066a41086a2205200341f8016a41086a290300370300200320032903f8013703b00610a003210a1098012113200341b8046a420037030020034180046a412c6a41d0b5c00036020020034180046a41286a4101360200200341a0046a42003703002003419c046a41f8b9c000360200200341d8046a2005290300370300200341e0046a2002290300370300200341e8046a200429030037030020034200370388042003428080808080013703b004410021122003410036029804200320032903b0063703d0042003200341fc036a3602c8042003200341f8036a3602c4042003200341b8026a3602c004200320133602cc042003200a37038004200320073602880520032006360284052003200836028005200341b0066a20034180046a201b201c20034198026a200341d8016a20034180056a10b50120032802b0064101470d0420022802002207410876212f200341bc066a2802002126200341b0066a41086a280200210420032802b406211a41012112410121190c050b200141216a2d0000210620034180056a41186a200141196a29000037030020034180056a41106a200141116a29000037030020034180056a41086a200141096a290000370300200320012900013703800541ad94c400210541e900210420022d00000d0c200228000121130240200641ff01714101460d00201341ff01714101470d0d20134118762104201341087621052002411a6a290100210a200241196a2d00002106200241186a2d00002113200241166a2f01002108200241156a2d00002109200241146a2d00002114200241126a2f01002115200241116a2d00002116200241106a2d000021172002410e6a2f010021182002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241056a2800002102410221100c030b201341ff01714102470d0c2001413a6a290000210a200141396a2d00002106200141386a2d00002113200141366a2f00002108200141356a2d00002109200141346a2d00002114200141326a2f00002115200141316a2d00002116200141306a2d000021172001412e6a2f000021182001412d6a2d0000210c2001412c6a2d0000210d2001412a6a2f0000210e200141296a2d0000210f200141256a2800002102200141246a2d00002104200141226a2f00002105410021100c020b411441011037000b411541011037000b2003200a3703c806200320063a00c706200320133a00c606200320083b01c406200320093a00c306200320143a00c206200320153b01c006200320163a00bf06200320173a00be06200320183b01bc062003200c3a00bb062003200d3a00ba062003200e3b01b8062003200f3a00b706200320023600b306200320043a00b206200320053b01b006200341b8026a20034180056a2010410010c20120032d00b8022102024020032d00c0020d00200341dc026a280200450d00200341d8026a280200102a0b0240200241ff01714101470d00200341b8026a200341b0066a42808086bdbacdd21a420010a502024020032802b8024101470d0020032802c002210420032802bc022105410121060c0c0b200320032903c0023703c0082003200341c8026a2903003703c8082003200341c0086a3602800420034180046a109c010b410021050c080b200341e0066a2802002207410876212f200341b0066a412c6a2802002126200341b0066a41286a2802002104200341d4066a280200211a41012119200741ff01710d00200341b0066a41086a200341a0046a29030037030020034180056a41086a200341bc066a28020036020020032003290398043703b006200320032902b40637038005200341f8096a20034180056a1092014100210741002112410021190b200341f8006a20032903a802200341b0026a29030020032903a002220a4200109f05200329039802200a7d10e50320034188016a200341f8016a2003290378200341f8006a41086a29030010d001200341c0066a201e20034188016a41086a290300220b7d201d200329038801220a54ad7d200b201e7d200a201d54ad7d200a201d58200b201e58200b201e5122021b22051b221c3703002003201d200a7d200a201d7d20051b221b3703b8062003200a201d56200b201e5620021b2202ad220a3703b00641012105024020020d002003201b370380052003201c37038805200320034180056a3602c008200341c0086a109d014100210520032903b006210a0b200341b0066a41086a210202400240200a4200520d002005450d01200320023602800520034180056a109d010c010b200320023602800520034180056a109c010b20032802bc04210520032802b8042106200320032802b40422023602f804200320063602f404200320023602f00420032002200541b0016c6a22163602fc0402402005450d00200341c0086a410172210e200341e7076a210f200341e0076a4102722113200341b0066a41106a2110200341d8066a210d20034194076a2118200341f1066a2108200341d1066a2109200341b0066a4101722117200341a8076a2111034020022d0000210520034180056a200241016a41af01109a051a0240024020054103460d00200320053a00b006201720034180056a41af01109a052106024002400240024020050e03000102000b20032802b806211520032802bc06210620032802b4062105200f201041d800109a051a2003410c3a00c008200e200341e0076a41df00109a051a20052006200341c0086a10cc01410121064100211402402015450d002005102a0b410021150c020b20032f00b106210520032d00b306211420032802b406211520032d00b806210c20032900b906210a20032900c106210b20032900c906211d200341c0086a200d418801109a051a20132006290000370000201341086a200641086a290000370000201341106a200641106a290000370000201341186a200641186a29000037000020034180023b01e007200341c8096a200341c0086a200341e0076a10f401200320032d00d0094102463a00e9082003201d3700e1082003200b3700d9082003200a3700d1082003200c3a00d008200320153602cc08200320143a00cb08200320053b00c908200341043a00c8082003410c3a00c008410021064101211441014100200341c0086a10cc01410021150c010b2011290300210a20032903a007210b200341c8096a41186a200641186a290000370300200341c8096a41106a200641106a290000370300200341c8096a41086a200641086a290000370300200320062900003703c809200341e0076a41186a200941186a290000370300200341e0076a41106a200941106a290000370300200341e0076a41086a200941086a290000370300200320092900003703e007200341c0086a41186a200841186a290000370300200341c0086a41106a200841106a290000370300200341c0086a41086a200841086a290000370300200320082900003703c008200341e8096a41086a201841086a280200360200200320182902003703e809200341c8096a200341e0076a200341c0086a200b200a200341e8096a10f8034101211441012106410121150b024020032d00b006220541014b0d000240024020050e020001000b2014450d03024020032802b806450d0020032802b406102a0b20032d00c0064105490d0320032802e806450d0320032802e406102a0c030b2006450d02200d106a0c020b201520032802980745720d01200328029407102a0c010b2003200241b0016a3602f8040c020b200241b0016a22022016470d000b200320163602f8040b200341f0046a10690240200328028c042202450d0020034190046a280200450d002002102a0b02402019450d0020034180046a411c6a280200210220032802a40421080240024020032802a00422060d00200221050c010b2006211320022105034020052802880b21052013417f6a22130d000b0340200220022f01064102746a41880b6a28020021022006417f6a22060d000b0b200341b0066a411c6a20022f0106360200200341c8066a4100360200200341c4066a2002360200200320083602d006200341003602c006200342003703b806200320053602b406200341003602b006200341b0066a109b010b024020120d0041002105024020040d00410021040c020b201a102a0c010b0240201a0d00410021050c010b0240202f410874200741ff017172450d002026102a0b201a21050b4100210841012106410121130c080b41002113410121062008450d032009102a410121080c070b410121132008450d002009102a0b200341086a200b201b4200201e20051b221e4200109f05200a201e7d10e503200341186a20034180046a2003290308200341086a41086a29030010d001200341c0066a201c200341186a41086a290300220b7d201d2003290318220a54ad7d200b201c7d200a201d54ad7d200a201d58200b201c58200b201c5122051b22061b221b3703002003201d200a7d200a201d7d20061b221e3703b8062003200a201d56200b201c5620051b2205ad220a3703b00641012106024020050d002003201e3703c0082003201b3703c8082003200341c0086a3602e007200341e0076a109d014100210620032903b006210a0b200341b0066a41086a210502400240200a4200520d002006450d01200320053602c008200341c0086a109d010c010b200320053602c008200341c0086a109c010b41002106410021052013450d04200221050c040b41012113410021062008450d002009102a0b410121080c030b0b410121060b41012113410121080b024020012d0000417e6a220241024b0d00024002400240024020020e03000102000b2006450d03200141086a280200450d03200141046a280200102a0c030b20130d010c020b2008450d01200141286a280200450d01200141246a280200102a0c010b2001412c6a280200450d00200141286a280200102a0b2000200436020420002005360200200341800a6a24000be90604057f027e067f027e23004190016b2202240041002103200241003a008801200128020421040240024003402004450d01200241e8006a20036a200128020022052d00003a000020012004417f6a22043602042001200541016a3602002002200341016a22063a0088012006210320064120470d000b200241086a41086a200241e8006a41086a290300370300200241086a41106a200241e8006a41106a290300370300200241086a41186a200241e8006a41186a29030037030020022002290368370308024020044110490d00200541096a2900002107200529000121082001200441706a22093602042001200541116a36020041002103200241003a008801416f210a0340024020092003470d000240200341ff0171450d00200241003a0088010b200042013703000c040b200241e8006a20036a200520036a220641116a2d00003a00002001200420036b416f6a3602042001200641126a3602002002200341016a22063a008801200a417f6a210a2006210320064120470d000b200241286a41086a220b200241e8006a41086a2203290300370300200241286a41106a220c200241e8006a41106a220a290300370300200241286a41186a220d200241e8006a41186a2209290300370300200220022903683703280240200420066b220441706a4110490d002003200241086a41086a290300370300200a200241086a41106a2903003703002009200241086a41186a290300370300200241c8006a41086a220e200b290300370300200241c8006a41106a220b200c290300370300200241c8006a41186a220c200d290300370300200520066a220641116a290000210f200641196a29000021102001200441606a3602042001200641216a3602002002200229030837036820022002290328370348200041206a2010370300200041186a200f370300200041106a200737030020002008370308200041286a2002290368370300200041306a2003290300370300200041386a200a290300370300200041c0006a2009290300370300200041c8006a2002290348370300200041d0006a200e290300370300200041d8006a200b290300370300200041e0006a200c290300370300200042003703000c030b200042013703000c020b200042013703000c010b0240200341ff0171450d00200241003a0088010b200042013703000b20024190016a24000ba80302067f027e230041d0006b2204240002400240411810282205450d00200541002900e3e140370000200541106a41002900f3e140370000200541086a41002900ebe140370000200442988080808003370224200420053602202001200441206a108f012004280228210520042802202106200441306a41186a22074200370300200441306a41106a22084200370300200441306a41086a220942003703002004420037033020062005200441306a1000200441186a2007290300370300200441106a2008290300370300200441086a20092903003703002004200429033037030002402004280224450d002004280220102a0b2004410036023020044120200441306a100621050240024020042802302206417f470d004200210a4200210b0c010b20064110490d02200541086a290000210b2005290000210a2005102a0b2001200a2002200a200a200256200b200356200b2003511b22051b22027d200b2003200b20051b22037d200a200254ad7d1090022000200337030820002002370300200441d0006a24000f0b411841011037000b41c4d1c3004133200441306a419cd9c3001038000be40602067f047e230041e0006b22042400024002400240024002400240411410282205450d00200541002900cfe140370000200541106a41002800dfe140360000200541086a41002900d7e14037000020044294808080c002370234200420053602302001200441306a108f012004280238210520042802302106200441c0006a41186a22074200370300200441c0006a41106a22084200370300200441c0006a41086a220942003703002004420037034020062005200441c0006a1000200441106a41186a2007290300370300200441106a41106a2008290300370300200441106a41086a20092903003703002004200429034037031002402004280234450d002004280230102a0b20044100360240200441106a4120200441c0006a100621050240024020042802402206417f470d004200210a4200210b0c010b20064110490d02200541086a290000210b2005290000210a2005102a0b0240200a2002542205200b200354200b2003511b450d00418991c1002105411521010c060b200441086a20014104200a20027d220a200b20037d2005ad7d220b10bc01200428020822050d04411810282205450d02200541002900e3e140370000200541106a41002900f3e140370000200541086a41002900ebe140370000200442988080808003370234200420053602302001200441306a108f012004280238210520042802302106200441c0006a41186a22074200370300200441c0006a41106a22084200370300200441c0006a41086a220942003703002004420037034020062005200441c0006a1000200441106a41186a2007290300370300200441106a41106a2008290300370300200441106a41086a20092903003703002004200429034037031002402004280234450d002004280230102a0b20044100360240200441106a4120200441c0006a100621050240024020042802402206417f470d004200210c4200210d0c010b20064110490d04200541086a290000210d2005290000210c2005102a0b2001200c20027c2202200d20037c2002200c54ad7c1090022001200a200b108f02410021050c050b411441011037000b41c4d1c3004133200441c0006a419cd9c3001038000b411841011037000b41c4d1c3004133200441c0006a419cd9c3001038000b200428020c21010b2000200136020420002005360200200441e0006a24000bd9140a057f017e067f037e037f017e017f027e077f057e23002204210520044180026b4160712204240002400240200141ffffff3f712001470d0020014105742206417f4c0d0002400240024020060d00410121070c010b200610282207450d010b410021084100210602402001450d002001410574210820072106034020062000290000370000200641186a200041186a290000370000200641106a200041106a290000370000200641086a200041086a290000370000200641206a2106200041206a2100200841606a22080d000b200141057441606a41057641016a2106200121080b20042006360218200420083602142004200736021020072006410041202006676b10c40242002109200441b0016a41086a22004200370300200442003703b00141cf96c300411d200441b0016a1008200441e0016a41086a2000290300370300200420042903b0013703e001200441003602b001200441e0016a4110200441b0016a1006210602400240024020042802b0012200417f460d0020042000360294012004200636029001200441b0016a20044190016a106d20042802b001220a450d0220042902b40121092000450d012006102a0c010b4101210a0b2009422088a72200450d032000410574210b200441e0016a410c6a210c200441e0016a411472210d200441e0016a410872210e200441c0006a410c72210f200a210002400340200041086a2900002110200041106a290000211120002900002112200441206a41186a2213200041186a290000370300200441206a41106a22142011370300200441206a41086a22152010370300200420123703200240024002400240411a10282206450d00200641002900ec96432216370000200641186a41002f0084974322173b0000200641106a41002900fc96432218370000200641086a41002900f4964322193700002004429a808080a0033702b401200420063602b0012004200441b0016a3602e001200441206a200441e0016a10c80120042802b001210720042802b801211a200441e0016a41186a22014200370300200441e0016a41106a22064200370300200441e0016a41086a22084200370300200442003703e0012007201a200441e0016a100020044190016a41186a221b200129030037030020044190016a41106a221c200629030037030020044190016a41086a221a2008290300370300200420042903e00137039001024020042802b401450d0020042802b001102a0b200441003602e00120044190016a4120200441e0016a1006211d20042802e0012207417f460d02200420073602642004201d360260200441e0016a200441e0006a10b30320042802e801221e450d01200441b0016a41086a221f200c41086a290200370300200441b0016a41106a2220200c41106a2802003602002004200c2902003703b00120042903e001211002402007450d00201d102a0b200f20042903b00122113702002006202028020022073602002008201f2903002212370300200f41086a2012370200200f41106a2007360200200420113703e001200420103703400c030b411a41011037000b41c4d1c3004133200441d0016a419cd9c3001038000b2006200441b0016a41106a2802003602002008200441b0016a41086a290300370300200420042903b0013703e0014100211e0b2004201e360248200441003602e80120042903582112200420042903f801222137035820042903502122200420042903f001222337035020042903402124200420042903e001221137034020042903482110200420042903e80122253703482025a72107024002402010a7221d0d002025211020232122202121120c010b200420243703e001200420103703e801200420223703f001200420123703f8012004201d2022a74105746a3602bc012004201d3602b80120042010422088a73602b4012004201d3602b0012004200441106a3602c00120044190016a200441b0016a108401200e41086a201a280200360200200e20042903900137020020042022422088a7221d2012422088a74105746a3602bc012004201d3602b80120042012a73602b4012004201d3602b0012004200441106a3602c00120044190016a200441b0016a108401200d41086a201a280200360200200d20042903900137020020042903e801211020042903e001211120042903f801211220042903f001212202402007450d002021a7211d02402025422088a7450d002007102a0b201d450d002023422088a7102a0b200420113703402004201037034820042022370350200420123703582010a721070b2004201137036020042010370368200420223703702004201237037802400240024020070d00200441b0016a41186a2013290300370300200441b0016a41106a2014290300370300200441b0016a41086a2015290300370300200420042903203703b001411a10282207450d0220072016370000200741186a20173b0000200741106a2018370000200741086a20193700002004429a808080a0033702d401200420073602d0012004200441d0016a3602e001200441b0016a200441e0016a10c80120042802d001210720042802d801211d200142003703002006420037030020084200370300200442003703e0012007201d200441e0016a1000201b2001290300370300201c2006290300370300201a2008290300370300200420042903e00137039001024020042802d401450d0020042802d001102a0b20044190016a412010090c010b200441b0016a41186a2013290300370300200441b0016a41106a2014290300370300200441b0016a41086a2015290300370300200420042903203703b001411a10282207450d0320072016370000200741186a20173b0000200741106a2018370000200741086a20193700002004429a808080a0033702d401200420073602d0012004200441d0016a3602e001200441b0016a200441e0016a10c80120042802d001210720042802d801211d200142003703002006420037030020084200370300200442003703e0012007201d200441e0016a1000201b2001290300370300201c2006290300370300201a2008290300370300200420042903e00137039001024020042802d401450d0020042802d001102a0b200441203602e401200420044190016a3602e001200441e0006a200441e0016a10b4030b02402010a72206450d002012a7210802402010422088a7450d002006102a0b2008450d002022422088a7102a0b200041206a2100200b41606a220b0d010c060b0b411a41011037000b411a41011037000b41c4d1c3004133200441d0016a419cd9c3001038000b200641011037000b1036000b02402009a7450d00200a102a0b200441003602e801200442013703e0012003200441e0016a10b40102402003450d002003410574210003402002200441e0016a108f01200241206a2102200041606a22000d000b0b20042802e401210620042802e801210820042802e0012100200441b0016a41086a22014200370300200442003703b0014196f0c200411b200441b0016a1008200441e0016a41086a2001290300370300200420042903b0013703e001200441e0016a411020002008100702402006450d002000102a0b02402004280214450d002004280210102a0b200524000bb80901177f230041206b220424002002410020031b21052000410020011b2106200241206a200220031b2107200041206a200020011b2108200020014105746a2109200220034105746a210a4100210b4100210c4101210d4100210e4100210f41012110024002400340200b4101742111200b4105742112024002400240024002400340024020050d0020072113200d2114200c2115200b21160c040b2005210220072103200d2114200c2115200b2116201221172011211802400340024002402006450d0020022006460d06200220064120109c052213450d062013417f4c0d01200321072014210d2015210c2016210b200221050c080b200441186a2203200541186a290000370300200441106a2216200541106a290000370300200441086a2206200541086a290000370300200420052900003703000240200b200c470d00200b41016a2202200b490d0c200b41017422172002201720024b1b220c41ffffff3f71200c470d0c200c41057422024100480d0c02400240200b0d0020021028210d0c010b200d200b4105742002102c210d0b200d450d030b200d200b4105746a22022004290300370000200241186a2003290300370000200241106a2016290300370000200241086a200629030037000041002106410020072007200a4622021b2105201141026a2111201241206a2112200b41016a210b2007200741206a20021b21070c030b200441186a2213200241186a290000370300200441106a2219200241106a290000370300200441086a221a200241086a29000037030020042002290000370300024020162015470d00201641016a22022016490d0b20182002201820024b1b221541ffffff3f712015470d0b201541057422024100480d0b0240024020160d002002102821140c010b201420172002102c21140b2014450d040b201420176a22022004290300370000200241186a2013290300370000200241106a2019290300370000200241086a201a290300370000410020032003200a4622131b2102201841026a2118201741206a2117201641016a21162003200341206a20131b221321032002450d050c000b0b0b200241011037000b200241011037000b2014210d2015210c2016210b2003200341206a2003200a4622021b210741002008200820094622161b21064100200320021b21052008200841206a20161b21080c030b410021052006450d01201321072014210d2015210c2016210b0b200441186a2203200641186a290000370300200441106a2216200641106a290000370300200441086a2217200641086a290000370300200420062900003703000240200e200f470d00200e41016a2202200e490d04200e41017422062002200620024b1b220f41ffffff3f71200f470d04200f41057422024100480d0402400240200e0d002002102821100c010b2010200e4105742002102c21100b2010450d030b2010200e4105746a22022004290300370000200241186a2003290300370000200241106a2016290300370000200241086a201729030037000041002008200820094622021b2106200e41016a210e2008200841206a20021b21080c010b0b201420162000200110840202402015450d002014102a0b0240200f450d002010102a0b200441206a24000f0b200241011037000b1031000ba8ca0106017f027e057f017e217f0b7e230041e0046b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e0b000102030405060c0d0e0f000b20034184036a4101360200200342013702f402200341ccd1c5003602f002200341043602b404200341c4d1c5003602b0042003200341b0046a36028003200341f0026a41a0f8c100103e000b200141206a2903002104200141186a29030021052001410c6a2802002106200141086a2802002107200141146a2802002108200141106a28020021092001280204210a2002411a6a290100210b200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d000021132002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241096a2d0000211841042119200241046a2d0000211a200241026a2f0100211b0240024020022d00000d0020022d00014101470d00200241056a2d00002119200241066a2f0100211c200241086a2d000021024100211d0c010b4101211d410021024100211c0b2003200b370380012003200c3a007f2003200d3a007e2003200e3b017c2003200f3a007b200320103a007a200320113b0178200320123a0077200320133a0076200320143b0174200320153a0073200320163a0072200320173b0170200320183a006f2003201a3a006a2003201b3b01682003201c41ffff0371410874200241187472201941ff017172221c36006b201d450d0e410f210241ea9fc60021190240024002400240024002400240201c0e0700010203040506000b200328006f2119200328007321020c050b410e210241dc9fc60021190c040b410c210241d09fc60021190c030b4109210241c79fc60021190c020b4113210241b49fc60021190c010b4111210241a39fc60021190b4100210c4101211d2007450d43200a102a0c430b200141206a2903002104200141186a29030021052001410c6a2802002106200141086a280200211b200141146a2802002108200141106a28020021092001280204210a2002411a6a290100210b200241196a2d0000210c200241186a2d00002107200241166a2f0100210d200241156a2d0000210e200241146a2d0000210f200241126a2f01002110200241116a2d00002111200241106a2d000021122002410e6a2f010021132002410d6a2d000021142002410c6a2d000021152002410a6a2f01002116200241096a2d0000211741042119200241046a2d00002118200241026a2f0100211a0240024020022d00000d0020022d00014101470d00200241056a2d00002119200241066a2f0100211c200241086a2d000021024100211d0c010b4101211d410021024100211c0b2003200b3703e8022003200c3a00e702200320073a00e6022003200d3b01e4022003200e3a00e3022003200f3a00e202200320103b01e002200320113a00df02200320123a00de02200320133b01dc02200320143a00db02200320153a00da02200320163b01d802200320173a00d702200320183a00d2022003201a3b01d0022003201c41ffff0371410874200241187472201941ff017172221c3600d3020240201d450d00410f210241ea9fc6002119024002400240024002400240201c0e0700010203040548000b20032800d702211920032800db0221020c470b410e210241dc9fc60021190c460b410c210241d09fc60021190c450b4109210241c79fc60021190c440b4113210241b49fc60021190c430b4111210241a39fc60021190c420b20034188046a41186a200341d0026a41186a29030037030020034188046a41106a200341d0026a41106a29030037030020034188046a41086a200341d0026a41086a290300370300200320032903d00237038804410d10282202450d0e200241002900b0f841370000200241056a41002900b5f8413700002003428d808080d0013702f402200320023602f00220034188046a200341f0026a108f0120032802f802210220032802f0022119200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a220c4200370300200342003703b00420192002200341b0046a1000200341e8006a41186a201c290300370300200341e8006a41106a201d290300370300200341e8006a41086a200c290300370300200320032903b004370368024020032802f402450d0020032802f002102a0b200341003602f002200341e8006a4120200341f0026a1006211c20032802f002221d417f460d3f201c450d3f41002102200341003a009003024002400340201d2002460d01200341f0026a20026a201c20026a2d00003a00002003200241016a22193a0090032019210220194120470d000b200341b0046a41186a2202200341f0026a41186a290300370300200341b0046a41106a200341f0026a41106a290300370300200341b0046a41086a200341f0026a41086a290300370300200320032903f0023703b004201941ff0171411f4d0d01200341e0036a41086a2219200341c3046a290000370300200341e0036a410d6a220c2002290000370000200341e8016a41026a220720032d00b2043a0000200341a8026a41086a2019290300370300200341a8026a410d6a220d200c290000370000200320032f01b0043b01e801200320032900bb043703a80220032800b304211920032800b70421020240201d450d00201c102a0b200341b0046a41026a20072d00003a0000200341f0026a41086a200341a8026a41086a290300370300200341f0026a410d6a200d290000370000200320032f01e8013b01b004200320032903a8023703f0024101211c0c420b200241ff0171450d00200341003a0090030b41c4d1c3004133200341d8046a419cd9c3001038000b200141216a290000210b200141206a2d000021072001411d6a2f0000210d2001411c6a2d0000210e200141196a2f0000210f200141186a2d00002110200141156a2f00002111200141146a2d00002112200141116a2f00002113200141106a2d000021142001410c6a280200211c200141086a2d0000211e200141306a280200211f2001412c6a280200212020012d001f211520012d001b211620012d0017211720012d0013211820012d000b211a20012f0009211b200128020421212002411a6a2901002104200241196a2d00002122200241186a2d00002123200241166a2f01002124200241156a2d00002125200241146a2d00002126200241126a2f01002127200241116a2d00002128200241106a2d0000210a2002410e6a2f010021062002410d6a2d000021082002410c6a2d000021092002410a6a2f01002129200241096a2d0000212a41042119200241046a2d0000212b200241026a2f0100212c0240024020022d00000d0020022d00014101470d00200241056a2d00002119200241066a2f0100211d200241086a2d000021024100210c0c010b4101210c410021024100211d0b201d41ffff0371410874200241187472201941ff017172211d0240200c450d00410f210241ea9fc60021190240201d0e0700050607083e3f000b2029410874202a7220094118747221192006410874200872200a4118747221020c3e0b200320043703a002200320223a009f02200320233a009e02200320243b019c02200320253a009b02200320263a009a02200320273b019802200320283a0097022003200a3a009602200320063b019402200320083a009302200320093a009202200320293b0190022003202a3a008f022003201d36008b022003202b3a008a022003202c3b0188020240201e41ff01714101470d00200341f0026a201c41067610fe0120032802f00221190240024020032802f802201c413f7122024b0d00410021020c010b201920024105746a2202290018210b20022d0017210720022d0016211520022f0014210d20022d0013210e20022d0012211620022f0010210f20022d000f211020022d000e211720022f000c211120022d000b211220022d000a211820022f0008211320022d000721142002280003211c20022d0002211a20022f0000211b410121020b024020032802f402450d002019102a0b2002450d3c0b2003200b3703c002200320073a00bf02200320153a00be022003200d3b01bc022003200e3a00bb02200320163a00ba022003200f3b01b802200320103a00b702200320173a00b602200320113b01b402200320123a00b302200320183a00b202200320133b01b002200320143a00af022003201c3600ab022003201a3a00aa022003201b3b01a802200341b0046a41086a22024200370300200342003703b00441b8a2c1004114200341b0046a1008200341e8006a41086a2002290300370300200320032903b0043703680240200341e8006a41104101410041001003417f460d0041bdf8c1002119412621020c3e0b411310282202450d0e200241002900c2a3413700002002410f6a41002800d1a341360000200241086a41002900caa34137000020034293808080b0023702f402200320023602f00220034188026a200341f0026a108f0120032802f802210220032802f0022119200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a220c4200370300200342003703b00420192002200341b0046a1000200341d0026a41186a201c290300370300200341d0026a41106a201d290300370300200341d0026a41086a200c290300370300200320032903b0043703d002024020032802f402450d0020032802f002102a0b200341003602f002200341d0026a4120200341f0026a1006210220032802f0022219417f460d102002450d10200320193602b404200320023602b004200341f0026a200341b0046a10c20220032903f0024201510d0f02402019450d002002102a0b411310282202450d11200241002900c2a3413700002002410f6a41002800d1a341360000200241086a41002900caa34137000020034293808080b0023702f402200320023602f002200341a8026a200341f0026a108f0120032802f802210220032802f0022119200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a220c4200370300200342003703b00420192002200341b0046a1000200341d0026a41186a201c290300370300200341d0026a41106a201d290300370300200341d0026a41086a200c290300370300200320032903b0043703d002024020032802f402450d0020032802f002102a0b200341003602f002200341d0026a4120200341f0026a1006210220032802f0022219417f460d132002450d13200320193602b404200320023602b004200341f0026a200341b0046a10c20220032903f0024201510d1220034198036a280200211002402019450d002002102a0b200341b0046a41086a22024200370300200342003703b004418891c6004111200341b0046a1008200341e8006a41086a2002290300370300200320032903b00437036841002119200341003602f002200341e8006a4110200341f0026a10062102024020032802f002221c417f460d002002450d00201c4104490d15200228000021192002102a0b02402019201f460d0041e3f8c1002119411621020c3e0b0240201041016a201f490d0041f9f8c1002119411f21020c3e0b410e10282202450d15200241066a41002900b2a441370000200241002900aca4413700002002410e411c102c2202450d162002202141067636000e200341b0046a41186a22194200370300200341b0046a41106a221c4200370300200341b0046a41086a221d4200370300200342003703b00420024112200341b0046a1000200341d0026a41186a2019290300370300200341d0026a41106a201c290300370300200341d0026a41086a201d290300370300200320032903b0043703d0022002102a200341003602f002200341d0026a4120200341f0026a1006210220032802f0022219417f460d342002450d34200320193602b404200320023602b004200341f0026a200341b0046a107420032802f002220c450d172021413f71211c20032902f402210b02402019450d002002102a0b4100211d201c200b422088a74f0d32200c201c41216c6a22192d00004101470d32200341a6016a201941036a2d00003a000020034188016a41086a201941146a29000037030020034195016a201941196a290000370000200320192f00013b01a40120032019410c6a29000037038801201941086a2800002102201941046a28000021194101211d0c330b2001280204211b2002411a6a290100210b200241196a2d0000210c200241186a2d00002107200241166a2f0100210d200241156a2d0000210e200241146a2d0000210f200241126a2f01002110200241116a2d00002111200241106a2d000021122002410e6a2f010021132002410d6a2d000021142002410c6a2d000021152002410a6a2f01002116200241096a2d0000211741042119200241046a2d00002118200241026a2f0100211a0240024020022d00000d0020022d00014101470d00200241056a2d00002119200241066a2f0100211c200241086a2d000021024100211d0c010b4101211d410021024100211c0b2003200b3703e8022003200c3a00e702200320073a00e6022003200d3b01e4022003200e3a00e3022003200f3a00e202200320103b01e002200320113a00df02200320123a00de02200320133b01dc02200320143a00db02200320153a00da02200320163b01d802200320173a00d702200320183a00d2022003201a3b01d0022003201c41ffff0371410874200241187472201941ff017172221c3600d3020240201d450d00410f210241ea9fc60021190240201c0e0700040506073d3e000b20032800d702211920032800db0221020c3d0b20034188046a41186a200341d0026a41186a29030037030020034188046a41106a200341d0026a41106a29030037030020034188046a41086a200341d0026a41086a290300370300200320032903d00237038804200341b0046a41086a22024200370300200342003703b00441b8a2c1004114200341b0046a1008200341e8006a41086a2002290300370300200320032903b0043703680240200341e8006a41104101410041001003417f460d0041d9fac1002119411e21020c3d0b411310282202450d17200241002900c2a3413700002002410f6a41002800d1a341360000200241086a41002900caa34137000020034293808080b0023702f402200320023602f00220034188046a200341f0026a108f0120032802f802211920032802f002211c41182102200341b0046a41186a221d4200370300200341b0046a41106a220c4200370300200341b0046a41086a22074200370300200342003703b004201c2019200341b0046a1000200341d0026a41186a201d290300370300200341d0026a41106a200c290300370300200341d0026a41086a2007290300370300200320032903b0043703d002024020032802f402450d0020032802f002102a0b0240200341d0026a41204101410041001003417f470d0041f7fac10021190c3d0b410e10282202450d18200241066a41002900b2a441370000200241002900aca4413700002002410e411c102c2219450d192019201b41067636000e41182102200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a220c4200370300200342003703b00420194112200341b0046a1000200341e8006a41186a201c290300370300200341e8006a41106a201d290300370300200341e8006a41086a200c290300370300200320032903b0043703682019102a200341003602b004200341e8006a4120200341b0046a1006211c20032802b0042219417f460d1b200320193602e4032003201c3602e003200341b0046a200341e0036a107420032802b004221d450d1a201b413f71210220032902b404210b02402019450d00201c102a0b4100211c2002200b422088a74f0d2e201d200241216c6a22192d00004101470d2e20034186026a201941036a2d00003a0000200341e8016a41086a201941146a290000370300200341f5016a201941196a290000370000200320192f00013b01840220032019410c6a2900003703e801201941086a2800002102201941046a28000021194101211c0c2f0b2001280204210c2002411a6a290100210b200241196a2d00002112200241186a2d00002113200241166a2f01002114200241156a2d00002115200241146a2d00002116200241126a2f01002117200241116a2d00002118200241106a2d000021072002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d0000211141042119200241046a2d0000211a200241026a2f0100211b0240024020022d00000d0020022d00014101470d00200241056a2d00002119200241066a2f0100211c200241086a2d000021024100211d0c010b4101211d4100211c410021020b201c41ffff0371410874201941ff017172200241187472211c0240201d450d00410f210241ea9fc60021190240201c0e0700030405063c3d000b2010410874201172200f411874722119200d410874200e7220074118747221020c3c0b2003200b3703a004200320123a009f04200320133a009e04200320143b019c04200320153a009b04200320163a009a04200320173b019804200320183a009704200320073a0096042003200d3b0194042003200e3a0093042003200f3a009204200320103b019004200320113a008f042003201c36008b042003201a3a008a042003201b3b018804411610282202450d1b20024100290093a2413700002002410e6a41002900a1a241370000200241086a410029009ba24137000020034296808080e0023702f402200320023602f00220034188046a200341f0026a108f0120032802f802210220032802f0022119200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a22074200370300200342003703b00420192002200341b0046a1000200341e8006a41186a201c290300370300200341e8006a41106a201d290300370300200341e8006a41086a2007290300370300200320032903b004370368024020032802f402450d0020032802f002102a0b4101211d0240200341e8006a41204101410041001003417f460d00418ffbc1002119411e21024101210c0c400b200341b0046a41086a22024200370300200342003703b00441bf91c6004116200341b0046a1008200341e8006a41086a2002290300370300200320032903b0043703684100211c200341003602f002200341e8006a4110200341f0026a10062102024020032802f0022219417f460d002002450d0020194104490d1d2002280000211c2002102a0b200341b0046a41086a22024200370300200342003703b00441b0a3c1004112200341b0046a1008200341e8006a41086a2002290300370300200320032903b004370368200341003602f002200341e8006a4110200341f0026a100621020240024020032802f0022219417f460d002002450d00200320193602b404200320023602b004200341f0026a200341b0046a106d20032802f0022207450d1f20032902f402210b02402019450d002002102a0b200b422088a7210d0c010b4100210d4200210b410121070b0240024002400240201c200c470d00200d200c460d010b41adfbc100211941162102200d200c4d0d01200c200b422088a7220d4f0d2120034188036a420037030020034180036a4200370300200341f8026a4200370300200342003703f0022007200c4105746a220d200341f0026a460d00200d200341f0026a4120109c050d010b200341306a20034188046a4280809aa6eaafe30142001083022003280230450d0141c3fbc1002119411e21020b0240200ba7450d002007102a0b4101210c0c400b200341b0046a41086a22024200370300200342003703b004418891c6004111200341b0046a1008200341e8006a41086a2002290300370300200320032903b00437036841002119200341003602f002200341e8006a4110200341f0026a10062102024020032802f002221d417f460d002002450d00201d4104490d20200228000021192002102a0b411610282202450d2020024100290093a2413700002002410e6a41002900a1a241370000200241086a410029009ba24137000020034296808080e0023702f402200320023602f00220034188046a200341f0026a108f0120032802f802210220032802f002211d200341b0046a41186a220d4200370300200341b0046a41106a220e4200370300200341b0046a41086a220f4200370300200342003703b004201d2002200341b0046a1000200341e8006a41186a200d290300370300200341e8006a41106a200e290300370300200341e8006a41086a200f290300370300200320032903b004370368024020032802f402450d0020032802f002102a0b410810282202450d212002200c36000420022019360000200341e8006a41202002410810072002102a200ba7211d02400240200c200b422088a72202460d00200341d0026a41186a220d20034188046a41186a290300370300200341d0026a41106a220e20034188046a41106a290300370300200341d0026a41086a20034188046a41086a29030037030020032003290388043703d002200c20024f0d242007200c4105746a221920032903d002370000201941186a200d290300370000201941106a200e290300370000201941086a200341d0026a41086a2903003700000c010b200341d0026a41186a221920034188046a41186a290300370300200341d0026a41106a220d20034188046a41106a290300370300200341d0026a41086a20034188046a41086a29030037030020032003290388043703d0020240200c201d470d00200c41016a2202200c490d38200c410174221d2002201d20024b1b221d41ffffff3f71201d470d38201d41057422024100480d3802400240200c0d002002102821070c010b2007200c4105742002102c21070b2007450d25200b422088a7210c0b2007200c4105746a220220032903d002370000200241186a2019290300370000200241106a200d290300370000200241086a200341d0026a41086a290300370000200c41016a21020b200341b0046a41086a22194200370300200342003703b00441b0a3c1004112200341b0046a1008200341e8006a41086a2019290300370300200320032903b004370368200341003602f802200342013703f0022002200341f0026a10b40102402002450d00200241057421192007210203402002200341f0026a108f01200241206a2102201941606a22190d000b0b20032802f4022102200341e8006a411020032802f002221920032802f802100702402002450d002019102a0b0240201d450d002007102a0b200341b0046a41086a22024200370300200342003703b00441bf91c6004116200341b0046a1008200341e8006a41086a2002290300370300200320032903b0043703684101211d2003201c41016a3602f002200341e8006a4110200341f0026a41041007410021194101210c0c3f0b200141386a2903002104200141306a29030021052001411d6a290000210b2001411c6a2d00002112200141196a2f00002113200141186a2d00002114200141156a2f00002115200141146a2d00002116200141116a2f00002117200141106a2d000021182001410d6a2f0000211a2001410c6a2d0000211b200141086a280200210c200141286a280200211f20012d001b210a20012d0017210620012d0013210820012d000f210920012d0007212920012f0005212a20012d0004212c2002411a6a290100212d200241196a2d0000211e200241186a2d00002122200241166a2f01002123200241156a2d00002124200241146a2d00002125200241126a2f01002126200241116a2d00002127200241106a2d000021072002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d0000211141042119200241046a2d00002128200241026a2f0100212b0240024020022d00000d0020022d00014101470d00200241056a2d00002119200241066a2f0100211c200241086a2d000021024100211d0c010b4101211d4100211c410021020b201c41ffff0371410874201941ff017172200241187472211c201d450d04410f210241ea9fc60021190240201c0e0700010203043a3b000b2010410874201172200f411874722119200d410874200e7220074118747221020c3a0b410e210241dc9fc60021190c390b410c210241d09fc60021190c380b4109210241c79fc60021190c370b4113210241b49fc60021190c360b2003202d3703f8032003201e3a00f703200320223a00f603200320233b01f403200320243a00f303200320253a00f203200320263b01f003200320273a00ef03200320073a00ee032003200d3b01ec032003200e3a00eb032003200f3a00ea03200320103b01e803200320113a00e7032003201c3600e303200320283a00e2032003202b3b01e0030240200520048450450d00419ffcc100211941d00021020c360b02400240202c41ff01714101470d00200341f0026a200c41067610fe0120032802f00221190240024020032802f802200c413f7122024b0d00410021020c010b201920024105746a2202290018210b20022d0017211220022d0016210a20022f0014211320022d0013211420022d0012210620022f0010211520022d000f211620022d000e210820022f000c211720022d000b211820022d000a210920022f0008211a20022d0007211b2002280003210c20022d0002212920022f0000212a410121020b024020032802f402450d002019102a0b20020d00410121020c010b410021020b2003200b3701e802200320123a00e7022003200a3a00e602200320133b01e402200320143a00e302200320063a00e202200320153b01e002200320163a00df02200320083a00de02200320173b01dc02200320183a00db02200320093a00da022003201a3b01d8022003201b3a00d7022003200c3600d302200320293a00d2022003202a3b01d00220020d3320034188046a41186a200341d0026a41186a29010037030020034188046a41106a200341d0026a41106a29010037030020034188046a41086a200341d0026a41086a290100370300200320032901d00237038804200341b0046a41086a22024200370300200342003703b004418891c6004111200341b0046a1008200341e8006a41086a2002290300370300200320032903b00437036841002119200341003602f002200341e8006a4110200341f0026a10062102024020032802f002221c417f460d002002450d00201c4104490d1f200228000021192002102a0b02402019201f460d00418efcc1002119411121020c360b200341b0046a41086a22024200370300200342003703b00441b8a2c1004114200341b0046a1008200341e8006a41086a22192002290300370300200320032903b004370368200341f0026a200341e8006a10be02024020032802f802220d0d0041e1fbc1002119412d21020c360b20032902fc02212e20024200370300200342003703b00441ad91c6004112200341b0046a100820192002290300370300200320032903b00437036841002119200341003602f002200341e8006a4110200341f0026a10062102024020032802f002221c417f460d002002450d00201c4104490d20200228000021192002102a0b200341d8006a2019ad42004280a094a58d1d4200109f05200341d8006a41086a290300210b411410282202450d202003290358212f200241002900cfe140370000200241106a41002800dfe140360000200241086a41002900d7e14037000020034294808080c0023702d402200320023602d002200341e0036a200341d0026a108f0120032802d802210220032802d0022119200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a220c4200370300200342003703b00420192002200341b0046a1000200341f0026a41186a201c290300370300200341f0026a41106a201d290300370300200341f0026a41086a200c290300370300200320032903b0043703f002024020032802d402450d0020032802d002102a0b200341003602b004200341f0026a4120200341b0046a1006210220032802b0042219417f460d252002450d2520194110490d21200241086a290000212d200229000021302002102a0c260b4101211d20022d000120022d0000720d2320012802042102200341b0046a41086a22194200370300200342003703b00441f490c6004114200341b0046a1008200341e8006a41086a2019290300370300200320032903b004370368200320023602f002200341e8006a4110200341f0026a41041007410021194101210c0c380b024020022d000120022d000072450d0041a39fc6002119411121020c340b200141086a2802002119024020012d00044101460d00200141106a2d0000211c200141146a2d0000211d200141186a2d0000210c2001411c6a2d0000210720012f0005210220012d0007210d20012d000c210e20012f000d210f20012d000f211020012f0011211120012d0013211220012f0015211320012d0017211420012f0019211520012d001b2116200129001d210b0c210b200341f0026a201941067610fe0120032802f00221170240024020032802f8022019413f7122024b0d00410021180c010b201720024105746a2202290018210b20022d0017210720022d0016211620022f0014211520022d0013210c20022d0012211420022f0010211320022d000f211d20022d000e211220022f000c211120022d000b211c20022d000a211020022f0008210f20022d0007210e2002280003211920022d0002210d20022f00002102410121180b024020032802f402450d002017102a0b20180d20410121170c210b4101211d20022d000120022d0000720d2120012802042102200341b0046a41086a22194200370300200342003703b00441f0a2c100411c200341b0046a1008200341e8006a41086a2019290300370300200320032903b004370368200320023602f002200341e8006a4110200341f0026a41041007410021194101210c0c360b4101211d20022d000120022d0000720d2020012802042102200341b0046a41086a22194200370300200342003703b00441dca2c1004114200341b0046a1008200341e8006a41086a2019290300370300200320032903b004370368200320023602f002200341e8006a4110200341f0026a41041007410021194101210c0c350b200341d0026a41186a200341e8006a41186a290300220b370300200341d0026a41106a200341e8006a41106a290300222d370300200341d0026a41086a200341e8006a41086a290300222e37030020032003290368222f3703d002200341f0026a41186a200b370300200341f0026a41106a202d370300200341f0026a41086a202e3703002003202f3703f002200320063602b804200320073602b4042003200a3602b0042003200341f0026a200341b0046a200920082005200410d40220032802042102200328020021194100210c4101211d0c340b410d41011037000b411341011037000b41c4d1c3004133200341d8046a419cd9c3001038000b41c4f9c1002119411821020c2c0b411341011037000b41c4d1c3004133200341d8046a419cd9c3001038000b4198f9c1002119412c21020c290b41c4d1c3004133200341d8046a419cd9c3001038000b410e41011037000b411c41011037000b41c4d1c3004133200341d8046a419cd9c3001038000b411341011037000b410e41011037000b411c41011037000b41c4d1c3004133200341d8046a419cd9c3001038000b4101211c41a8fac10021190c140b411641011037000b41c4d1c3004133200341d8046a419cd9c3001038000b41c4d1c3004133200341d8046a419cd9c3001038000b41cca2c100200c200d1034000b41c4d1c3004133200341d8046a419cd9c3001038000b411641011037000b410841011037000b41a0a3c100200c20021034000b200241011037000b41c4d1c3004133200341d8046a419cd9c3001038000b41c4d1c3004133200341d8046a419cd9c3001038000b411441011037000b41c4d1c3004133200341d8046a419cd9c3001038000b410021170b2003200b37018001200320073a007f200320163a007e200320153b017c2003200c3a007b200320143a007a200320133b01782003201d3a0077200320123a0076200320113b01742003201c3a0073200320103a00722003200f3b01702003200e3a006f2003201936006b2003200d3a006a200320023b016820170d0f200341d0026a41186a200341e8006a41186a290100370300200341d0026a41106a200341e8006a41106a290100370300200341d0026a41086a200341e8006a41086a2202290100370300200320032901683703d002200341b0046a41086a22194200370300200342003703b00441a9a2c100410f200341b0046a100820022019290300370300200320032903b004370368200341003602f002200341e8006a4110200341f0026a10062102024002400240024002400240024020032802f0022219417f460d002002450d00200320193602b404200320023602b004200341f0026a200341b0046a107d20032802f002221c450d0220032902f402210b2019450d012002102a0c010b4200210b4104211c0b200ba72111024002400240200b422088a72207450d00201c200741246c221d6a210c410021190340200341f0026a41206a201c20196a220241206a280200360200200341f0026a41186a200241186a290200370300200341f0026a41106a200241106a290200370300200341f0026a41086a200241086a290200370300200320022902003703f002200341f0026a200341d0026a4120109c050d02201d201941246a2219470d000b0b4104210f4100210d024020110d00410021100c020b201c102a410021100c010b20034188046a41086a200341f0026a41086a290300220b370300200341e0036a41086a221d200b370300200341e0036a41106a220d200341f0026a41106a290300370300200341e0036a41186a220e200341f0026a41186a290300370300200341e0036a41206a2210200341f0026a41206a280200360200200320032903f002220b370388042003200b3703e00341241028220f450d02200f20032903e003370200200f41206a2010280200360200200f41186a200e290300370200200f41106a200d290300370200200f41086a201d29030037020002400240200741246c415c6a2019470d004101210d410121100c010b200241246a2113200c415c6a21144101210d4101211003402013210202400340200341f0026a41206a2219200241206a280200360200200341f0026a41186a221d200241186a290200370300200341f0026a41106a2207200241106a290200370300200341f0026a41086a220e200241086a290200370300200320022902003703f002200341f0026a200341d0026a4120109c050d01200c200241246a2202470d000c030b0b200341b0046a41206a2019280200221236020020034188046a41086a200e290300220b37030020034188046a41106a2007290300220437030020034188046a41186a201d290300220537030020034188046a41206a2012360200200320032903f002222d3703880420192012360200201d200537030020072004370300200e200b3703002003202d3703f00202402010200d470d00200d41016a2210200d490d15200d41017422122010201220104b1b2210ad42247e220b422088a70d15200ba722124100480d1502400240200d0d0020121028210f0c010b200f200d41246c2012102c210f0b200f450d060b200241246a2113200f200d41246c6a221220032903f002370200201241206a2019280200360200201241186a201d290300370200201241106a2007290300370200201241086a200e290300370200200d41016a210d20142002470d000b0b2011450d00201c102a0b200341b0046a41086a22024200370300200342003703b00441a9a2c100410f200341b0046a1008200341e8006a41086a2002290300370300200320032903b004370368200341003602f802200342013703f002200d200341f0026a10b4010240200d450d00200f200d41246c6a2107200f211903402019200341f0026a108f01201941206a280200211d0240024020032802f402221c20032802f80222026b4104490d0020032802f002211c0c010b200241046a220c2002490d14201c4101742202200c2002200c4b1b22024100480d1402400240201c0d0020021028211c0c010b20032802f002201c2002102c211c0b201c450d06200320023602f4022003201c3602f00220032802f80221020b2003200241046a3602f802201c20026a201d3600002007201941246a2219470d000b0b20032802f4022102200341e8006a411020032802f002221920032802f802100702402002450d002019102a0b200d41246c220241246d210c4100211c0240024020020d00410121074100210c0c010b200c41ffffff3f71200c470d12200c41057422024100480d12200210282207450d050b0240200d450d00200d41246c211d4100211c20072102200f21190340201941086a290000210b201941106a290000210420192900002105200241186a201941186a290000370000200241106a2004370000200241086a200b37000020022005370000201c41016a211c200241206a2102201941246a2119201d415c6a221d0d000b0b02402010450d00200f102a0b200341f0026a41186a200341d0026a41186a290300370300200341f0026a41106a200341d0026a41106a290300370300200341f0026a41086a200341d0026a41086a290300370300200320032903d0023703f002410021192007201c41004120201c676b10c4024101211d200341f0026a41012007201c10c5020240200c450d002007102a0b4101210c0c1a0b41c4d1c3004133200341d8046a419cd9c3001038000b412441041037000b201241041037000b200241011037000b200241011037000b41a39fc6002119411121024101210c0c140b420021304200212d0b024002402030202f54202d200b54202d200b511b450d0041a0fdc1002119412e21020c010b200341b0046a41086a22024200370300200342003703b004418ca3c1004113200341b0046a1008200341e8006a41086a2002290300370300200320032903b004370368200341003602f002200341e8006a4110200341f0026a1006210202400240024002400240024002400240024020032802f0022219417f460d002002450d00200320193602b404200320023602b004200341f0026a200341b0046a107820032802f0022210450d0320032902f402212d02402019450d002002102a0b202d422088a72217450d05202da7211441f1fdc1002119412321022010290300200554201041086a290300223020045420302004511b450d07200341b0046a41086a22194200370300200342003703b00441a9a2c100410f200341b0046a1008200341e8006a41086a2019290300370300200320032903b004370368200341003602f002200341e8006a4110200341f0026a1006211920032802f002221c417f460d012019450d012003201c3602b404200320193602b004200341f0026a200341b0046a107d20032802f0022207450d0420032902f4022130201c450d022019102a0c020b41effcc1002119413121020c080b42002130410421070b20072030422088a7220e41246c6a210c200721194100211c024003400240200c20196b41ec004b0d00200c2019460d062007200e41246c6a210c034020034188046a2019460d03201c201920034188046a4120109c05221d4100476a211c201d450d03200c201941246a2219470d000c070b0b201920034188046a460d01201c201920034188046a4120109c05221d4100476a211c201d450d01201941246a221d20034188046a460d01201c201d20034188046a4120109c05221d4100476a211c201d450d01201941c8006a221d20034188046a460d01201c201d20034188046a4120109c05221d4100476a211c201d450d01201941ec006a221d20034188046a460d0120194190016a2119201c201d20034188046a4120109c05221d4100476a211c201d0d000b0b201c202e422088a7490d034194fec1002119413621022030a7450d042007102a0c040b41c4d1c3004133200341d8046a419cd9c3001038000b41c4d1c3004133200341d8046a419cd9c3001038000b41cca2c100410041001034000b02402030a7450d002007102a0b200341a8026a10c002200341f0026a20034188046a10bf0220032802f0024101460d01024020032802ac02450d0020032802a802102a0b41cefdc10021190b2014450d012010102a0c010b20032802a80221260240024002400240024002400240024002400240024020032802b00222020d0042002131420021320c010b20032802f4022111200241216c211c202641016a2102200341f8026a2802002219410876211241012019411f7174211520194105764107712213417f7321164200213142002132034002402002417f6a2d00004101470d00411310282219450d06201941002900c2a3413700002019410f6a41002800d1a341360000201941086a41002900caa34137000020034293808080b0023702f402200320193602f0022002200341f0026a108f0120032802f802211d20032802f002210c200341b0046a41186a22074200370300200341b0046a41106a220e4200370300200341b0046a41086a22194200370300200342003703b004200c201d200341b0046a1000200341e8006a41186a2007290300370300200341e8006a41106a200e290300370300200341e8006a41086a22072019290300370300200320032903b004370368024020032802f402450d0020032802f002102a0b200341003602f002200341e8006a4120200341f0026a1006210c20032802f002221d417f460d002003201d3602b4042003200c3602b004200341f0026a200341b0046a10c20220032903f0024201510d05200341f0026a41206a2903002133200341f0026a41106a220f2903002134200329038803213520032903f8022136200328029803210e0240201d450d00200c102a0b200e2011490d0020194200370300200342003703b004418891c6004111200341b0046a100820072019290300370300200320032903b004370368200341003602f002200341e8006a4110200341f0026a10062119024020032802f002221d417f460d00201d41034d0d052019102a0b200341f0026a41186a200241186a290000370300200f200241106a290000370300200341f0026a41086a200241086a290000370300200320022900003703f0022003201236029003200341b0046a200341f0026a10c10242002130420021370240201320032802b80422194f0d00201920166a221d20194f0d04203320347c203520367c2230203554ad7c420020032802b004201d4102746a28020020157122191b21372030420020191b21300b024020032802b404450d0020032802b004102a0b203720327c203020317c2231203054ad7c21320b200241216a2102201c415f6a221c0d000b0b2010201741306c6a210920102102024002400240024003400240200920026b4190014b0d00024020022009460d0003404101211c200241106a220220034188046a460d04200220034188046a4120109c05450d04200241206a22022009470d000b0b4100211c203120058520322004858450450d02200341d0026a41186a220220034188046a41186a290300370300200341d0026a41106a221920034188046a41106a290300370300200341d0026a41086a221c20034188046a41086a29030037030020032003290388043703d0022010200437030820102005370300201020032903d002370310201041186a201c290300370300201041206a2019290300370300201041286a200229030037030020174115490d0a202d422188220b42307e2204422088a70d182004a72202417f4c0d1820020d03410821254108210f0c040b4101211c200241106a221920034188046a460d01201920034188046a4120109c05450d01200241c0006a221920034188046a460d01201920034188046a4120109c05450d01200241f0006a221920034188046a460d01201920034188046a4120109c05450d01200241a0016a221920034188046a460d01200241c0016a2102201920034188046a4120109c050d000b0b200341386a200341e0036a202f200b10cf012003290338210b2003200341c0006a2903003703f8022003200b3703f00241cafec10041e0fec100201c1b21194116410f201c1b21022003200341f0026a3602b004200341b0046a109d014101211c0c090b200210282225450d012025210f0b200ba7211f201041506a2128201041306a212c201041f07e6a212b410421154100212741002106410021122017210a0340200a21074100210a4101210c02402007417f6a221c450d000240024002400240024002402010201c41306c6a2202290300200741306c221120106a41a07f6a2219290300220454200241086a2903002205201941086a290300220b542005200b511b0d002007417e6a210e202b20116a21024100210a4100211903400240200e2019470d002007210c0c080b20042002290300222d5a211c200b200241086a290300220551211d200b20055a210c200241506a2102201941016a2119202d21042005210b201c200c201d1b0d000b201941016a210c2019417f7320076a211c0c010b202b20116a2102024003400240201c4101470d004100211c0c020b20042002290300222d542119200b200241086a290300220551211d200b200554210c200241506a2102201c417f6a211c202d21042005210b2019200c201d1b0d000b0b2007201c490d01200720174b0d032007201c6b220c410176221d450d00202820116a21022010201c41306c6a21190340200341f0026a41286a220e201941286a2211290300370300200341f0026a41206a2213201941206a2216290300370300200341f0026a41186a2218201941186a221a290300370300200341f0026a41106a221b201941106a220a290300370300200341f0026a41086a2208201941086a2229290300370300200320192903003703f002200241086a222a290300210b200241106a221e2903002104200241186a22222903002105200241206a2223290300212d200241286a2224290300212f201920022903003703002011202f3703002016202d370300201a2005370300200a20043703002029200b3703002024200e2903003703002023201329030037030020222018290300370300201e201b290300370300202a2008290300370300200220032903f002370300201941306a2119200241506a2102201d417f6a221d0d000b0b0240201c0d00201c210a0c050b0240200c41094d0d00201c210a0c050b200720174b0d012007201c6b211d202c201c41306c6a210e03402007201c417f6a220a490d0402402007200a6b220c4102490d002010201c41306c6a22022903002010200a41306c6a221c29030022055a200241086a22192903002204201c41086a2211290300220b5a2004200b511b0d00200341b0046a41186a2216201c41286a2213290300370300200341b0046a41106a2218201c41206a221a290300370300200341b0046a41086a221b201c41186a22082903003703002003201c2903103703b004201c200229030037030020112019290300370300201c41106a200241106a2903003703002008200241186a290300370300201a200241206a2903003703002013200241286a290300370300410121190240200c4103490d00201c29036020055a201c41e8006a2903002204200b5a2004200b511b0d0041022111200e211303402013220241506a22192002290300370300201941286a200241286a290300370300201941206a200241206a290300370300201941186a200241186a290300370300201941106a200241106a290300370300201941086a200241086a290300370300201d20112219460d01201941016a2111200241306a221329030020055a200241386a2903002204200b5a2004200b511b450d000b0b200220053703002002200b370308201c201941306c6a220241286a2016290300370300200241206a2018290300370300200241186a201b290300370300200220032903b0043703100b200a450d05200e41506a210e201d41016a211d200a211c200c410a4f0d050c000b0b201c20071044000b2007201c417f6a220a490d010b20072017103c000b200a20071044000b02400240024020122027470d00202741016a22022027490d18202741017422192002201920024b1b220241ffffffff01712002470d18200241037422194100480d180240024020270d002019102821150c010b201520274103742019102c21150b2015450d0120022127200621120b201520124103746a2202200c3602042002200a360200200641016a2212210620124102490d0102400340024002400240024020152012417f6a22064103746a2202280200450d00201241037420156a221d41746a280200221c200228020422194d0d000240201241024b0d0020122106410221120c080b20152012417d6a22164103746a28020422022019201c6a4d0d010240201241034b0d0020122106410321120c080b201d41646a2802002002201c6a4d0d01201221060c070b20124103490d012002280204211920152012417d6a22164103746a28020421020b20022019490d010b2012417e6a21160b0240024002400240024002402012201641016a22084b2229450d00201220164b222a450d01201520164103746a2218280204221e20182802006a2202201520084103746a221a280200221b490d02200220174b0d032010201b41306c6a2211201a280204221341306c22196a211d200241306c211c2002201b6b220720136b220220134f0d042025201d200241306c2219109a051a200f20196a210c0240024020134101480d00200241014e0d010b201d2102200f21190c060b2028201c6a211c201d21020340201c200241506a221d200c41506a22072007290300201d29030054200741086a290300220b201d41086a290300220454200b2004511b220e1b2219290300370300201c41086a201941086a290300370300201c41106a201941106a290300370300201c41186a201941186a290300370300201c41206a201941206a290300370300201c41286a201941286a290300370300200c2007200e1b210c02402011201d2002200e1b2202490d00200f21190c070b201c41506a211c200f2119200f200c490d000c060b0b41b8dbc000200820121034000b41b8dbc000201620121034000b201b20021044000b20022017103c000b202520112019109a051a200f20196a210c0240024020134101480d00200720134a0d010b20112102200f21190c010b2010201c6a210e200f21192011210203402002201d2019201d290300201929030054201d41086a290300220b201941086a290300220454200b2004511b22071b221c290300370300200241086a201c41086a290300370300200241106a201c41106a290300370300200241186a201c41186a290300370300200241206a201c41206a290300370300200241286a201c41286a2903003703002019201941306a20071b2119200241306a2102201d41306a201d20071b221d200e4f0d01200c20194b0d000b0b20022019200c20196b221c201c4130706b109a051a0240202a450d002018201b360200201841046a201e20136a3602002029450d02201a201a41086a20122008417f736a410374109b051a20062112200641014d0d040c010b0b41c8dbc000201620121034000b41b0b1c0001032000b201941041037000b200a0d000b02402027450d002015102a0b201f450d062025102a0c060b200241081037000b41cca2c100201d20191034000b41c4d1c3004133200341d8046a419cd9c3001038000b41c4d1c3004133200341d8046a419cd9c3001038000b411341011037000b20174102490d002017417f6a211c2010201741306c6a21074101211d03400240024002400240201c2202417f6a221c20174b0d002017201c6b22194102490d032010200241306c6a22022903002010201c41306c6a220c29030022055a200241086a220e2903002204200c41086a220f290300220b5a2004200b511b0d03200341b0046a41186a2211200c41286a2212290300370300200341b0046a41106a2213200c41206a2215290300370300200341b0046a41086a2216200c41186a22182903003703002003200c2903103703b004200c2002290300370300200f200e290300370300200c41106a200241106a2903003703002018200241186a2903003703002015200241206a2903003703002012200241286a2903003703004101210e20194103490d02200c29036020055a200c41e8006a2903002204200b5a2004200b511b0d024100210e2007211903402019220241506a22192002290300370300201941286a200241286a290300370300201941206a200241206a290300370300201941186a200241186a290300370300201941106a200241106a290300370300201941086a200241086a290300370300201d200e220f460d02200f417f6a210e200241306a221929030020055a200241386a2903002204200b5a2004200b511b0d020c000b0b201c20171044000b4102200f6b210e0b200220053703002002200b370308200c200e41306c6a220241286a2011290300370300200241206a2013290300370300200241186a2016290300370300200220032903b0043703100b200741506a2107201d417f6a211d201c0d000b0b200341b0046a41086a22024200370300200342003703b004418ca3c1004113200341b0046a1008200341e8006a41086a2002290300370300200320032903b004370368200341003602f802200342013703f0022017200341f0026a10b401201021020340200241086a290300210b200229030021040240024020032802f402221c20032802f80222196b4110490d0020032802f002211c0c010b201941106a221d2019490d0f201c4101742219201d2019201d4b1b22194100480d0f02400240201c0d0020191028211c0c010b20032802f002201c2019102c211c0b201c450d03200320193602f4022003201c3602f00220032802f80221190b201c20196a221c200b370008201c20043700002003201941106a3602f802200241106a200341f0026a108f01200241306a22022009470d000b20032802f4022102200341e8006a411020032802f002221920032802f802100702402002450d002019102a0b02402014450d002010102a0b4100211c410021190b024020032802ac02450d002026102a0b0240201c0d00202ea7450d120c020b02402014450d002010102a0b202ea7450d110c010b201941011037000b200d102a0c0f0b202ea7450d0e200d102a0c0e0b0b024002400240200ba7450d00201d102a201c0d010c020b201c450d010b200341e4016a41026a20034184026a41026a2d00003a0000200341c8016a41086a200341e8016a41086a290300370300200341c8016a410d6a200341e8016a410d6a290000370000200320032f0184023b01e401200320032903e8013703c8014100211c0c010b4101211c4118210241a8fac10021190b200341c4016a41026a221d200341e4016a41026a2d00003a0000200341a8016a41086a220c200341c8016a41086a290300370300200341a8016a41106a200341c8016a41106a290300370300200320032f01e4013b01c401200320032903c8013703a801201c0d0b20034183036a200c29030037000020034188036a200341b5016a290000370000200320032f01c4013b01f002200320023600f702200320193600f302200320032903a8013700fb022003201d2d00003a00f2020240200341f0026a20034188046a4120109c050d0020034188046a201b10d50220034188046a428080e983b1de16420010aa02200342f0f2bda9c6add9b1f4003703d00220031098013602a802200341b0046a20034188046a109a0220032802b404211920032802b004210220032802b804211c200341c4046a200341d0026a36020020032002201c4105746a3602bc04200320023602b804200320193602b404200320023602b0042003200341a8026a3602c004200341e0036a200341b0046a108701200341b0046a41086a200341e0036a41086a280200360200200320032903e0033703b00420034188046a200341b0046a109c02410021190c0c0b41c0fac1002119411921020c0b0b0b0240200ba7450d00200c102a201d450d010c020b201d0d010b4101211c4116210241dcf9c10021190c010b200341b0046a41026a200341a4016a41026a2d00003a0000200341f0026a41086a20034188016a41086a290300370300200341f0026a410d6a20034188016a410d6a290000370000200320032f01a4013b01b00420032003290388013703f0024100211c0b200341e8006a41026a221d200341b0046a41026a2d00003a000020034188046a41086a220c200341f0026a41086a29030037030020034188046a41106a200341f0026a41106a290300370300200320032f01b0043b0168200320032903f00237038804201c0d06200341f3036a200c290300370000200341f8036a20034195046a290000370000200320032f01683b01e003200320023600e703200320193600e30320032003290388043700eb032003201d2d00003a00e20302400240024002400240024002400240410e10282202450d00200241066a41002900b2a441370000200241002900aca4413700002002410e411c102c2202450d012002202041067636000e200341b0046a41186a22194200370300200341b0046a41106a221c4200370300200341b0046a41086a221d4200370300200342003703b00420024112200341b0046a1000200341e8006a41186a2019290300370300200341e8006a41106a201c290300370300200341e8006a41086a201d290300370300200320032903b0043703682002102a200341003602f002200341e8006a4120200341f0026a1006210220032802f0022219417f460d052002450d05200320193602b404200320023602b004200341f0026a200341b0046a107420032802f002220c450d022020413f71211c20032902f402210b02402019450d002002102a0b4100211d201c200b422088a74f0d03200c201c41216c6a22192d00004101470d0320034186026a201941036a2d00003a0000200341e8016a41086a201941146a290000370300200341f5016a201941196a290000370000200320192f00013b01840220032019410c6a2900003703e801201941086a2800002102201941046a28000021194101211d0c040b410e41011037000b411c41011037000b41c4d1c3004133200341d8046a419cd9c3001038000b0b0240200ba7450d00200c102a201d450d010c020b201d0d010b4101211c4114210241f2f9c10021190c010b200341e4016a41026a20034184026a41026a2d00003a0000200341c8016a41086a200341e8016a41086a290300370300200341c8016a410d6a200341e8016a410d6a290000370000200320032f0184023b01e401200320032903e8013703c8014100211c0b200341c4016a41026a221d200341e4016a41026a2d00003a0000200341a8016a41086a220c200341c8016a41086a290300370300200341a8016a41106a200341c8016a41106a290300370300200320032f01e4013b01c401200320032903c8013703a801201c0d062003419b046a200c290300370000200341a0046a200341b5016a290000370000200320032f01c4013b0188042003200236008f042003201936008b04200320032903a801370093042003201d2d00003a008a040240200341e0036a20034188026a4120109c05450d004186fac1002119411221020c070b024020034188046a200341a8026a4120109c05450d004198fac1002119411021020c070b200341f0026a41186a2217200341a8026a41186a2218290300370300200341f0026a41106a221a200341a8026a41106a221b290300370300200341f0026a41086a220a200341a8026a41086a2206290300370300200320032903a8023703f002410021022003410036029003200341b0046a200341f0026a10c1020240024020032802b804220d0d0041012112410021130c010b410021114100211341012112410021150340200d417f4c0d0220032802b404211620032802b00421140240024002400240200d1028220e450d0002400240200d41027422020d00410021070c010b201420026a210f410021072014210c0340200c2802002119412010282202450d0320022019411f763a001f200220194101713a000020022019411e764101713a001e20022019411d764101713a001d20022019411c764101713a001c20022019411b764101713a001b20022019411a764101713a001a200220194119764101713a0019200220194118764101713a0018200220194117764101713a0017200220194116764101713a0016200220194115764101713a0015200220194114764101713a0014200220194113764101713a0013200220194112764101713a0012200220194111764101713a0011200220194110764101713a001020022019410f764101713a000f20022019410e764101713a000e20022019410d764101713a000d20022019410c764101713a000c20022019410b764101713a000b20022019410a764101713a000a200220194109764101713a0009200220194108764101713a00082002201941ff017122194107763a0007200220194106764101713a0006200220194105764101713a0005200220194104764101713a0004200220194103764101713a0003200220194102764101713a0002200220194101764101713a0001200c41046a210c4100211902400240024002400340201941206a221c41034d0d010240200220196a221c411f6a2d0000450d002019411f6a211d0c040b0240201c411e6a2d0000450d002019411e6a211d0c040b0240201c411d6a2d00000d002019417c6a2119201c411c6a2d00000d030c010b0b2019411d6a211d0c020b0340201c450d032002201c6a2119201c417f6a221d211c2019417f6a2d0000450d000c020b0b201941206a211d0b201d41016a221c201d490d000240200d20076b201c4120201c4120491b22194f0d00200720196a22192007490d0b200d410174221d2019201d20194b1b22194100480d0b02400240200d0d0020191028210e0c010b200e200d2019102c210e0b200e450d062019210d0b200e20076a211d410021190240034020194120460d01201d20196a200220196a2d00004101713a0000201c201941016a2219470d000b0b200720196a21070b2002102a200c200f470d000b0b02402016450d002014102a0b0240201320116b2007490d00201120076a21020c040b201120076a22022011490d07201341017422192002201920024b1b22194100480d070240024020130d002019102821120c010b201220132019102c21120b02402012450d00201921130c040b201941011037000b200d41011037000b412041011037000b201941011037000b201220116a200e2007109a051a0240200d450d00200e102a0b20172018290300370300201a201b290300370300200a2006290300370300200320032903a8023703f0022003201541016a221536029003200341b0046a200341f0026a10c1022002211120032802b804220d0d000b0b024020032802b404450d0020032802b004102a0b200341b0046a41086a22194200370300200342003703b00441b0a3c1004112200341b0046a1008200341e8006a41086a2019290300370300200320032903b004370368200341003602f002200341e8006a4110200341f0026a1006211902400240024020032802f002221c417f460d002019450d002003201c3602b404200320193602b004200341f0026a200341b0046a106d20032802f002220e450d0220032902f402210b201c450d012019102a0c010b4101210e4200210b0b200b422088a741ffffff3f7122192002200220194b1b221c450d034100211920034188036a211d20034180036a210c200341f8026a2107200e210203400240201220196a2d0000450d00201d4200370300200c420037030020074200370300200342003703f002200341f0026a2002460d002002200341f0026a4120109c05450d00200341f0026a200210bf024101210d20032802f0024101470d0020032802f40220104d0d060b200241206a2102201941016a2219201c4f0d040c000b0b41c4d1c3004133200341d8046a419cd9c3001038000b1036000b1031000b4100210d0b0240200ba7450d00200e102a0b02402013450d002012102a0b20034188026a200341a8026a200d1b221920212020200d1b10d502200342f0f2bda9c6add9b1f4003703c80220031098013602d002200341f0026a2019109a0220032802f402211c20032802f002210220032802f802211d20034184036a200341c8026a36020020032002201d4105746a3602fc02200320023602f8022003201c3602f402200320023602f0022003200341d0026a36028003200341b0046a200341f0026a108701200341f0026a41086a200341b0046a41086a280200360200200320032903b0043703f0022019200341f0026a109c020240024002400240024002400240200d450d00200341106a20034188026a428080e983b1de1642001082022003290310210b2003200341106a41086a2903003703f8022003200b3703f0022003200341f0026a3602b004200341b0046a109d01200341013a00f402200341083a00f002200341f0026a4105722102200341f0026a211c0c010b200341206a20034188026a109d022003290320200341206a41086a29030084500d02411810282202450d03200241002900e3e140370000200241106a41002900f3e140370000200241086a41002900ebe1403700002003429880808080033702d402200320023602d002200341a8026a200341d0026a108f0120032802d802210220032802d0022119200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a220c4200370300200342003703b00420192002200341b0046a1000200341f0026a41186a201c290300370300200341f0026a41106a201d290300370300200341f0026a41086a200c290300370300200320032903b0043703f002024020032802d402450d0020032802d002102a0b200341003602b004200341f0026a4120200341b0046a1006210202400240024020032802b0042219417f470d004200210b420021050c010b20194110490d06200241086a29000021052002290000210b2002102a428080e983b1de1621044200212d200b428080e983b1de165441002005501b450d010b200b21042005212d0b411410282202450d05200241002900cfe140370000200241106a41002800dfe140360000200241086a41002900d7e14037000020034294808080c0023702d402200320023602d00220034188026a200341d0026a108f0120032802d802210220032802d0022119200341b0046a41186a221c4200370300200341b0046a41106a221d4200370300200341b0046a41086a220c4200370300200342003703b00420192002200341b0046a1000200341f0026a41186a201c290300370300200341f0026a41106a201d290300370300200341f0026a41086a200c290300370300200320032903b0043703f002024020032802d402450d0020032802d002102a0b200341003602b004200341f0026a4120200341b0046a100621020240024020032802b0042219417f470d004200212e4200212f0c010b20194110490d02200241086a290000212f2002290000212e2002102a0b20034188026a202e20047c2230202f202d7c2030202e54ad7c108f02200341a8026a200b20047d2005202d7d200b200454ad7d10900220034185036a200341b8026a2903003700002003418d036a200341c0026a290300370000200341083a00f002200341fd026a200341a8026a41086a290300370000200341003a00f402200320032903a8023700f50220034195036a2102200341f0026a211c0b2002200329038802370000200241186a20034188026a41186a290300370000200241106a20034188026a41106a290300370000200241086a20034188026a41086a290300370000410021194101211d41014100201c10cc014101210c0c0b0b41c4d1c3004133200341d8046a419cd9c3001038000b41b5dfc0002119412221020c050b411841011037000b41c4d1c3004133200341d8046a419cd9c3001038000b411441011037000b41dc9fc6002119410e21020c010b4111210241a39fc60021190b4101211d4101210c0c030b4100211c0b20034184026a41026a221d200341b0046a41026a2d00003a0000200341e8016a41086a220c200341f0026a41086a290300370300200341e8016a410d6a2207200341f0026a410d6a290000370000200320032f01b0043b018402200320032903f0023703e80102400240201c0d004101211c410b210241d8d2c50021190c010b200341e4016a41026a201d2d00003a0000200341c8016a41086a200c290300370300200341c8016a410d6a2007290000370000200320032f0184023b01e401200320032903e8013703c8014100211c0b200341c4016a41026a200341e4016a41026a2d00003a0000200341a8016a41086a200341c8016a41086a290300370300200341a8016a41106a200341c8016a41106a290300370300200320032f01e4013b01c401200320032903c8013703a801201c0d00200341a4016a41026a200341c4016a41026a2d0000221c3a000020034188016a41086a221d200341a8016a41086a29030037030020034188016a410d6a220c200341a8016a410d6a290000370000200320032f01c40122073b01a401200320032903a8013703880120034183036a201d29030037000020034188036a200c2900003700002003201c3a00f202200320073b01f002200320023600f702200320193600f30220032003290388013700fb02200320063602b8042003201b3602b4042003200a3602b004200341086a200341f0026a200341b0046a200920082005200410d402200328020c2102200328020821194101210c4100211d0c010b4101210c4100211d201b450d00200a102a0b02402001280200417f6a221c41014b0d0002400240201c0e020100010b201d450d01200141086a280200450d012001280204102a0c010b200c450d00200141086a280200450d002001280204102a0b2000200236020420002019360200200341e0046a24000bb55304087f017e097f027e23004190056b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d000022040e050001020304000b2003418c046a4101360200200342013702fc03200341ccd1c5003602f803200341043602f402200341c4d1c5003602f0022003200341f0026a36028804200341f8036a41a8a6c300103e000b200141086a2802002105200141046a2802002106024020022d000020022d000172450d0041a39fc600210741112108410021094101210a02402005450d002006102a0b410121060c230b20062001410c6a280200220210f0014200210b200341f8036a41086a22074200370300200342003703f8034196f0c200411b200341f8036a1008200341f0026a41086a2007290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621090240024020032802f8032208417f460d00200320083602ec01200320093602e801200341f8036a200341e8016a106d20032802f8032207450d0520032902fc03210b2008450d012009102a0c010b410121070b200620022007200b422088a71085020240200ba7450d002007102a0b200341f8036a41086a22074200370300200342003703f8034196f0c200411b200341f8036a1008200341f0026a41086a2007290300370300200320032903f8033703f0022003410036028004200342013703f8032002200341f8036a10b40102402002450d00200241057421072006210203402002200341f8036a108f01200241206a2102200741606a22070d000b0b20032802fc032102200341f0026a411020032802f8032207200328028004100702402002450d002007102a0b4101210a2005450d212006102a0c210b200141046a280200210941b49fc60021074113210820022d00000d1e2002280001220a41ff01714101470d1e2003200a4118763a00622003200a4108763b01602003200241216a2d00003a007f2003200241196a2900003700772003200241116a29000037006f2003200241096a2900003700672003200241056a2800003600634200210b200341f8036a41086a22024200370300200342003703f8034196f0c200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621080240024020032802f8032207417f460d00200320073602ec01200320083602e801200341f8036a200341e8016a106d20032802f8032202450d0520032902fc03210b2007450d012008102a0c010b410121020b2002200b422088a7200341e0006a10cd0121070240200ba7450d002002102a0b024020070d0041b8a6c3002107411521080c1f0b4100210a2003410036028004200342013703f8032009200341f8036a10eb0120032802fc032107200328028004210820032802f8032102200341f0026a41186a22064200370300200341f0026a41106a22054200370300200341f0026a41086a220c4200370300200342003703f00220022008200341f0026a1000200341e8016a41186a22082006290300370300200341e8016a41106a220d2005290300370300200341e8016a41086a2205200c290300370300200320032903f0023703e80102402007450d002002102a0b200341f8036a2009418801109a051a200341f0026a410d6a200341e0006a41086a290300370000200341f0026a41156a200341e0006a41106a290300370000200341f0026a411d6a200341e0006a41186a29030037000041012106200341013a00f402200320032903603700f502200341023a00f002200341c0006a200341f8036a200341f0026a10f40120032d00482102200341f8036a410d6a2005290300370000200341f8036a41156a200d290300370000200341f8036a411d6a20082903003700002003419d046a20024102463a0000200341053a00fc03200341073a00f803200320032903e8013700fd0341014100200341f8036a10cc012009102a0c170b200141086a280200210941b49fc60021074113210820022d00000d1c2002280001220a41ff01714101470d1c200141046a28020021062003200a4118763a00422003200a4108763b01402003200241216a2d00003a005f2003200241196a2900003700572003200241116a29000037004f2003200241096a2900003700472003200241056a280000360043200341f8036a41086a22024200370300200342003703f8034196f0c200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621070240024020032802f8032208417f460d002007450d00200320083602ec01200320073602e801200341f8036a200341e8016a106d20032802f8032202450d0520032902fc03210b2008450d012007102a0c010b4200210b410121020b2002200b422088a7200341c0006a10cd0121070240200ba7450d002002102a0b024020070d0041b8a6c3002107411521080c1d0b2003410036028004200342013703f8032009200341f8036a10eb0120032802fc032107200328028004210820032802f8032102200341f0026a41186a220a4200370300200341f0026a41106a22054200370300200341f0026a41086a220c4200370300200342003703f00220022008200341f0026a1000200341e0006a41186a2208200a290300370300200341e0006a41106a220a2005290300370300200341e0006a41086a2205200c290300370300200320032903f00237036002402007450d002002102a0b200341f8036a41186a2008290300370300200341f8036a41106a200a290300370300200341f8036a41086a2005290300370300200320032903603703f803411e10282202450d04200241002900f6a743370000200241166a410029008ca843370000200241106a4100290086a843370000200241086a41002900fea7433700002003429e808080e0033702ec01200320023602e8012003200341e8016a3602f002200341f8036a200341f0026a10c80120032802e801210220032802f0012107200341f0026a41186a22084200370300200341f0026a41106a220a4200370300200341f0026a41086a22054200370300200342003703f00220022007200341f0026a1000200341206a41186a2008290300370300200341206a41106a200a290300370300200341206a41086a2005290300370300200320032903f002370320024020032802ec01450d0020032802e801102a0b200341206a41204101410041001003417f470d05200341f8036a41086a22024200370300200342003703f803024020064102490d004194a8c3004121200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f0024100210a200341003602f803200341f0026a4110200341f8036a10062102024020032802f8032207417f460d002002450d0020074104490d082002280000210a2002102a0b200341f8036a41086a22024200370300200342003703f8034194a8c3004121200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621020240024020032802f8032207417f460d002002450d00024020074104490d00200228000021072002102a200741016a21070c020b41c4d1c300413320034188056a419cd9c3001038000b410121070b200341f8036a41086a22024200370300200342003703f8034194a8c3004121200341f8036a1008200341f0026a41086a22082002290300370300200320032903f8033703f002200320073602f803200341f0026a4110200341f8036a4104100720024200370300200342003703f80341cf96c300411d200341f8036a100820082002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a1006210220032802f8032207417f460d092002450d09200320073602ec01200320023602e801200341f8036a200341e8016a106d20032802f8032208450d0820032902fc03210b02402007450d002002102a0b200320083602e8012003200b3702ec01200341206a41186a200341e0006a41186a290300370300200341206a41106a200341e0006a41106a290300370300200341206a41086a200341e0006a41086a29030037030020032003290360370320200341e8016a2107200b422088a72202200ba72208470d150c140b4196f0c200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f00241002102200341003602f803200341f0026a4110200341f8036a10062108024020032802f8032207417f460d00200320073602ec01200320083602e801200341f8036a200341e8016a106d20032802f803220a450d0a20032902fc03210b02402007450d002008102a0b200b422088a72102200ba7450d00200a102a0b200341f8036a2009418801109a051a200341fc026a2002360200200341f0026a41086a4101360200200341003a00f402200341023a00f002200341e8016a200341f8036a200341f0026a10f40120032d00f001210220034185046a200341e0006a41086a2903003700002003418d046a200341f0006a29030037000020034195046a200341f8006a2903003700002003419d046a20024102463a0000200341043a00fc03200341073a00f803200320032903603700fd03200341f8036a21020c150b200141216a2d0000210a200141246a2802002109200341186a200141196a290000370300200341106a200141116a290000370300200341086a200141096a290000370300200320012900013703000240024020022d00000d002002280001220741ff01714101460d010b41b49fc60021070c110b200320074118763a0042200320074108763b01402003200241216a2d00003a005f2003200241196a2900003700572003200241116a29000037004f2003200241096a2900003700472003200241056a280000360043200341f8036a41086a22024200370300200342003703f8034196f0c200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621070240024020032802f8032208417f460d002007450d00200320083602ec01200320073602e801200341f8036a200341e8016a106d20032802f8032202450d0b20032902fc03210b2008450d012007102a0c010b4200210b410121020b2002200b422088a7200341c0006a10cd0121070240200ba7450d002002102a0b024020070d0041bea7c3002107411221080c120b411a10282202450d0a200241002900ec9643370000200241186a41002f008497433b0000200241106a41002900fc9643370000200241086a41002900f496433700002003429a808080a0033702fc03200320023602f8032003200341f8036a3602f0022003200341f0026a10c80120032802f80321022003280280042107200341f0026a41186a22084200370300200341f0026a41106a22064200370300200341f0026a41086a22054200370300200342003703f00220022007200341f0026a1000200341206a41186a2008290300370300200341206a41106a2006290300370300200341206a41086a2005290300370300200320032903f002370320024020032802fc03450d0020032802f803102a0b200341003602f803200341206a4120200341f8036a1006210220032802f8032207417f460d0f2002450d0f200320073602f402200320023602f002200341f8036a200341f0026a10b3032003280280042205450d0b20034194046a280200210e20034190046a280200210f2003418c046a280200210c41102108200341f8036a41106a2802002110200328028404211120032802fc03211220032802f803210602402007450d002002102a0b41d0a7c300210720062009470d0e200520104105746a21062005210241002108024003400240200620026b41e0004b0d0020022006470d02410021130c100b200341c0006a2002460d0e20082002200341c0006a4120109c0522074100476a21082007450d0e200241206a2207200341c0006a460d0e20082007200341c0006a4120109c0522074100476a21082007450d0e200241c0006a2207200341c0006a460d0e20082007200341c0006a4120109c0522074100476a21082007450d0e200241e0006a2207200341c0006a460d0e20024180016a210220082007200341c0006a4120109c0522074100476a210820070d000c0e0b0b200520104105746a21060340200341c0006a2002460d0d20082002200341c0006a4120109c0522074100476a21082007450d0d410021132006200241206a2202470d000c0e0b0b41c4d1c300413320034188056a419cd9c3001038000b41c4d1c300413320034188056a419cd9c3001038000b41c4d1c300413320034188056a419cd9c3001038000b411e41011037000b41cda6c3002107411f21080c160b41c4d1c300413320034188056a419cd9c3001038000b41c4d1c300413320034188056a419cd9c3001038000b41002102200341003602f001200342013703e801200341206a41186a200341e0006a41186a290300370300200341206a41106a200341e0006a41106a290300370300200341206a41086a200341e0006a41086a29030037030020032003290360370320200341e8016a21070c0a0b41c4d1c300413320034188056a419cd9c3001038000b41c4d1c300413320034188056a419cd9c3001038000b411a41011037000b41c4d1c300413320034188056a419cd9c3001038000b410121130b200c200e4105746a210d200c21024100210702400240024003400240200d20026b41e0004b0d002002200d470d02410021060c040b200341c0006a2002460d0220072002200341c0006a4120109c0522064100476a21072006450d02200241206a2206200341c0006a460d0220072006200341c0006a4120109c0522064100476a21072006450d02200241c0006a2206200341c0006a460d0220072006200341c0006a4120109c0522064100476a21072006450d02200241e0006a2206200341c0006a460d0220024180016a210220072006200341c0006a4120109c0522064100476a210720060d000c020b0b0340200341c0006a2002460d0120072002200341c0006a4120109c0522064100476a21072006450d0141002106200d200241206a2202470d000c020b0b410121060b024002400240024002400240024002400240200a41ff01710d002006450d010c080b20130d07200341f8036a41186a220d200341c0006a41186a290300370300200341f8036a41106a2213200341c0006a41106a290300370300200341f8036a41086a2214200341c0006a41086a290300370300200320032903403703f803024020102011460d0020112108201021110c020b201141016a22022011490d10201141017422082002200820024b1b220841ffffff3f712008470d10200841057422024100480d100240024020110d002002102821050c010b200520114105742002102c21050b20050d01200241011037000b200341f8036a41186a2206200341c0006a41186a290300370300200341f8036a41106a220d200341c0006a41106a290300370300200341f8036a41086a2214200341c0006a41086a290300370300200320032903403703f80302400240200e200f460d00200f2107200e210f0c010b200f41016a2202200f490d10200f41017422072002200720024b1b220741ffffff3f712007470d10200741057422024100480d1002400240200f0d0020021028210c0c010b200c200f4105742002102c210c0b200c0d00200241011037000b200c200f4105746a220220032903f803370000200241186a2006290300370000200241106a200d290300370000200241086a2014290300370000200e41016a210e024002402013450d00201020084d0d0120052010417f6a22104105746a2202290000210b2002290008211520022900102116200520084105746a220841186a200241186a29000037000020082016370010200820153700082008200b3700000b2007210f201121080c020b41c4f2c200200820101034000b200520114105746a220220032903f803370000200241186a200d290300370000200241106a2013290300370000200241086a2014290300370000201041016a21102006450d00200e20074d0d01200c200e417f6a220e4105746a2202290000210b2002290008211520022900102116200c20074105746a220741186a200241186a29000037000020072016370010200720153700082007200b3700000b2003419d046a200329030037000020034185046a200341c0006a41086a2903003700002003418d046a200341c0006a41106a29030037000020034195046a200341c0006a41186a290300370000200341a5046a200341086a290300370000200341ad046a200341106a290300370000200341b5046a200341186a290300370000200341013a00fc03200341073a00f803200320032903403700fd03200341c4046a200e360200200341c0046a2010360200200341bd046a200a3a000041014100200341f8036a10cc01200341f8036a41086a22024200370300200342003703f8034196f0c200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a1006210220032802f8032207417f460d022002450d02200320073602ec01200320023602e801200341f8036a200341e8016a106d20032802f803220a450d0120032902fc03210b02402007450d002002102a0b200b422088a72102200ba7450d03200a102a0c030b41c4f2c2002007200e1034000b41c4d1c300413320034188056a419cd9c3001038000b410021020b024002400240024002400240024002400240201020124f22070d0041002002200e6b220a200a20024b1b2012490d0020034194046a200e360200200341f8036a41186a200f360200200341f8036a41106a201036020020034184046a20083602002003200c36028c042003200536028004200320123602fc03200320093602f803411a10282202450d01200241002900ec9643370000200241186a41002f008497433b0000200241106a41002900fc9643370000200241086a41002900f496433700002003429a808080a0033702ec01200320023602e8012003200341e8016a3602f0022003200341f0026a10c80120032802e801210220032802f0012107200341f0026a41186a22094200370300200341f0026a41106a220a4200370300200341f0026a41086a22064200370300200342003703f00220022007200341f0026a1000200341206a41186a2009290300370300200341206a41106a200a290300370300200341206a41086a2006290300370300200320032903f002370320024020032802ec01450d0020032802e801102a0b200341203602f4022003200341206a3602f002200341f8036a200341f0026a10b40302402008450d002005102a0b200f0d050c060b024020070d0020034185046a200341086a2903003700002003418d046a200341106a29030037000020034195046a200341186a290300370000200341033a00fc03200341073a00f803200320032903003700fd0341014100200341f8036a10cc010c040b20034185046a200341086a2903003700002003418d046a200341106a29030037000020034195046a200341186a290300370000200341023a00fc03200341073a00f803200320032903003700fd0341014100200341f8036a10cc01411e10282207450d01200741002900f6a743370000200741166a410029008ca843370000200741106a4100290086a843370000200741086a41002900fea7433700002003429e808080e0033702fc03200320073602f8032003200341f8036a3602f0022003200341f0026a10c80120032802f80321072003280280042109200341f0026a41186a220a4200370300200341f0026a41106a22064200370300200341f0026a41086a220d4200370300200342003703f00220072009200341f0026a1000200341206a41186a200a290300370300200341206a41106a2006290300370300200341206a41086a200d290300370300200320032903f002370320024020032802fc03450d0020032802f803102a0b200341003602f803200341206a4120200341f8036a100621090240024020032802f803220a417f470d00411321070c010b024020090d00411321070c010b2003200a360284052003200936028005200341f8036a20034180056a10810120032802f80322074113460d03200341f0026a200341f8036a410472418401109a051a0240200a450d002009102a0b200341206a412010090b200341e8016a200341f0026a418401109a051a200341f8036a200341e8016a418401109a051a20074113460d03200341e0006a200341f8036a418401109a051a200320073602f803200341f8036a410472200341e0006a418401109a051a200341fc026a2002360200200341f0026a41086a2012360200200341003a00f402200341023a00f002200341e8016a200341f8036a200341f0026a10f40120032d00f001210220034185046a200341086a2903003700002003418d046a200341106a29030037000020034195046a200341186a2903003700002003419d046a20024102463a0000200341043a00fc03200341073a00f803200320032903003700fd0341014100200341f8036a10cc010c030b411a41011037000b411e41011037000b41c4d1c300413320034188056a419cd9c3001038000b411a10282202450d02200241002900ec9643370000200241186a41002f008497433b0000200241106a41002900fc9643370000200241086a41002900f496433700002003429a808080a0033702fc03200320023602f8032003200341f8036a3602f0022003200341f0026a10c80120032802f80321072003280280042109200341f0026a41186a220a4200370300200341f0026a41106a22064200370300200341f0026a41086a22024200370300200342003703f00220072009200341f0026a1000200341206a41186a200a290300370300200341206a41106a2006290300370300200341206a41086a2002290300370300200320032903f002370320024020032802fc03450d0020032802f803102a0b200341206a41201009200341f8036a41086a22074200370300200342003703f80341cf96c300411d200341f8036a100820022007290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621070240024020032802f8032202417f460d00200320023602ec01200320073602e801200341f8036a200341e8016a106d20032802f8032209450d0520032902fc03210b02402002450d002007102a0b2003200b3702ec01200320093602e8010c010b200341003602f001200342013703e8010b200341e8016a2003106e20032802f001210220032802ec01210a20032802e8012109200341f8036a41086a22074200370300200342003703f80341cf96c300411d200341f8036a1008200341f0026a41086a2007290300370300200320032903f8033703f0020240024020090d00200341f0026a411010090c010b2003410036028004200342013703f8032002200341f8036a10b40102402002450d00200241057421072009210203402003200341f8036a3602602002200341e0006a10c801200241206a2102200741606a22070d000b0b20032802fc032102200341f0026a411020032802f8032207200328028004100702402002450d002007102a0b200a450d002009102a0b02402008450d002005102a0b200f450d010b200c102a0b410021074101210a41012106410121090c140b411a41011037000b41c4d1c300413320034188056a419cd9c3001038000b41e0a7c3002107411621080b02402011450d002005102a0b200f450d02200c102a0c020b41aba7c30021070b411321080b4101210a410121060c0b0b200741046a28020022082002470d00200241016a22082002490d03200241017422052008200520084b1b220841ffffff3f712008470d03200841057422054100480d030240024020020d002005102821020c010b200728020020024105742005102c21020b2002450d0420072002360200200741046a200836020020032802f00121020b200728020022052002410574220d6a22072003290320370000200741186a200341206a41186a290300370000200741106a200341206a41106a290300370000200741086a200341206a41086a2903003700002003200241016a22073602f001200341f8036a41086a220c4200370300200342003703f80341cf96c300411d200341f8036a1008200341f0026a41086a200c290300370300200320032903f8033703f0022003410036028004200342013703f8032007200341f8036a10b401024020072002490d00200d41206a21072005210203402003200341f8036a3602202002200341206a10c801200241206a2102200741606a22070d000b0b20032802fc032102200341f0026a411020032802f8032207200328028004100702402002450d002007102a0b02402008450d002005102a0b200341f8036a2009418801109a051a200341e8016a41186a200341e0006a41186a290300370300200341e8016a41106a200341e0006a41106a290300370300200341e8016a41086a200341e0006a41086a290300370300200320032903603703e801411e10282202450d04200241002900f6a743370000200241166a410029008ca843370000200241106a4100290086a843370000200241086a41002900fea7433700002003429e808080e00337020420032002360200200320033602f002200341e8016a200341f0026a10c8012003280200210220032802082107200341f0026a41186a22084200370300200341f0026a41106a22054200370300200341f0026a41086a220c4200370300200342003703f00220022007200341f0026a1000200341206a41186a2008290300370300200341206a41106a2005290300370300200341206a41086a200c290300370300200320032903f00237032002402003280204450d002003280200102a0b200341003602f802200342013703f002200341f8036a200341f0026a10eb0120032802f4022102200341206a412020032802f002220720032802f802100702402002450d002007102a0b200341f8036a106a412010282202450d0520022003290340370000200241186a200341c0006a41186a290300370000200241106a200341c0006a41106a290300370000200241086a200341c0006a41086a29030037000020034184026a4100360200200341f4016a428180808010370200200342013702fc01200320023602f001200320063602ec012003200a3602e801200341f8036a41186a200341e0006a41186a290300370300200341f8036a41106a200341e0006a41106a290300370300200341f8036a41086a200341e0006a41086a290300370300200320032903603703f803411a10282207450d06200741002900ec9643370000200741186a41002f008497433b0000200741106a41002900fc9643370000200741086a41002900f496433700002003429a808080a00337020420032007360200200320033602f002200341f8036a200341f0026a10c8012003280200210720032802082108200341f0026a41186a22054200370300200341f0026a41106a220c4200370300200341f0026a41086a220d4200370300200342003703f00220072008200341f0026a1000200341206a41186a2005290300370300200341206a41106a200c290300370300200341206a41086a200d290300370300200320032903f00237032002402003280204450d002003280200102a0b200341203602fc032003200341206a3602f803200341e8016a200341f8036a10b4032002102a20034185046a200341c0006a41086a2903003700002003418d046a200341c0006a41106a29030037000020034195046a200341c0006a41186a2903003700002003419d046a2003290360370000200341a5046a200341e0006a41086a290300370000200341ad046a200341e0006a41106a290300370000200341b5046a200341e0006a41186a290300370000200341c4046a2006360200200341c0046a200a360200200341003a00fc03200341073a00f803200320032903403700fd03200341f8036a21020b410021064101210a41014100200210cc012009102a0b41012109410021070c090b1031000b200541011037000b411e41011037000b412041011037000b411a41011037000b2009106a2009102a410021064101210a0c010b2009106a2009102a410121064100210a0b410121090c010b4100210941012106410021070b02402004410771417f6a220241024b0d0002400240024020020e03000102000b2009450d02200141086a280200450d02200141046a280200102a0c020b200a450d01200141046a2802002202106a2002102a0c010b2006450d00200141086a2802002202106a2002102a0b200020083602042000200736020020034190056a24000bf35c040b7f017e127f027e23004190056b220324000240024002400240024002400240024002400240024002400240024002400240024020012d000022040e0500010a0302000b2003418c046a4101360200200342013702fc03200341ccd1c5003602f803200341043602f402200341c4d1c5003602f0022003200341f0026a36028804200341f8036a41a8a6c300103e000b200141086a2802002105200141046a2802002106024020022d000020022d000172450d0041a39fc600210741112108410021094101210a02402005450d002006102a0b4101210b0c0f0b20062001410c6a280200220c10f001200341f8036a41086a22024200370300200342003703f80341fbefc200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a1006210202400240024020032802f8032207417f460d002002450d00200320073602ec01200320023602e801200341f8036a200341e8016a106d20032802f803220d450d0220032902fc03210e2007450d012002102a0c010b4101210d4200210e0b20064100200c1b2109200d41206a200d200e422088a722021b210f200641206a2006200c1b2110200d410020021b21112006200c4105746a2112200d20024105746a2113410021144100211541012116410021174100211841012119024003402014410174211a2014410574211b024002400240024002400340024020110d00200f211c2016211d2015211e201421080c040b20112102200f21072016211d2015211e20142108201b210a201a210b02400340024002402009450d0020022009460d06200220094120109c05221c450d06201c417f4c0d012007210f201d2116201e211520082114200221110c080b200341f8036a41186a2207201141186a290000370300200341f8036a41106a2208201141106a290000370300200341f8036a41086a2209201141086a290000370300200320112900003703f803024020142015470d00201441016a22022014490d0f2014410174220a2002200a20024b1b221541ffffff3f712015470d0f201541057422024100480d0f0240024020140d002002102821160c010b201620144105742002102c21160b2016450d030b201620144105746a220220032903f803370000200241186a2007290300370000200241106a2008290300370000200241086a2009290300370000410021094100200f200f20134622021b2111201a41026a211a201b41206a211b201441016a2114200f200f41206a20021b210f0c030b200341f8036a41186a221c200241186a290000370300200341f8036a41106a221f200241106a290000370300200341f8036a41086a2220200241086a290000370300200320022900003703f80302402008201e470d00200841016a22022008490d0e200b2002200b20024b1b221e41ffffff3f71201e470d0e201e41057422024100480d0e0240024020080d0020021028211d0c010b201d200a2002102c211d0b201d450d040b201d200a6a220220032903f803370000200241186a201c290300370000200241106a201f290300370000200241086a2020290300370000410020072007201346221c1b2102200b41026a210b200a41206a210a200841016a21082007200741206a201c1b221c21072002450d050c000b0b0b200241011037000b200241011037000b201d2116201e2115200821142007200741206a200720134622021b210f41002010201020124622081b21094100200720021b21112010201041206a20081b21100c030b410021112009450d01201c210f201d2116201e2115200821140b200341206a41186a2207200941186a290000370300200341206a41106a2208200941106a290000370300200341206a41086a220a200941086a29000037030020032009290000370320024020172018470d00201741016a22022017490d07201741017422092002200920024b1b221841ffffff3f712018470d07201841057422024100480d070240024020170d002002102821190c010b201920174105742002102c21190b2019450d030b201920174105746a22022003290320370000200241186a2007290300370000200241106a2008290300370000200241086a200a29030037000041002010201020124622021b2109201741016a21172010201041206a20021b21100c010b0b201d20082006200c10c5020240201e450d00201d102a0b02402018450d002019102a0b0240200ea7450d00200d102a0b200341f8036a41086a22024200370300200342003703f80341fbefc200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f0022003410036028004200342013703f803200c200341f8036a10b4010240200c450d00200c41057421072006210203402002200341f8036a108f01200241206a2102200741606a22070d000b0b20032802fc032102200341f0026a411020032802f8032207200328028004100702402002450d002007102a0b4101210a2005450d0f2006102a0c0f0b200241011037000b41c4d1c300413320034188056a419cd9c3001038000b200141216a2d0000210a200141246a2802002109200341186a200141196a290000370300200341106a200141116a290000370300200341086a200141096a29000037030020032001290001370300024002400240024020022d00000d002002280001220741ff01714101460d010b41b49fc60021070c010b200320074118763a0042200320074108763b01402003200241216a2d00003a005f2003200241196a2900003700572003200241116a29000037004f2003200241096a2900003700472003200241056a280000360043200341f8036a41086a22024200370300200342003703f80341fbefc200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a1006210702400240024002400240024002400240024020032802f8032208417f460d002007450d00200320083602ec01200320073602e801200341f8036a200341e8016a106d20032802f8032202450d0220032902fc03210e2008450d012007102a0c010b4200210e410121020b2002200e422088a7200341c0006a10cd0121070240200ea7450d002002102a0b024020070d0041bea7c3002107411221080c090b411a10282202450d01200241002900b59643370000200241186a41002f00cd96433b0000200241106a41002900c59643370000200241086a41002900bd96433700002003429a808080a0033702fc03200320023602f8032003200341f8036a3602f0022003200341f0026a10c80120032802f80321022003280280042107200341f0026a41186a22084200370300200341f0026a41106a220b4200370300200341f0026a41086a221e4200370300200342003703f00220022007200341f0026a1000200341206a41186a2008290300370300200341206a41106a200b290300370300200341206a41086a201e290300370300200320032903f002370320024020032802fc03450d0020032802f803102a0b200341003602f803200341206a4120200341f8036a1006210220032802f8032207417f460d062002450d06200320073602f402200320023602f002200341f8036a200341f0026a10b303200328028004221e450d0220034194046a280200211420034190046a28020021202003418c046a280200211d41102108200341f8036a41106a280200211f200328028404211320032802fc03211020032802f803210b02402007450d002002102a0b41d0a7c3002107200b2009470d05201e201f4105746a210b201e210241002108024003400240200b20026b41e0004b0d002002200b470d02410021110c070b200341c0006a2002460d0520082002200341c0006a4120109c0522074100476a21082007450d05200241206a2207200341c0006a460d0520082007200341c0006a4120109c0522074100476a21082007450d05200241c0006a2207200341c0006a460d0520082007200341c0006a4120109c0522074100476a21082007450d05200241e0006a2207200341c0006a460d0520024180016a210220082007200341c0006a4120109c0522074100476a210820070d000c050b0b201e201f4105746a210b0340200341c0006a2002460d0420082002200341c0006a4120109c0522074100476a21082007450d0441002111200b200241206a2202470d000c050b0b41c4d1c300413320034188056a419cd9c3001038000b411a41011037000b41c4d1c300413320034188056a419cd9c3001038000b410121110b201d20144105746a211c201d21024100210702400240024003400240201c20026b41e0004b0d002002201c470d024100210b0c040b200341c0006a2002460d0220072002200341c0006a4120109c05220b4100476a2107200b450d02200241206a220b200341c0006a460d022007200b200341c0006a4120109c05220b4100476a2107200b450d02200241c0006a220b200341c0006a460d022007200b200341c0006a4120109c05220b4100476a2107200b450d02200241e0006a220b200341c0006a460d0220024180016a21022007200b200341c0006a4120109c05220b4100476a2107200b0d000c020b0b0340200341c0006a2002460d0120072002200341c0006a4120109c05220b4100476a2107200b450d014100210b201c200241206a2202470d000c020b0b4101210b0b024002400240024002400240024002400240200a41ff01710d00200b450d010c080b20110d07200341f8036a41186a221c200341c0006a41186a290300370300200341f8036a41106a2211200341c0006a41106a290300370300200341f8036a41086a220f200341c0006a41086a290300370300200320032903403703f8030240201f2013460d0020132108201f21130c020b201341016a22022013490d0d201341017422082002200820024b1b220841ffffff3f712008470d0d200841057422024100480d0d0240024020130d0020021028211e0c010b201e20134105742002102c211e0b201e0d01200241011037000b200341f8036a41186a220b200341c0006a41186a290300370300200341f8036a41106a221c200341c0006a41106a290300370300200341f8036a41086a220f200341c0006a41086a290300370300200320032903403703f8030240024020142020460d0020202107201421200c010b202041016a22022020490d0d202041017422072002200720024b1b220741ffffff3f712007470d0d200741057422024100480d0d0240024020200d0020021028211d0c010b201d20204105742002102c211d0b201d0d00200241011037000b201d20204105746a220220032903f803370000200241186a200b290300370000200241106a201c290300370000200241086a200f290300370000201441016a2114024002402011450d00201f20084d0d01201e201f417f6a221f4105746a2202290000210e2002290008212120022900102122201e20084105746a220841186a200241186a29000037000020082022370010200820213700082008200e3700000b20072120201321080c020b41c4f2c2002008201f1034000b201e20134105746a220220032903f803370000200241186a201c290300370000200241106a2011290300370000200241086a200f290300370000201f41016a211f200b450d00201420074d0d01201d2014417f6a22144105746a2202290000210e2002290008212120022900102122201d20074105746a220741186a200241186a29000037000020072022370010200720213700082007200e3700000b2003419d046a200329030037000020034185046a200341c0006a41086a2903003700002003418d046a200341c0006a41106a29030037000020034195046a200341c0006a41186a290300370000200341a5046a200341086a290300370000200341ad046a200341106a290300370000200341b5046a200341186a290300370000200341013a00fc03200341063a00f803200320032903403700fd03200341c4046a2014360200200341c0046a201f360200200341bd046a200a3a000041014100200341f8036a10cc01200341f8036a41086a22024200370300200342003703f80341fbefc200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a1006210220032802f8032207417f460d022002450d02200320073602ec01200320023602e801200341f8036a200341e8016a106d20032802f803220a450d0120032902fc03210e02402007450d002002102a0b200e422088a72102200ea7450d03200a102a0c030b41c4f2c200200720141034000b41c4d1c300413320034188056a419cd9c3001038000b410021020b024002400240024002400240024002400240201f20104f22070d004100200220146b220a200a20024b1b2010490d0020034194046a2014360200200341f8036a41186a2020360200200341f8036a41106a201f36020020034184046a20083602002003201d36028c042003201e36028004200320103602fc03200320093602f803411a10282202450d01200241002900b59643370000200241186a41002f00cd96433b0000200241106a41002900c59643370000200241086a41002900bd96433700002003429a808080a0033702ec01200320023602e8012003200341e8016a3602f0022003200341f0026a10c80120032802e801210220032802f0012107200341f0026a41186a22094200370300200341f0026a41106a220a4200370300200341f0026a41086a220b4200370300200342003703f00220022007200341f0026a1000200341206a41186a2009290300370300200341206a41106a200a290300370300200341206a41086a200b290300370300200320032903f002370320024020032802ec01450d0020032802e801102a0b200341203602f4022003200341206a3602f002200341f8036a200341f0026a10b40302402008450d00201e102a0b20200d050c060b024020070d0020034185046a200341086a2903003700002003418d046a200341106a29030037000020034195046a200341186a290300370000200341033a00fc03200341063a00f803200320032903003700fd0341014100200341f8036a10cc010c040b20034185046a200341086a2903003700002003418d046a200341106a29030037000020034195046a200341186a290300370000200341023a00fc03200341063a00f803200320032903003700fd0341014100200341f8036a10cc01411e10282207450d01200741002900eca643370000200741166a4100290082a743370000200741106a41002900fca643370000200741086a41002900f4a6433700002003429e808080e0033702fc03200320073602f8032003200341f8036a3602f0022003200341f0026a10c80120032802f80321072003280280042109200341f0026a41186a220a4200370300200341f0026a41106a220b4200370300200341f0026a41086a221c4200370300200342003703f00220072009200341f0026a1000200341206a41186a200a290300370300200341206a41106a200b290300370300200341206a41086a201c290300370300200320032903f002370320024020032802fc03450d0020032802f803102a0b200341003602f803200341206a4120200341f8036a100621090240024020032802f803220a417f470d00411321070c010b024020090d00411321070c010b2003200a360284052003200936028005200341f8036a20034180056a10810120032802f80322074113460d03200341f0026a200341f8036a410472418401109a051a0240200a450d002009102a0b200341206a412010090b200341e8016a200341f0026a418401109a051a200341f8036a200341e8016a418401109a051a20074113460d03200341e0006a200341f8036a418401109a051a200320073602f803200341f8036a410472200341e0006a418401109a051a200341fc026a2002360200200341f0026a41086a2010360200200341003a00f402200341013a00f002200341e8016a200341f8036a200341f0026a10f40120032d00f001210220034185046a200341086a2903003700002003418d046a200341106a29030037000020034195046a200341186a2903003700002003419d046a20024102463a0000200341043a00fc03200341063a00f803200320032903003700fd0341014100200341f8036a10cc010c030b411a41011037000b411e41011037000b41c4d1c300413320034188056a419cd9c3001038000b411a10282202450d02200241002900b59643370000200241186a41002f00cd96433b0000200241106a41002900c59643370000200241086a41002900bd96433700002003429a808080a0033702fc03200320023602f8032003200341f8036a3602f0022003200341f0026a10c80120032802f80321072003280280042109200341f0026a41186a220a4200370300200341f0026a41106a220b4200370300200341f0026a41086a22024200370300200342003703f00220072009200341f0026a1000200341206a41186a200a290300370300200341206a41106a200b290300370300200341206a41086a2002290300370300200320032903f002370320024020032802fc03450d0020032802f803102a0b200341206a41201009200341f8036a41086a22074200370300200342003703f803419896c300411d200341f8036a100820022007290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621070240024020032802f8032202417f460d00200320023602ec01200320073602e801200341f8036a200341e8016a106d20032802f8032209450d0520032902fc03210e02402002450d002007102a0b2003200e3702ec01200320093602e8010c010b200341003602f001200342013703e8010b200341e8016a2003106e20032802f001210220032802ec01210a20032802e8012109200341f8036a41086a22074200370300200342003703f803419896c300411d200341f8036a1008200341f0026a41086a2007290300370300200320032903f8033703f0020240024020090d00200341f0026a411010090c010b2003410036028004200342013703f8032002200341f8036a10b40102402002450d00200241057421072009210203402003200341f8036a3602602002200341e0006a10c801200241206a2102200741606a22070d000b0b20032802fc032102200341f0026a411020032802f8032207200328028004100702402002450d002007102a0b200a450d002009102a0b02402008450d00201e102a0b2020450d010b201d102a0b410021074101210a4101210b410121090c140b411a41011037000b41c4d1c300413320034188056a419cd9c3001038000b41e0a7c3002107411621080b02402013450d00201e102a0b2020450d02201d102a0c020b41aba7c30021070b411321080b4101210a4101210b0c0b0b200141086a280200210941b49fc60021074113210820022d00000d052002280001220a41ff01714101470d05200141046a280200210b2003200a4118763a00422003200a4108763b01402003200241216a2d00003a005f2003200241196a2900003700572003200241116a29000037004f2003200241096a2900003700472003200241056a280000360043200341f8036a41086a22024200370300200342003703f80341fbefc200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a1006210702400240024002400240024002400240024002400240024020032802f8032208417f460d002007450d00200320083602ec01200320073602e801200341f8036a200341e8016a106d20032802f8032202450d0220032902fc03210e2008450d012007102a0c010b4200210e410121020b2002200e422088a7200341c0006a10cd0121070240200ea7450d002002102a0b024020070d0041b8a6c3002107411521080c100b2003410036028004200342013703f8032009200341f8036a10eb0120032802fc032107200328028004210820032802f8032102200341f0026a41186a220a4200370300200341f0026a41106a221e4200370300200341f0026a41086a221d4200370300200342003703f00220022008200341f0026a1000200341e0006a41186a2208200a290300370300200341e0006a41106a220a201e290300370300200341e0006a41086a221e201d290300370300200320032903f00237036002402007450d002002102a0b200341f8036a41186a2008290300370300200341f8036a41106a200a290300370300200341f8036a41086a201e290300370300200320032903603703f803411e10282202450d01200241002900eca643370000200241166a4100290082a743370000200241106a41002900fca643370000200241086a41002900f4a6433700002003429e808080e0033702ec01200320023602e8012003200341e8016a3602f002200341f8036a200341f0026a10c80120032802e801210220032802f0012107200341f0026a41186a22084200370300200341f0026a41106a220a4200370300200341f0026a41086a221e4200370300200342003703f00220022007200341f0026a1000200341206a41186a2008290300370300200341206a41106a200a290300370300200341206a41086a201e290300370300200320032903f002370320024020032802ec01450d0020032802e801102a0b200341206a41204101410041001003417f470d02200341f8036a41086a22024200370300200342003703f8030240200b4102490d00418aa7c3004121200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f0024100210a200341003602f803200341f0026a4110200341f8036a10062102024020032802f8032207417f460d002002450d0020074104490d052002280000210a2002102a0b200341f8036a41086a22024200370300200342003703f803418aa7c3004121200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621020240024020032802f8032207417f460d002002450d00024020074104490d00200228000021072002102a200741016a21070c020b41c4d1c300413320034188056a419cd9c3001038000b410121070b200341f8036a41086a22024200370300200342003703f803418aa7c3004121200341f8036a1008200341f0026a41086a22082002290300370300200320032903f8033703f002200320073602f803200341f0026a4110200341f8036a4104100720024200370300200342003703f803419896c300411d200341f8036a100820082002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a1006210220032802f8032207417f460d062002450d06200320073602ec01200320023602e801200341f8036a200341e8016a106d20032802f8032208450d0520032902fc03210e02402007450d002002102a0b200320083602e8012003200e3702ec01200341206a41186a200341e0006a41186a290300370300200341206a41106a200341e0006a41106a290300370300200341206a41086a200341e0006a41086a29030037030020032003290360370320200341e8016a2107200e422088a72202200ea72208470d090c080b41fbefc200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f00241002102200341003602f803200341f0026a4110200341f8036a10062108024020032802f8032207417f460d00200320073602ec01200320083602e801200341f8036a200341e8016a106d20032802f803220a450d0720032902fc03210e02402007450d002008102a0b200e422088a72102200ea7450d00200a102a0b200341f8036a2009418801109a051a200341fc026a2002360200200341f0026a41086a4101360200200341003a00f402200341013a00f002200341e8016a200341f8036a200341f0026a10f40120032d00f001210220034185046a200341e0006a41086a2903003700002003418d046a200341f0006a29030037000020034195046a200341f8006a2903003700002003419d046a20024102463a0000200341043a00fc03200341063a00f803200320032903603700fd03200341f8036a21020c090b41c4d1c300413320034188056a419cd9c3001038000b411e41011037000b41cda6c3002107411f21080c0c0b41c4d1c300413320034188056a419cd9c3001038000b41c4d1c300413320034188056a419cd9c3001038000b41002102200341003602f001200342013703e801200341206a41186a200341e0006a41186a290300370300200341206a41106a200341e0006a41106a290300370300200341206a41086a200341e0006a41086a29030037030020032003290360370320200341e8016a21070c010b41c4d1c300413320034188056a419cd9c3001038000b200741046a28020022082002470d00200241016a22082002490d022002410174221e2008201e20084b1b220841ffffff3f712008470d022008410574221e4100480d020240024020020d00201e102821020c010b20072802002002410574201e102c21020b2002450d0320072002360200200741046a200836020020032802f00121020b2007280200221e2002410574221c6a22072003290320370000200741186a200341206a41186a290300370000200741106a200341206a41106a290300370000200741086a200341206a41086a2903003700002003200241016a22073602f001200341f8036a41086a221d4200370300200342003703f803419896c300411d200341f8036a1008200341f0026a41086a201d290300370300200320032903f8033703f0022003410036028004200342013703f8032007200341f8036a10b401024020072002490d00201c41206a2107201e210203402003200341f8036a3602202002200341206a10c801200241206a2102200741606a22070d000b0b20032802fc032102200341f0026a411020032802f8032207200328028004100702402002450d002007102a0b02402008450d00201e102a0b200341f8036a2009418801109a051a200341e8016a41186a200341e0006a41186a290300370300200341e8016a41106a200341e0006a41106a290300370300200341e8016a41086a200341e0006a41086a290300370300200320032903603703e801411e10282202450d03200241002900eca643370000200241166a4100290082a743370000200241106a41002900fca643370000200241086a41002900f4a6433700002003429e808080e00337020420032002360200200320033602f002200341e8016a200341f0026a10c8012003280200210220032802082107200341f0026a41186a22084200370300200341f0026a41106a221e4200370300200341f0026a41086a221d4200370300200342003703f00220022007200341f0026a1000200341206a41186a2008290300370300200341206a41106a201e290300370300200341206a41086a201d290300370300200320032903f00237032002402003280204450d002003280200102a0b200341003602f802200342013703f002200341f8036a200341f0026a10eb0120032802f4022102200341206a412020032802f002220720032802f802100702402002450d002007102a0b200341f8036a106a412010282202450d0420022003290340370000200241186a200341c0006a41186a290300370000200241106a200341c0006a41106a290300370000200241086a200341c0006a41086a29030037000020034184026a4100360200200341f4016a428180808010370200200342013702fc01200320023602f0012003200b3602ec012003200a3602e801200341f8036a41186a200341e0006a41186a290300370300200341f8036a41106a200341e0006a41106a290300370300200341f8036a41086a200341e0006a41086a290300370300200320032903603703f803411a10282207450d05200741002900b59643370000200741186a41002f00cd96433b0000200741106a41002900c59643370000200741086a41002900bd96433700002003429a808080a00337020420032007360200200320033602f002200341f8036a200341f0026a10c8012003280200210720032802082108200341f0026a41186a221e4200370300200341f0026a41106a221d4200370300200341f0026a41086a221c4200370300200342003703f00220072008200341f0026a1000200341206a41186a201e290300370300200341206a41106a201d290300370300200341206a41086a201c290300370300200320032903f00237032002402003280204450d002003280200102a0b200341203602fc032003200341206a3602f803200341e8016a200341f8036a10b4032002102a20034185046a200341c0006a41086a2903003700002003418d046a200341c0006a41106a29030037000020034195046a200341c0006a41186a2903003700002003419d046a2003290360370000200341a5046a200341e0006a41086a290300370000200341ad046a200341e0006a41106a290300370000200341b5046a200341e0006a41186a290300370000200341c4046a200b360200200341c0046a200a360200200341003a00fc03200341063a00f803200320032903403700fd03200341f8036a21020b4100210b4101210a41014100200210cc012009102a0c070b1031000b201e41011037000b411e41011037000b412041011037000b411a41011037000b2009106a2009102a4100210b4101210a0c040b200141046a280200210941b49fc60021074113210820022d00000d022002280001220a41ff01714101470d022003200a4118763a00622003200a4108763b01602003200241216a2d00003a007f2003200241196a2900003700772003200241116a29000037006f2003200241096a2900003700672003200241056a2800003600634200210e200341f8036a41086a22024200370300200342003703f80341fbefc200411b200341f8036a1008200341f0026a41086a2002290300370300200320032903f8033703f002200341003602f803200341f0026a4110200341f8036a100621080240024020032802f8032207417f460d00200320073602ec01200320083602e801200341f8036a200341e8016a106d20032802f8032202450d0320032902fc03210e2007450d012008102a0c010b410121020b2002200e422088a7200341e0006a10cd0121070240200ea7450d002002102a0b024020070d0041b8a6c3002107411521080c030b4100210a2003410036028004200342013703f8032009200341f8036a10eb0120032802fc032107200328028004210820032802f8032102200341f0026a41186a220b4200370300200341f0026a41106a221e4200370300200341f0026a41086a221d4200370300200342003703f00220022008200341f0026a1000200341e8016a41186a2208200b290300370300200341e8016a41106a221c201e290300370300200341e8016a41086a221e201d290300370300200320032903f0023703e80102402007450d002002102a0b200341f8036a2009418801109a051a200341f0026a410d6a200341e0006a41086a290300370000200341f0026a41156a200341e0006a41106a290300370000200341f0026a411d6a200341e0006a41186a2903003700004101210b200341013a00f402200320032903603700f502200341013a00f002200341c0006a200341f8036a200341f0026a10f40120032d00482102200341f8036a410d6a201e290300370000200341f8036a41156a201c290300370000200341f8036a411d6a20082903003700002003419d046a20024102463a0000200341053a00fc03200341063a00f803200320032903e8013700fd0341014100200341f8036a10cc012009102a0b41012109410021070c040b41c4d1c300413320034188056a419cd9c3001038000b2009106a2009102a4101210b4100210a0b410121090c010b410021094101210b410021070b02402004410771417f6a220241024b0d0002400240024020020e03000102000b2009450d02200141086a280200450d02200141046a280200102a0c020b200a450d01200141046a2802002202106a2002102a0c010b200b450d00200141086a2802002202106a2002102a0b200020083602042000200736020020034190056a24000bfad30106017f027e017f017e157f017e230041b0086b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e12000102030405060708090a0b0c0d0e0f1013000b200341ac066a41013602002003420137029c06200341ccd1c5003602980620034104360254200341c4d1c5003602502003200341d0006a3602a80620034198066a41d4d1c500103e000b200141106a2903002104200141086a2903002105200141046a28020021062002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241046a2d00002115200241026a2f0100211602400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703980641002102201a41ff01714101460d010b410121024104211941002117410021180b20032007370348200320083a0047200320093a00462003200a3b01442003200b3a00432003200c3a00422003200d3b01402003200e3a003f2003200f3a003e200320103b013c200320113a003b200320123a003a200320133b0138200320143a0037200320153a0032200320163b01302003201841ffff0371410874201741187472201941ff017172220a36003302402002450d00410f210841ea9fc6002109024002400240024002400240200a0e0700010203040565000b20032800372109200328003b21080c640b410e210841dc9fc60021090c630b410c210841d09fc60021090c620b4109210841c79fc60021090c610b4113210841b49fc60021090c600b4111210841a39fc60021090c5f0b200341b8036a41186a200341306a41186a290300370300200341b8036a41106a200341306a41106a290300370300200341b8036a41086a200341306a41086a290300370300200320032903303703b8030240200542808084fea6dee1115441002004501b450d0041e4d1c5002109410d21080c5f0b2003200341b8036a2005200410830202402003280200450d0041f1d1c5002109411a21080c5f0b20034188086a41086a220242003703002003420037038808419090c600411920034188086a1008200341e8076a41086a200229030037030020032003290388083703e807410021082003410036029806200341e8076a411020034198066a1006210202402003280298062209417f460d002002450d0020094104490d18200228000021082002102a0b20034188086a41086a220942003703002003420037038808419090c600411920034188086a1008200341e8076a41086a220a200929030037030020032003290388083703e8072003200841016a36029806200341e8076a411020034198066a41041007412010282202450d18200220032903b803370000200341ac066a428180808010370200200241186a200341b8036a41186a2217290300370000200241106a200341b8036a41106a2218290300370000200241086a200341b8036a41086a22192903003700002003200537039806200320023602a806200320043703a006200820034198066a10c404200341a0026a200610cf03200341d0006a200341a0026a418801109a051a200341e4016a2019290300370200200341ec016a2018290300370200200341f4016a2017290300370200200320083602d801200320032903b8033702dc0120094200370300200342003703880841ac89c500411520034188086a1008200a200929030037030020032003290388083703e8072003410036029806200341e8076a411020034198066a10062109024002402003280298062202417f460d002002210a20090d010b200341003602a0062003420137039806410020034198066a10b40120032802a0062102200328029c06210a20032802980621090b200320023602d0072003200a3602cc07200320093602c807024002402002450d0020034198066a20092002410110d6022003280298064101470d0120032802cc07450d5d20032802c807102a0c5d0b4101200341c8076a10b40120032802d801210a0240024020032802cc07220920032802d00722026b4104490d0020032802c80721090c010b200241046a22172002490d4b200941017422022017200220174b1b22024100480d4b0240024020090d002002102821090c010b20032802c80720092002102c21090b2009450d1b200320023602cc07200320093602c80720032802d00721020b2003200241046a3602d007200920026a200a360000200341d0006a200341c8076a10eb01200341dc016a200341c8076a108f010c5a0b200328029c0621170240200341a4066a2802002202200341a0066a2802002209460d0020032802d007200220096b6a220a41b0016a2218417f4c0d1b0240024020180d00410121190c010b201810282219450d1d0b2003201836028c0820032019360288082003200a36029008200320034188086a36029806201720034198066a200210d701200a2002490d1d2003280290082217200a490d1e20032802d00722172009490d1f200328028808211820032802c80721192003200a20026b220a3602302003201720096b221736028002200a2017470d20201820026a201920096a200a109a051a20032802d801210a02400240200328028c08220920032802900822026b4104490d0020032802880821090c010b200241046a22172002490d4b200941017422022017200220174b1b22024100480d4b0240024020090d002002102821090c010b20032802880820092002102c21090b2009450d222003200236028c08200320093602880820032802900821020b2003200241046a36029008200920026a200a360000200341d0006a20034188086a10eb01200341dc016a20034188086a108f012003280290082109200328028c08210a200328028808210220032802cc07450d5b20032802c807102a0c5b0b2003200341c8076a36029806201720034198066a200910d70120032802d801210a0240024020032802cc07220920032802d00722026b4104490d0020032802c80721090c010b200241046a22172002490d4a200941017422022017200220174b1b22024100480d4a0240024020090d002002102821090c010b20032802c80720092002102c21090b2009450d22200320023602cc07200320093602c80720032802d00721020b2003200241046a3602d007200920026a200a360000200341d0006a200341c8076a10eb01200341dc016a200341c8076a108f010c590b200141046a28020021162002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002106200241056a2d0000211820022d0001211a200320073703980641002102201a41ff01714101460d010b410121024104211841002117410021060b2003200737039802200320083a009702200320093a0096022003200a3b019402200320193a0093022003200b3a0092022003200c3b0190022003200d3a008f022003200e3a008e022003200f3b018c02200320103a008b02200320113a008a02200320123b018802200320133a008702200320143a008202200320153b0180022003200641ffff0371410874201741187472201841ff017172220a3600830202402002450d00410f210841ea9fc6002109200a0e070f1213141555560f0b200341d0006a41186a20034180026a41186a290300370300200341d0006a41106a20034180026a41106a290300370300200341d0006a41086a20034180026a41086a290300370300200320032903800237035020034198066a201610b804024020032802a80622170d00418bd2c5002109412421084101210a0c570b200341b4066a280200210920034198066a41186a280200210820032802ac062102200341086a200341d0006a200329029c062207422086200335029806842204200341a4066a350200422086200742208884220710830220032802080d53200341306a41186a200341d0006a41186a290300370300200341306a41106a220a200341d0006a41106a290300370300200341306a41086a2218200341d0006a41086a29030037030020032003290350370330024020082002460d0020022106200821020c520b200241016a22062002490d48200241017422192006201920064b1b220641ffffff3f712006470d48200641057422194100480d480240024020020d002019102821170c010b201720024105742019102c21170b20170d51201941011037000b200141026a2d00002116200141046a280200211a20012d0001211b2002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002106200241056a2d0000211820022d0001211c200320073703980641002102201c41ff01714101460d010b410121024104211841002117410021060b20032007370348200320083a0047200320093a00462003200a3b0144200320193a00432003200b3a00422003200c3b01402003200d3a003f2003200e3a003e2003200f3b013c200320103a003b200320113a003a200320123b0138200320133a0037200320143a0032200320153b01302003200641ffff0371410874201741187472201841ff017172220a36003302402002450d00410f210841ea9fc60021090240200a0e0700121314155556000b20032800372109200328003b21084101210a0c560b20034180026a41186a200341306a41186a290300220737030020034180026a41106a200341306a41106a290300220437030020034180026a41086a200341306a41086a290300220537030020032003290330221d3703800220034198066a41186a200737030020034198066a41106a200437030020034198066a41086a20053703002003201d3703980620034198066a201a201b41ff0171410047201610c50421090c4f0b200141026a2d00002116200141046a280200211a20012d0001211b2002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002106200241056a2d0000211820022d0001211c200320073703980641002102201c41ff01714101460d010b410121024104211841002117410021060b2003200737039802200320083a009702200320093a0096022003200a3b019402200320193a0093022003200b3a0092022003200c3b0190022003200d3a008f022003200e3a008e022003200f3b018c02200320103a008b02200320113a008a02200320123b018802200320133a008702200320143a008202200320153b0180022003200641ffff0371410874201741187472201841ff017172220a3600830202402002450d00410f210841ea9fc6002109200a0e070d1011121353540d0b200341d0006a41186a20034180026a41186a290300370300200341d0006a41106a20034180026a41106a290300370300200341d0006a41086a20034180026a41086a2903003703002003200329038002370350410f10282202450d1f200241002900c9d245370000200241076a41002900d0d2453700002003428f808080f00137029c062003200236029806200341d0006a20034198066a108f0120032802a00621022003280298062108200341a0026a41186a22094200370300200341a0026a41106a220a4200370300200341a0026a41086a22174200370300200342003703a00220082002200341a0026a1000200341306a41186a2009290300370300200341306a41106a200a290300370300200341306a41086a2017290300370300200320032903a0023703300240200328029c06450d00200328029806102a0b20034198066a200341306a412010fd01200341e8046a41026a220a20032d009b063a0000200341e8076a41086a200341ac066a290200370300200341e8076a410d6a2217200341b1066a290000370000200320032f0099063b01e8042003200341a4066a2902003703e807410121020240024020032d0098064101460d00410b210841d8d2c50021090c010b20034198066a41086a2802002108200328029c062109200341c0046a41026a200a2d00003a000020034188056a41086a200341e8076a41086a29030037030020034188056a410d6a2017290000370000200320032f01e8043b01c004200320032903e80737038805410021020b200341106a41026a200341c0046a41026a2d00003a000020034188086a41086a220a20034188056a41086a29030037030020034188086a41106a20034188056a41106a290300370300200320032f01c0043b011020032003290388053703880820020d53200341d0056a41026a200341106a41026a2d000022023a0000200341b8036a41086a2217200a290300370300200341b8036a410d6a220a20034188086a410d6a290000370000200320032f011022063b01d00520032003290388083703b803200341ab066a2017290300370000200341b0066a200a290000370000200320023a009a06200320063b0198062003200836009f062003200936009b06200320032903b8033700a30620034198066a201a201b41ff0171410047201610c50421090c4e0b41a6f5c5002109410e210820022d0000417f6a221941024b0d52200141046a280200210b4101210a4101210641012118410121170240024020190e03005d01000b200241046a2d00000d534101210a410121064101211841012117200241086a28020041036c2002410c6a280200410174490d5c0b20034198066a200b10ca03024020032802980622024113470d0041f3d4c5002109410d21084101210a0c540b200341a0026a20034198066a410472419401109a051a20032002360250200341d0006a410472200341a0026a419401109a051a200341003602a0062003420137039806200341d0006a20034198066a10eb01200328029c06210820032802a00621092003280298062102200341a0026a41186a220a4200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220022009200341a0026a1000200341b8036a41186a2209200a290300370300200341b8036a41106a220a2017290300370300200341b8036a41086a22172006290300370300200320032903a0023703b80302402008450d002002102a0b20034198066a41186a200929030037030020034198066a41106a200a29030037030020034198066a41086a2017290300370300200320032903b80337039806411710282202450d1f200241002900e3d2453700002002410f6a41002900f2d245370000200241086a41002900ebd24537000020034297808080f0023702d405200320023602d0052003200341d0056a3602a00220034198066a200341a0026a10c80120032802d005210220032802d8052108200341a0026a41186a22094200370300200341a0026a41106a220a4200370300200341a0026a41086a22174200370300200342003703a00220022008200341a0026a1000200341306a41186a2009290300370300200341306a41106a200a290300370300200341306a41086a2017290300370300200320032903a002370330024020032802d405450d0020032802d005102a0b4101210a200341306a41204101410041001003417f460d4c200341d0006a106a4180d5c5002109412521080c530b200141046a280200210a41a6f5c5002109410e210820022d0000417f6a221741024b0d4a0240024020170e03004c01000b200241086a2802004101742002410c6a280200490d4b200241046a28020041ff01710d4b0b20034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e8070240200341e8076a41104101410041001003417f460d004194d3c5002109411521080c4b0b200341003602a0062003420137039806200a20034198066a10eb01200328029c06210820032802a00621092003280298062102200341a0026a41186a22174200370300200341a0026a41106a22064200370300200341a0026a41086a22184200370300200342003703a00220022009200341a0026a1000200341d0006a41186a22092017290300370300200341d0006a41106a2006290300370300200341d0006a41086a2018290300370300200320032903a00237035002402008450d002002102a0b20034198066a41186a200929030037030020034198066a41106a200341d0006a41106a29030037030020034198066a41086a200341d0006a41086a2903003703002003200329035037039806411310282202450d1f200241002900a9d3453700002002410f6a41002800b8d345360000200241086a41002900b1d34537000020034293808080b0023702d405200320023602d0052003200341d0056a3602a00220034198066a200341a0026a10c80120032802d005210220032802d8052108200341a0026a41186a22094200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220022008200341a0026a1000200341306a41186a2009290300370300200341306a41106a2017290300370300200341306a41086a2006290300370300200320032903a002370330024020032802d405450d0020032802d005102a0b200341b8036a200341306a10e103024020032802bc032202450d0020032802b803210820032802c0032109109801211702402009450d002002102a0b201720084f0d0041fad2c5002109411a21080c4b0b20034198066a200a418801109b051a200341003a00a00720034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e807200341003602a802200342013703a00220034198066a200341a0026a10eb01024020032d00a007220241024b0d00024002400240024020020e03000102000b410021080c020b410121080c010b410221080b200320083a00a8080240024020032802a40220032802a8022202460d0020032802a00221090c010b200241016a22082002490d46200241017422092008200920084b1b22084100480d460240024020020d002008102821090c010b20032802a00220022008102c21090b2009450d22200320083602a402200320093602a00220032d00a808210820032802a80221020b2003200241016a3602a802200920026a20083a00000b20032802a4022102200341e8076a411020032802a002220820032802a802100702402002450d002008102a0b20034198066a106a200a102a4100210a410121060c480b200141046a28020021080240024020022d0000417f6a220941024b0d00024020090e03000102000b200241046a2d00000d00200241086a2802004102742002410c6a28020041036c4f0d010b2008106a2008102a41a6f5c5002109410e2108410021064101210a410121180c530b20034198066a2008418801109a051a200341023a00a00720034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e807200341003602582003420137035020034198066a200341d0006a10eb01024020032d00a007220241024b0d00024002400240024020020e03000102000b410021090c020b410121090c010b410221090b200320093a00a80802400240200328025420032802582202460d002003280250210a0c010b200241016a22092002490d452002410174220a2009200a20094b1b22094100480d450240024020020d0020091028210a0c010b200328025020022009102c210a0b200a450d22200320093602542003200a36025020032d00a8082109200328025821020b2003200241016a360258200a20026a20093a00000b20032802542102200341e8076a4110200328025022092003280258100702402002450d002009102a0b20034198066a106a2008102a410021064101210a0c470b200141046a28020021080240024020022d0000417f6a220941024b0d00024020090e03000102000b200241086a2802002002410c6a280200490d00200241046a28020041ff0171450d010b2008106a2008102a41a6f5c5002109410e2108410021184101210a410121060c520b20034198066a2008418801109a051a200341013a00a00720034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e807200341003602582003420137035020034198066a200341d0006a10eb01024020032d00a007220241024b0d00024002400240024020020e03000102000b410021090c020b410121090c010b410221090b200320093a00a80802400240200328025420032802582202460d002003280250210a0c010b200241016a22092002490d442002410174220a2009200a20094b1b22094100480d440240024020020d0020091028210a0c010b200328025020022009102c210a0b200a450d22200320093602542003200a36025020032d00a8082109200328025821020b2003200241016a360258200a20026a20093a00000b20032802542102200341e8076a4110200328025022092003280258100702402002450d002009102a0b20034198066a106a2008102a410021184101210a410121060c470b200141286a2802002118200141246a2802002106200341e8056a200141196a290000370300200341e0056a200141116a290000370300200341d0056a41086a200141096a290000370300200320012900013703d0054101210a41a6f5c5002109410e210820022d0000417e6a221741014b0d4f0240024020170e020001000b200241046a2d00000d50200241086a28020041036c2002410c6a280200410174490d500b20034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e80720034198066a200341e8076a10df032003280298062102200341a0026a20034198066a410472418401109a051a200320032800a107360288082003200341a4076a28000036008b08024020024113470d0041f2d3c5002109411021080c500b200341a0076a2d00002108200341b8036a200341a0026a418401109a051a20032002360250200341d0006a410472200341b8036a418401109a051a200841ff01710d4341c8d3c5002109412a21080c440b200341a0056a200141196a29000037030020034188056a41106a200141116a29000037030020034188056a41086a200141096a2900003703002003200129000137038805200241216a2f0000200241236a2d00004110747221082002411d6a2f00002002411f6a2d00004110747221092002410d6a2f00002002410f6a2d000041107472210a200241096a2f00002002410b6a2d0000411074722117200241056a2f0000200241076a2d0000411074722106200241206a2d0000210b200241106a2d0000210c2002410c6a2d0000210d200241086a2d0000210e0240024020022d00004102460d00410121180c010b200241246a2802002119200241116a2900002107200241046a2d0000210f2003200241196a2800003602a0062003200737039806410121180240200f4101460d000c010b2007421888a7210f2007a7210241002118200329029c0621070b200320083b019c022003419e026a20084110763a0000200320093b0198022003419a026a20094110763a0000200320023b018c02410e210820034180026a410e6a20024110763a00002003200a3b0188022003418a026a200a4110763a0000200320193a009f022003200b3a009b0220032007370390022003200f3a008f022003200c3a008b022003200d3a0087022003200e3a008302200320173b018402200320174110763a008602200320063b018002200320064110763a00820202402018450d0041a6f5c50021094101210a0c4f0b200341d0056a41186a20034180026a41186a290300370300200341d0056a41106a20034180026a41106a290300370300200341d0056a41086a20034180026a41086a29030037030020032003290380023703d00520034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e80720034198066a200341e8076a10df032003280298062102200341a0026a20034198066a4104722208418401109a051a2003200341a4076a28000036008b08200320032800a10736028808024020024113460d00200341d0006a200341a0026a418401109a051a20032002360298062008200341d0006a418401109a051a200341003602a802200342013703a00220034198066a200341a0026a10eb0120032802a402210820032802a802210920032802a0022102200341a0026a41186a220a4200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220022009200341a0026a1000200341b8036a41186a200a290300370300200341b8036a41106a2017290300370300200341b8036a41086a2006290300370300200320032903a0023703b80302402008450d002002102a0b20034188056a200341b8036a4120109c05210220034198066a106a02402002450d00411021084182d4c50021094101210a0c500b411310282202450d20200241002900a9d3453700002002410f6a41002800b8d345360000200241086a41002900b1d34537000020034293808080b002370254200320023602502003200341d0006a3602a00220034188056a200341a0026a10c8012003280250210220032802582108200341a0026a41186a22094200370300200341a0026a41106a220a4200370300200341a0026a41086a22174200370300200342003703a00220022008200341a0026a1000200341306a41186a2009290300370300200341306a41106a200a290300370300200341306a41086a2017290300370300200320032903a00237033002402003280254450d002003280250102a0b20034198066a200341306a10e103200328029c0622170d374101211741002118410021190c380b411421084192d4c50021094101210a0c4e0b4101210a20022d000120022d0000720d34200141046a28020010ce03410021090c490b4101210a20022d000120022d0000720d332001410c6a2802002119200141086a2802002108200141046a2802002109411710282202450d1e2002410f6a41002900918945370000200241086a410029008a894537000020024100290082894537000020024117412e102c2202450d1f2002200936001742002107200341a0026a41186a22174200370300200341a0026a41106a22064200370300200341a0026a41086a22184200370300200342003703a0022002411b200341a0026a1000200341306a41186a2017290300370300200341306a41106a2006290300370300200341306a41086a2018290300370300200320032903a0023703302002102a2003410036029806200341306a412020034198066a10062102024002402003280298062206417f470d00410821170c010b024020020d00410821170c010b200320063602542003200236025020034198066a200341d0006a1080012003280298062217450d21200329029c0621072006450d002002102a0b2007422088a721020240024002400240201720084190016c6a2206450d00200820024f0d0020062802004113460d01201720084190016c6a22084188016a2802002019470d012006106a20064113360200200841046a200341a0026a418401109a051a2008418c016a2003418b086a28000036000020084189016a200328008808360000411710282208450d252008410f6a41002900918945370000200841086a410029008a894537000020084100290082894537000020084117412e102c2208450d2620082009360017200341a0026a41186a22094200370300200341a0026a41106a22064200370300200341a0026a41086a22184200370300200342003703a0022008411b200341a0026a1000200341306a41186a2009290300370300200341306a41106a2006290300370300200341306a41086a2018290300370300200320032903a0023703302008102a20034198066a2017200210ac02200341306a4120200328029806220820032802a00610070240200328029c06450d002008102a0b20024190016c2108201721020340024020022802004113460d002002106a0b20024190016a2102200841f07e6a22080d000b410021092007a70d030c4c0b2002450d010b20024190016c2108201721020340024020022802004113460d002002106a0b20024190016a2102200841f07e6a22080d000b0b41a5d5c5002109411221082007a7450d4d2017102a0c4d0b2017102a0c480b200341b8036a41186a200141196a290000370300200341b8036a41106a200141116a290000370300200341b8036a41086a200141096a290000370300200320012900013703b8032002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002106200241056a2d0000211820022d00012116200320073703980641002102201641ff01714101460d010b410121024100210641042118410021170b2003200737039802200320083a009702200320093a0096022003200a3b019402200320193a0093022003200b3a0092022003200c3b0190022003200d3a008f022003200e3a008e022003200f3b018c02200320103a008b02200320113a008a02200320123b018802200320133a008702200320143a008202200320153b0180022003200641ffff0371410874201841ff017172201741187472220a3600830202402002450d00410f210841ea9fc6002109200a0e07040708090a4a4b040b200341c0046a41186a20034180026a41186a290300370300200341c0046a41106a20034180026a41106a290300370300200341c0046a41086a20034180026a41086a29030037030020032003290380023703c004410f10282202450d22200241002900c9d245370000200241076a41002900d0d2453700002003428f808080f00137029c062003200236029806200341b8036a20034198066a108f0120032802a00621022003280298062108200341a0026a41186a22094200370300200341a0026a41106a220a4200370300200341a0026a41086a22174200370300200342003703a00220082002200341a0026a1000200341306a41186a2009290300370300200341306a41106a200a290300370300200341306a41086a2017290300370300200320032903a0023703300240200328029c06450d00200328029806102a0b0240200341306a41204101410041001003417f460d0041ccd4c5002109410f21084101210a0c4c0b200341d0006a41186a200341c0046a41186a290300370300200341d0006a41106a200341c0046a41106a290300370300200341d0006a41086a200341c0046a41086a290300370300200320032903c00437035020034198066a41186a200341b8036a41186a29030037030020034198066a41106a200341b8036a41106a29030037030020034198066a41086a200341b8036a41086a290300370300200320032903b80337039806410f10282202450d2341002109200241002900c9d245370000200241076a41002900d0d2453700002003428f808080f0013702d405200320023602d00520034198066a200341d0056a108f0120032802d805210220032802d0052108200341a0026a41186a220a4200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220082002200341a0026a1000200341306a41186a200a290300370300200341306a41106a2017290300370300200341306a41086a2006290300370300200320032903a002370330024020032802d405450d0020032802d005102a0b2003412036029c062003200341306a36029806200341d0006a20034198066a10ff014101210a0c4b0b2002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002106200241056a2d0000211820022d00012116200320073703980641002102201641ff01714101460d010b410121024100210641042118410021170b2003200737039802200320083a009702200320093a0096022003200a3b019402200320193a0093022003200b3a0092022003200c3b0190022003200d3a008f022003200e3a008e022003200f3b018c02200320103a008b02200320113a008a02200320123b018802200320133a008702200320143a008202200320153b0180022003200641ffff0371410874201841ff017172201741187472220a3600830202402002450d00410f210841ea9fc6002109200a0e070306070809494a030b200341c0046a41186a20034180026a41186a2903002207370300200341c0046a41106a20034180026a41106a2903002204370300200341c0046a41086a20034180026a41086a29030022053703002003200329038002221d3703c00420034198066a41186a200737030020034198066a41106a200437030020034198066a41086a20053703002003201d37039806410f10282202450d2341002109200241002900c9d245370000200241076a41002900d0d2453700002003428f808080f0013702542003200236025020034198066a200341d0006a108f012003280258210220032802502108200341a0026a41186a220a4200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220082002200341a0026a1000200341306a41186a200a290300370300200341306a41106a2017290300370300200341306a41086a2006290300370300200320032903a00237033002402003280254450d002003280250102a0b200341306a412010094101210a0c460b200341d0056a41186a200141196a290000370300200341d0056a41106a200141116a290000370300200341d0056a41086a200141096a290000370300200320012900013703d0052002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002106200241056a2d0000211820022d00012116200320073703980641002102201641ff01714101460d010b410121024100210641042118410021170b200320073703d804200320083a00d704200320093a00d6042003200a3b01d404200320193a00d3042003200b3a00d2042003200c3b01d0042003200d3a00cf042003200e3a00ce042003200f3b01cc04200320103a00cb04200320113a00ca04200320123b01c804200320133a00c704200320143a00c204200320153b01c0042003200641ffff0371410874201841ff017172201741187472220a3600c30402402002450d00410f210841ea9fc60021090240200a0e070006070809494a000b20032800c704210920032800cb0421084101210a0c4a0b200341b8036a41186a200341c0046a41186a290300370300200341b8036a41106a200341c0046a41106a290300370300200341b8036a41086a200341c0046a41086a290300370300200320032903c0043703b803410f10282202450d23200241002900c9d245370000200241076a41002900d0d2453700002003428f808080f0013702cc07200320023602c807200341d0056a200341c8076a108f0120032802d007210220032802c8072108200341a0026a41186a22094200370300200341a0026a41106a220a4200370300200341a0026a41086a22174200370300200342003703a00220082002200341a0026a1000200341306a41186a2009290300370300200341306a41106a200a290300370300200341306a41086a2017290300370300200320032903a002370330024020032802cc07450d0020032802c807102a0b20034198066a200341306a412010fd0120034180026a41086a200341a1066a29000037030020034190026a200341a9066a29000037030020034180026a41186a200341b1066a290000370300200320032900990637038002410121020240024020032d0098064101460d00410b210841d8d2c50021090c010b200341e8046a41026a20032d00820222023a0000200341e8076a41086a220a20034193026a290000370300200341e8076a410d6a221720034198026a290000370000200341c0046a41026a20023a0000200320032f01800222023b01e8042003200329008b0222073703e807200320023b01c0042003280083022109200328008702210820034188056a410d6a201729000037000020034188056a41086a200a2903003703002003200737038805410021020b200341106a41026a220a200341c0046a41026a2d00003a000020034188086a41086a221720034188056a41086a29030037030020034188086a41106a20034188056a41106a290300370300200320032f01c0043b011020032003290388053703880820020d48200341e3006a2017290300370000200341d0006a41186a20034195086a290000370000200320032f01103b01502003200836005720032009360053200320032903880837005b2003200a2d00003a00520240200341d0006a200341b8036a4120109c05450d0041dbd4c5002109410b21084101210a0c4a0b20034198066a41186a200341d0056a41186a29030037030020034198066a41106a200341d0056a41106a29030037030020034198066a41086a200341d0056a41086a290300370300200320032903d00537039806410f10282202450d2441002109200241002900c9d245370000200241076a41002900d0d2453700002003428f808080f0013702542003200236025020034198066a200341d0006a108f012003280258210220032802502108200341a0026a41186a220a4200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220082002200341a0026a100020034180026a41186a200a29030037030020034180026a41106a201729030037030020034180026a41086a2006290300370300200320032903a0023703800202402003280254450d002003280250102a0b20034180026a412010094101210a0c490b200141216a2d00002116200341106a41186a200141196a290000370300200341106a41106a200141116a290000370300200341106a41086a200141096a290000370300200320012900013703102002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d00002119200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320083a009b06200320093a009a062003200a3b0198060c010b200241086a2d00002117200241066a2f01002106200241056a2d0000211820022d0001211a200320073703980641002102201a41ff01714101460d010b410121024100210641042118410021170b2003200737039802200320083a009702200320093a0096022003200a3b019402200320193a0093022003200b3a0092022003200c3b0190022003200d3a008f022003200e3a008e022003200f3b018c02200320103a008b02200320113a008a02200320123b018802200320133a008702200320143a008202200320153b0180022003200641ffff0371410874201841ff017172201741187472220a360083022002450d01410f210841ea9fc6002109200a0e0700030405064647000b2003280087022109200328008b0221084101210a0c470b200341c0046a41186a20034180026a41186a2903002207370300200341c0046a41106a20034180026a41106a2903002204370300200341c0046a41086a20034180026a41086a29030022053703002003200329038002221d3703c004200341e8046a41186a2007370300200341e8046a41106a2004370300200341e8046a41086a20053703002003201d3703e80420034188056a41186a200341106a41186a29030037030020034188056a41106a200341106a41106a29030037030020034188056a41086a200341106a41086a2903003703002003200329031037038805200320163a00a805411510282202450d22200241002900d088453700002002410d6a41002900dd8845370000200241086a41002900d8884537000020034295808080d00237029c062003200236029806200341e8046a20034198066a108f0120032802a00621022003280298062108200341a0026a41186a22094200370300200341a0026a41106a220a4200370300200341a0026a41086a22174200370300200342003703a00220082002200341a0026a1000200341306a41186a2009290300370300200341306a41106a200a290300370300200341306a41086a2017290300370300200320032903a0023703300240200328029c06450d00200328029806102a0b2003410036029806200341306a412020034198066a1006210202400240200328029806220a417f460d002002450d002003200a3602bc03200320023602b80320034198066a200341b8036a10b10120032d00b90622084102460d25200341d0006a41186a2217200341d2066a290100370300200341d0006a41106a2206200341ca066a290100370300200341d0006a41086a2218200341c2066a290100370300200341a0026a41086a2219200341e3066a290000370300200341a0026a41106a220b200341eb066a290000370300200341a0026a41186a220c200341f3066a290000370300200320032901ba063703502003200341db066a2900003703a002200341da066a2d000021090240200a450d002002102a0b200341b8036a41186a2017290300370300200341b8036a41106a2006290300370300200341b8036a41086a201829030037030020034188086a41086a201929030037030020034188086a41106a200b29030037030020034188086a41186a200c290300370300200320032903503703b803200320032903a002370388080c010b200341a0026a41186a22024200370300200341a0026a41106a22084200370300200341a0026a41086a22094200370300200342003703a00241e588c500411d200341a0026a100020034198066a41186a220a200229030037030020034198066a41106a2217200829030037030020034198066a41086a22062009290300370300200320032903a00237039806200341d0056a20034198066a412010fd010240024020032d00d0050d00200242003703002008420037030020094200370300200342003703a00241e588c500411d200341a0026a1000200a20022903003703002017200829030037030020062009290300370300200320032903a0023703980620034120360254200320034198066a360250200341e8046a200341d0006a10ff01410021090c010b200341c8076a41186a200341e9056a290000370300200341c8076a41106a200341e1056a290000370300200341c8076a41086a200341d9056a290000370300200320032900d1053703c807200341e8076a200341c8076a10b0012003410036029806200341e8076a412020034198066a100621022003280298062208417f460d272002450d27200320083602542003200236025020034198066a200341d0006a10b10120032d00b906220a4102460d2620034188086a41186a220920034198066a41186a29030037030020034188086a41106a221720034198066a41106a29030037030020034188086a41086a220620034198066a41086a29030037030020032003290398063703880820032d00b8062118200341a0026a200341ba066a221941c100109a051a02402008450d002002102a0b200341d0006a41186a22022009290300370300200341d0006a41106a22082017290300370300200341d0006a41086a220920062903003703002003200329038808370350200341b8036a200341a0026a41c100109a051a200341a0026a41186a22172002290300370300200341a0026a41106a22062008290300370300200341a0026a41086a220b2009290300370300200320032903503703a0022003200a3a00980620034198066a410172200341b8036a41c100109a051a20022017290300370300200820062903003703002009200b290300370300200341f8006a2019410020032d00b9064101461b360200200320032903a002370350200320183a00702003200341e8046a360274200341003602c003200342013703b803200341d0006a200341b8036a108f01024020032d0070220241064b0d000240024002400240024002400240024020020e0700010203040506000b410021080c060b410121080c050b410221080c040b410321080c030b410421080c020b410521080c010b410621080b200320083a00a8080240024020032802bc0320032802c0032202460d0020032802b80321090c010b200241016a22082002490d3c200241017422092008200920084b1b22084100480d3c0240024020020d002008102821090c010b20032802b80320022008102c21090b2009450d2a200320083602bc03200320093602b80320032d00a808210820032802c00321020b2003200241016a3602c003200920026a20083a00000b200341f4006a200341b8036a10aa0120032802bc032102200341e8076a412020032802b803220820032802c003100702402002450d002008102a0b200341a0026a41186a22024200370300200341a0026a41106a22084200370300200341a0026a41086a22094200370300200342003703a00241e588c500411d200341a0026a100020034198066a41186a200229030037030020034198066a41106a200829030037030020034198066a41086a2009290300370300200320032903a0023703980620034120360254200320034198066a360250200341e8046a200341d0006a10ff0120034188086a41086a200341c8076a41086a29030037030020034188086a41106a200341c8076a41106a29030037030020034188086a41186a200341c8076a41186a290300370300200320032903c80737038808410121090b410021080b200341a5066a200341b8036a41086a290300370000200341ad066a200341b8036a41106a290300370000200341b5066a200341b8036a41186a290300370000200341bd066a20093a0000200341be066a200329038808370100200341c6066a20034188086a41086a290300370100200341ce066a20034188086a41106a290300370100200341d6066a20034188086a41186a290300370100200320083a009c06200320032903b80337009d06200320034188056a36029806200341003602582003420137035020034188056a200341d0006a108f01024020032d00a805220241064b0d000240024002400240024002400240024020020e0700010203040506000b410021080c060b410121080c050b410221080c040b410321080c030b410421080c020b410521080c010b410621080b200320083a00a80802400240200328025420032802582202460d00200328025021090c010b200241016a22082002490d3a200241017422092008200920084b1b22084100480d3a0240024020020d002008102821090c010b200328025020022008102c21090b2009450d29200320083602542003200936025020032d00a8082108200328025821020b2003200241016a360258200920026a20083a00000b20034198066a410472200341d0006a10a90120032802542102200341306a4120200328025022082003280258100702402002450d002008102a0b200342e4cab5fbb6ccdcb0e3003703e004200341e0046a200341c0046a417f10a80220034198066a41086a41083a0000200341a1066a20032903c004370000200341a9066a200341c0046a41086a290300370000200341b1066a200341c0046a41106a290300370000200341b9066a200341c0046a41186a290300370000200341c1066a2003290310370000200341c9066a200341106a41086a290300370000200341d1066a200341106a41106a290300370000200341d9066a200341106a41186a290300370000200341053a009806410021094101210a4101410020034198066a10cc010c420b2002411a6a2901002107200241196a2d00002117200241186a2d00002106200241166a2f01002118200241156a2d00002110200241146a2d00002111200241126a2f01002112200241116a2d00002113200241106a2d000021192002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241046a2d00002114200241026a2f0100211502400240024020022d0000450d002003200737029c06200320173a009b06200320063a009a06200320183b0198060c010b200241086a2d00002108200241066a2f01002109200241056a2d0000210a20022d00012116200320073703980641002102201641ff01714101460d010b41012102410021094104210a410021080b200941ffff0371410874200a41ff017172200841187472210a2002450d04410f210841ea9fc60021090240200a0e0700010203044445000b200e410874200f72200d411874722109200b410874200c7220194118747221084101210a0c450b410e210841dc9fc60021094101210a0c440b410c210841d09fc60021094101210a0c430b4109210841c79fc60021094101210a0c420b4113210841b49fc60021094101210a0c410b2003200737038005200320173a00ff04200320063a00fe04200320183b01fc04200320103a00fb04200320113a00fa04200320123b01f804200320133a00f704200320193a00f6042003200b3b01f4042003200c3a00f3042003200d3a00f2042003200e3b01f0042003200f3a00ef042003200a3600eb04200320143a00ea04200320153b01e804411510282202450d22200241002900d08845370000410d21082002410d6a41002900dd8845370000200241086a41002900d8884537000020034295808080d00237025420032002360250200341e8046a200341d0006a108f012003280258210220032802502109200341a0026a41186a220a4200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220092002200341a0026a100020034198066a41186a200a29030037030020034198066a41106a201729030037030020034198066a41086a2006290300370300200320032903a0023703980602402003280254450d002003280250102a0b024020034198066a41204101410041001003417f470d0041e6d4c50021094101210a0c410b411510282202450d23200241002900d088453700002002410d6a41002900dd8845370000200241086a41002900d8884537000020034295808080d00237029c062003200236029806200341e8046a20034198066a108f0120032802a00621022003280298062108200341a0026a41186a22094200370300200341a0026a41106a220a4200370300200341a0026a41086a22174200370300200342003703a00220082002200341a0026a1000200341c0046a41186a2009290300370300200341c0046a41106a200a290300370300200341c0046a41086a2017290300370300200320032903a0023703c0040240200328029c06450d00200328029806102a0b2003410036029806200341c0046a412020034198066a100621022003280298062209417f460d252002450d25200320093602542003200236025020034198066a200341d0006a10b10120032d00b90622084102460d2420034188086a41186a20034198066a41186a29030037030020034188086a41106a20034198066a41106a29030037030020034188086a41086a20034198066a41086a29030037030020032003290398063703880820032d00b8062117200341a0026a200341ba066a41c100109a051a02402009450d002002102a0b200341c0046a412010090c260b41c4d1c3004133200341a8086a419cd9c3001038000b412041011037000b200241011037000b1036000b201841011037000b2002200a1044000b200a2017103c000b200920171044000b200341d0056a41146a4108360200200341dc056a412536020020034188056a41146a41033602002003420337028c05200341c8afc60036028805200341253602d4052003200341306a3602c004200320034180026a3602e804200342043703a8062003420137029c062003419cb0c600360298062003200341d0056a36029805200320034198066a3602e0052003200341e8046a3602d8052003200341c0046a3602d00520034188056a41d8b0c600103e000b200241011037000b200241011037000b410f41011037000b411741011037000b411341011037000b200841011037000b200941011037000b200941011037000b411341011037000b411741011037000b412e41011037000b41c4d1c3004133200341a8086a419cd9c3001038000b411741011037000b412e41011037000b410f41011037000b410f41011037000b410f41011037000b410f41011037000b410f41011037000b411541011037000b41c4d1c3004133200341a8086a419cd9c3001038000b41c4d1c3004133200341a8086a419cd9c3001038000b41b7b3c0004192011050000b200841011037000b200841011037000b411541011037000b411541011037000b41c4d1c3004133200341a8086a419cd9c3001038000b410221080b200341c8076a41186a220220034188086a41186a290300370300200341c8076a41106a220920034188086a41106a290300370300200341c8076a41086a220a20034188086a41086a29030037030020032003290388083703c80720034188056a200341a0026a41c100109a051a200341306a41086a2206200a290300370300200341306a41106a220a2009290300370300200341306a41186a22092002290300370300200320032903c807370330200341d0056a20034188056a41c100109a051a41072102024020084102460d0020034180026a41186a200929030037030020034180026a41106a200a29030037030020034180026a41086a20062903003703002003200329033037038002200320083a0050200341d0006a410172200341d0056a41c100109a05210a200341f2006a21094100210202400240024002400240024002400240024020032d00714101470d0020034198066a200910b001200341a0026a41186a20034198066a41186a22082900002207370300200341a0026a41106a20034198066a41106a22062900002204370300200341a0026a41086a20034198066a41086a221829000022053703002003200329009806221d3703a0022008200737030020062004370300201820053703002003201d37039806412010282202450d012002200329039806370000200241186a2008290300370000200241106a2006290300370000200241086a201829030037000020032d005021080b0240200841ff01714101460d0020032d00714101460d03200341a0026a41186a22084200370300200341a0026a41106a22094200370300200341a0026a41086a220a4200370300200342003703a00241e588c500411d200341a0026a100020034198066a41186a200829030037030020034198066a41106a200929030037030020034198066a41086a200a290300370300200320032903a0023703980620034198066a412010090c070b20034198066a200a10b001200341a0026a41186a20034198066a41186a2903002207370300200341a0026a41106a20034198066a41106a2903002204370300200341a0026a41086a20034198066a41086a29030022053703002003200329039806221d3703a002200341e8076a41186a22092007370300200341e8076a41106a220a2004370300200341e8076a41086a220620053703002003201d3703e807412010282208450d01200820032903e807370000200841186a2009290300370000200841106a200a290300370000200841086a200629030037000020034100360298062008412020034198066a1006210a2003280298062206417f460d04200a450d042003200636028c082003200a3602880820034198066a20034188086a10b10120032d00b90622194102460d03200341f1006a2109200341a0026a41206a220b20034198066a41206a22182d00003a0000200341a0026a41186a220c20034198066a41186a220d290300370300200341a0026a41106a220e20034198066a41106a220f290300370300200341a0026a41086a221020034198066a41086a221129030037030020032003290398063703a002200341b8036a200341ba066a221241c100109a051a02402006450d00200a102a0b201220032900b8033701002018200b2d00003a0000200d200c290300370300200f200e29030037030020112010290300370300200341c2066a200341b8036a41086a290000370100200341ca066a200341b8036a41106a290000370100200341d2066a200341b8036a41186a290000370100200320032903a00237039806200320193a00b906200341fa066a200941206a2d00003a0000200341f2066a200941186a290000370100200341ea066a200941106a290000370100200341e2066a200941086a290000370100200341da066a2009290000370100200341003602a802200342013703a00220034198066a200341a0026a108f01024020182d0000220941064b0d000240024002400240024002400240024020090e0700010203040506000b4100210a0c060b4101210a0c050b4102210a0c040b4103210a0c030b4104210a0c020b4105210a0c010b4106210a0b2003200a3a00a8080240024020032802a40220032802a8022209460d0020032802a00221060c010b200941016a220a2009490d1620094101742206200a2006200a4b1b220a4100480d160240024020090d00200a102821060c010b20032802a0022009200a102c21060b2006450d072003200a3602a402200320063602a00220032d00a808210a20032802a80221090b2003200941016a3602a802200620096a200a3a00000b200341b9066a200341a0026a10a90120032802a40221092008412020032802a002220a20032802a802100702402009450d00200a102a0b2008102a4101210a0c070b412041011037000b412041011037000b200341a0026a41186a22084200370300200341a0026a41106a220a4200370300200341a0026a41086a22064200370300200342003703a00241e588c500411d200341a0026a100020034198066a41186a200829030037030020034198066a41106a200a29030037030020034198066a41086a2006290300370300200320032903a00237039806200341203602a402200320034198066a3602a0022009200341a0026a10ff010c030b41c4d1c3004133200341a8086a419cd9c3001038000b41e2bbc00041d8001050000b200a41011037000b410021084100210a0b024002400240024002400240024020020d00410021090c010b20034100360298062002412020034198066a100621092003280298062206417f460d022009450d02200320063602bc03200320093602b80320034198066a200341b8036a10b10120032d00b9064102460d0120034188086a41186a221820034198066a41186a221929030037030020034188086a41106a220b20034198066a41106a220c29030037030020034188086a41086a220d20034198066a41086a220e29030037030020032003290398063703880820032d00b806210f200341a0026a200341ba066a221041c100109a051a02402006450d002009102a0b20192018290300370300200c200b290300370300200e200d2903003703002003200329038808370398062003200f3a00b8062010200341a0026a41c100109a051a200341c1066a200341d0006a41086a290300370000200341c9066a200341d0006a41106a290300370000200341d1066a200341d0006a41186a29030037000020034198066a41c1006a200341d0006a41206a2d00003a0000200320032903503700b906200341003602a802200342013703a00220034198066a200341a0026a108f01024020032d00b806220941064b0d000240024002400240024002400240024020090e0700010203040506000b410021060c060b410121060c050b410221060c040b410321060c030b410421060c020b410521060c010b410621060b200320063a00a8080240024020032802a40220032802a8022209460d0020032802a00221180c010b200941016a22062009490d14200941017422182006201820064b1b22064100480d140240024020090d002006102821180c010b20032802a00220092006102c21180b2018450d05200320063602a402200320183602a00220032d00a808210620032802a80221090b2003200941016a3602a802201820096a20063a00000b200341b9066a200341a0026a10a90120032802a40221092002412020032802a002220620032802a802100702402009450d002006102a0b2002102a410121090b200a20084572450d030c040b41c4d1c3004133200341a8086a419cd9c3001038000b41e2bbc00041d8001050000b200641011037000b2008102a0b02402002452009720d002002102a0b201721020b1098012108200342e4cab5fbb6ccdcb0e30037035041002109200341d0006a200341e8046a427f427f200841002002200241ff01714107461b41187441187541027441f48fc6006a2802004180de346c6a410210a90220034198066a41086a41093a000020034198066a41096a20032903e804370000200341a9066a200341e8046a41086a290300370000200341b1066a200341e8046a41106a290300370000200341b9066a200341e8046a41186a290300370000200341053a0098064101410020034198066a10cc014101210a0c190b41a39fc6002109411121080c180b20032802a006211820032903a0062207a7211941002102024002402007422088a7220641014b0d0020060e020201020b2006210803402008410176220920026a220a20022017200a4105746a200341d0056a4120109c054101481b2102200820096b220841014b0d000b0b201720024105746a200341d0056a4120109c052208450d0a0c010b20034198066a41186a200341d0056a41186a29030037030020034198066a41106a200341d0056a41106a29030037030020034198066a41086a200341d0056a41086a290300370300200320032903d005370398064100210620034198066a2108410021090c010b20034198066a41186a200341d0056a41186a29030037030020034198066a41106a200341d0056a41106a29030037030020034198066a41086a200341d0056a41086a290300370300200320032903d005370398062008411f7620026a220920064b0d0120034198066a21080b20062019460d012018210a0c020b41f8b0c0001032000b024020182006460d002018210a0c010b201841016a22022018490d042018410174220a2002200a20024b1b220a41ffffff3f71200a470d04200a41057422024100480d040240024020180d002002102821170c010b201720184105742002102c21170b2017450d010b201720094105746a220241206a2002200620096b410574109b051a200241186a200841186a290000370000200241106a200841106a290000370000200241086a200841086a290000370000200220082900003700001098012108411310282202450d01200241002900a9d3453700002002410f6a41002800b8d345360000200241086a41002900b1d34537000020034293808080b00237029c062003200236029806200320034198066a36025020034188056a200341d0006a10c801200328029806210220032802a0062109200341a0026a41186a22184200370300200341a0026a41106a22194200370300200341a0026a41086a220b4200370300200342003703a00220022009200341a0026a1000200341306a41186a2018290300370300200341306a41106a2019290300370300200341306a41086a200b290300370300200320032903a0023703300240200328029c06450d00200328029806102a0b410410282202450d0220034284808080c00037029c0620032002360298062002200841809c316a2209360000200641016a220220034198066a10b40102402002450d00200641057441206a2108201721020340200220034198066a108f01200241206a2102200841606a22080d000b0b200328029c062102200341306a4120200328029806220820032802a006100702402002450d002008102a0b0240200a450d002017102a0b20034198066a41086a410a3a0000200341a1066a20032903d005370000200341c1066a200329038805370000200341a9066a200341d0056a41086a290300370000200341b1066a200341d0056a41106a290300370000200341b9066a200341d0056a41186a290300370000200341c9066a20034188056a41086a290300370000200341d1066a20034188056a41106a290300370000200341d9066a20034188056a41186a290300370000200341053a009806200341e4066a2009360200410021094101410020034198066a10cc0120034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e807200341e8076a411010094101210a0c110b200241011037000b411341011037000b410441011037000b1031000b41a6d4c5002109412621082019450d0b2017102a4101210a0c0c0b200341003602a0062003420137039806200341d0006a20034198066a10eb01200328029c06210920032802a00621172003280298062102200341a0026a41186a22194200370300200341a0026a41106a220b4200370300200341a0026a41086a220c4200370300200342003703a00220022017200341a0026a100020034198066a41186a201929030037030020034198066a41106a200b29030037030020034198066a41086a200c290300370300200320032903a0023703980602402009450d002002102a0b0240200341d0056a20034198066a4120109c05450d0041bcd3c5002109410c21080c010b20034188086a41086a22024200370300200342003703880841988bc500411620034188086a1008200341e8076a41086a200229030037030020032003290388083703e807200341e8076a41101009109801210220034198066a200341d0006a418801109a051a200341a0026a200220064180a30520064180a3054b1b6a20034198066a2008201810b704024020032802a0024101470d0020032802a4022209450d00200341a0026a41086a28020021080c0c0b410021090c0b0b200341d0006a106a0c0a0b410121180b41012117410021090c100b200a106a200a102a410121064100210a410121180c080b200341013a00880520034198066a41186a200341b8036a41186a29030037030020034198066a41106a200341b8036a41106a29030037030020034198066a41086a200341b8036a41086a290300370300200320032903b803370398060240411710282202450d0041002109200241002900e3d2453700002002410f6a41002900f2d245370000200241086a41002900ebd24537000020034297808080f0023702d405200320023602d0052003200341d0056a3602a00220034198066a200341a0026a10c80120032802d005210220032802d8052108200341a0026a41186a220a4200370300200341a0026a41106a22174200370300200341a0026a41086a22064200370300200342003703a00220022008200341a0026a1000200341306a41186a200a290300370300200341306a41106a2017290300370300200341306a41086a2006290300370300200320032903a002370330024020032802d405450d0020032802d005102a0b4101210a200341306a412020034188056a41011007200b10ce03200341d0006a106a0c030b411741011037000b412221084101210a0c050b201720024105746a22022003290330370000200241186a200341306a41186a290300370000200241106a200a290300370000200241086a20182903003700004101210a20034198066a41186a200841016a360200200341ac066a2006360200200320073703a0062003200437039806200320093602b406200320173602a806201620034198066a10c404410021090b4101210641012118410121170c0b0b41afd2c5002109411a21082002450d012017102a4101210a0c020b4111210841a39fc60021090b4101210a0b41012106410121180b410121170c060b20032802d007210920032802cc07210a20032802c80721020b2002450d00200341e8076a4110200220091007200a450d012002102a0c010b41b00110282202450d01200320032802d8013602a00720034198066a200341d0006a10cf0320034198066a41a4016a200341d0006a41a4016a29020037020020034198066a419c016a200341d0006a419c016a29020037020020034198066a4194016a200341d0006a4194016a290200370200200320032902dc013702a407200220034198066a41b001109a05210220034188086a41086a22094200370300200342003703880841ac89c500411520034188086a1008200341e8076a41086a200929030037030020032003290388083703e8072003411036029c062003200341e8076a360298062002410120034198066a10ef012002106a2002102a0b200341d0006a106a200341b0066a2004370300200341a8066a2005370300200341a4066a200836020041002117200341a0066a41003a0000200341053a0098064101210a4101410020034198066a10cc012006106a2006102a4101210641012118410021090c020b41b00141081037000b2006106a2006102a410021174101210a41012106410121180b0240024020012d0000417f6a2202410f4b0d00024002400240024020020e1000040404040102030404040405040505000b2017450d04200141046a2202280200106a2002280200102a0c040b200a450d03200141046a2202280200106a2002280200102a0c030b2006450d02200141046a2202280200106a2002280200102a0c020b2018450d01200141046a2202280200106a2002280200102a0c010b200241074b0d00024002400240024020020e080004040404010203000b200141046a2202280200106a2002280200102a0c030b200141046a2202280200106a2002280200102a0c020b200141046a2202280200106a2002280200102a0c010b200141046a2202280200106a2002280200102a0b2000200836020420002009360200200341b0086a24000b8b0708047f047e057f027e017f017e017f017e230041a0016b2202240041002103200241003a0098012001280204417f6a210402400240024003402004417f460d01200241f8006a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a0098012004417f6a21042005210320054120470d000b200241d8006a41186a200241f8006a41186a290300370300200241d8006a41106a200241f8006a41106a290300370300200241d8006a41086a200241f8006a41086a29030037030020022002290378370358200241c0006a2001109f012002290340a7450d01200041003602200c020b0240200341ff0171450d00200241003a0098010b200041003602200c010b200241c0006a41106a290300210620022903482107200241286a2001109f0102402002290328a7450d00200041003602200c010b200241286a41106a290300210820022903302109200241206a2001106c02400240024002400240024020022802200d00200128020441186e220a41186c2204417f4c0d022002280224210b0240024020040d004108210c0c010b20041028220c450d040b0240200b450d00200241086a41106a210d4100210e41002105410021030340200241086a2001109f01024002402002290308a70d00200d290300210f2002290310211020022001106c2002280200450d010b200a450d03200c102a0c030b200341016a21042002280204211102402003200a470d00200e2004200e20044b1b220aad42187e2212422088a70d082012a722134100480d080240024020030d0020131028210c0c010b200c20052013102c210c0b200c450d070b200c20056a2203200f37030820032010370300200341106a2011360200200e41026a210e200541186a210520042103200b2004470d000b0b200c0d010b200041003602200c050b200241f8006a41186a200241d8006a41186a290300220f370300200241f8006a41106a200241d8006a41106a2903002210370300200241f8006a41086a200241d8006a41086a2903002212370300200220022903582214370378200041186a2008370300200020093703102000200637030820002007370300200041286a200b3602002000200a3602242000200c3602202000412c6a2014370200200041346a20123702002000413c6a2010370200200041c4006a200f3702000c040b1036000b200441081037000b201341081037000b1031000b200241a0016a24000bde0401067f230041306b2202240002400240024002400240411010282203450d00200341086a4100290097a5423700002003410029008fa54237000020024290808080800237021420022003360210410d200241106a10b40102400240024020022802142204200228021822056b410d490d002005410d6a2106200228021021030c010b2005410d6a22062005490d01200441017422032006200320064b1b22074100480d010240024020040d002007102821030c010b200228021020042007102c21030b2003450d032002200736021420022003360210200721040b20022006360218200320056a22054100290082a542370000200541056a4100290087a54237000020022003200610df0202402004450d002003102a0b20022802082203417f4c0d03200228020021050240024020030d0041012106410021040c010b20032104200310282206450d050b200620052003109a05210702402002280204450d002005102a0b200241106a200110e0020240200420036b4120490d00200341206a21050c060b200341206a22052003490d00200441017422062005200620054b1b22014100480d000240024020040d002001102821060c010b200720042001102c21060b02402006450d00200121040c060b200141011037000b1031000b411041011037000b200741011037000b1036000b200341011037000b200620036a22032002290010370000200341186a200241106a41186a290000370000200341106a200241106a41106a290000370000200341086a200241106a41086a290000370000200020053602082000200436020420002006360200200241306a24000bd00a010b7f230041c0006b2202240002400240024002400240024002400240024002400240411010282203450d00200341086a41002900b1c042370000200341002900a9c04237000020024290808080800237022420022003360220410d200241206a10b40102400240024020022802242204200228022822056b410d490d002005410d6a2106200228022021030c010b2005410d6a22062005490d01200441017422032006200320064b1b22074100480d010240024020040d002007102821030c010b200228022020042007102c21030b2003450d032002200736022420022003360220200721040b20022006360228200320056a22054100290082a542370000200541056a4100290087a54237000020022003200610df0202402004450d002003102a0b20022802082206417f4c0d03200228020021030240024020060d0041012107410021080c010b20062108200610282207450d050b200720032006109a05210902402002280204450d002003102a0b2001410c6a28020041046a2204417f4c0d03024002402004450d00200410282203450d0720024100360228200220043602240c010b200241003602282002200436022420024101360220410110282203450d07200241013602240b2002200336022020024101360228200320012d00003a00000240200228022422044101470d0041000d014102410241024102491b22044100480d01200341012004102c2203450d0820022004360224200220033602200b20024102360228200320012d00013a00010240024020044102460d00200421050c010b200441016a22052004490d012004410174220a2005200a20054b1b22054100480d010240024020040d002005102821030c010b200320042005102c21030b2003450d0920022005360224200220033602200b20024103360228200341026a20012d00023a0000024020054103470d00200541016a22042005490d012005410174220a2004200a20044b1b22044100480d010240024020050d002004102821030c010b200320052004102c21030b2003450d0a20022004360224200220033602200b20024104360228200341036a20012d00033a00002001280204210a200128020c2201200241206a10b4010240024020022802242205200228022822046b2001490d00200228022021030c010b200420016a22032004490d012005410174220b2003200b20034b1b220b4100480d010240024020050d00200b102821030c010b20022802202005200b102c21030b2003450d0b2002200b36022420022003360220200b21050b200320046a200a2001109a051a200241206a41186a220a4200370300200241206a41106a220b4200370300200241206a41086a220c4200370300200242003703202003200420016a200241206a1000200241186a200a290300370300200241106a200b290300370300200241086a200c2903003703002002200229032037030002402005450d002003102a0b0240200820066b4120490d00200641206a21010c0c0b200641206a22012006490d00200841017422032001200320014b1b22034100480d000240024020080d002003102821070c010b200920082003102c21070b02402007450d00200321080c0c0b200341011037000b1031000b411041011037000b200741011037000b1036000b200641011037000b200441011037000b410141011037000b200441011037000b200541011037000b200441011037000b200b41011037000b200720066a22032002290300370000200341186a200241186a290300370000200341106a200241106a290300370000200341086a200241086a290300370000200020013602082000200836020420002007360200200241c0006a24000be6e80106017f037e137f017e117f057e230041c0056b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0e000102030405060708090f101112000b20034184056a4101360200200342013702f404200341ccd1c5003602f004200341043602b401200341c4d1c5003602b0012003200341b0016a36028005200341f0046a41bc80c500103e000b200141306a2903002104200141286a29030021052001411d6a29000021062001411c6a2d000021072001411b6a2d00002108200141196a2f00002109200141186a2d0000210a200141176a2d0000210b200141156a2f0000210c200141146a2d0000210d200141136a2d0000210e200141116a2f0000210f200141106a2d000021102001410f6a2d000021112001410d6a2f000021122001410c6a2d00002113200141086a2802002114200141076a2d00002115200141056a2f0000211641042117200141046a2d0000211820012d000121192002411a6a290100211a200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d00002127200241046a2d00002128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b410021024100212a0b202a41ffff0371410874200241187472201741ff017172212a0240202b450d00410f211741ea9fc60021020240202a0e07000a0b0c0d5253000b20264108742027722025411874722102202341087420247220224118747221170c520b2003201a3703b8032003201b3a00b7032003201c3a00b6032003201d3b01b4032003201e3a00b3032003201f3a00b203200320203b01b003200320213a00af03200320223a00ae03200320233b01ac03200320243a00ab03200320253a00aa03200320263b01a803200320273a00a7032003202a3600a303200320283a00a203200320293b01a003410e10282202450d11200241002900fcae44370000200241066a4100290082af443700002003428e808080e0013702f404200320023602f004200341a0036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b4101212b0240200341d0006a41204101410041001003417f460d00419681c500210241142117410121220c530b0240201841ff01714101470d00200341f0046a201441067610fe0120032802f00421170240024020032802f8042014413f7122024b0d00410021020c010b201720024105746a2202290018210620022d0017210720022d0016210820022f0014210920022d0013210a20022d0012210b20022f0010210c20022d000f210d20022d000e210e20022f000c210f20022d000b211020022d000a211120022f0008211220022d000721132002280003211420022d0002211520022f00002116410121020b024020032802f404450d002017102a0b20020d0041dc9fc6002102410e2117410121220c530b200320063703c801200320073a00c701200320083a00c601200320093b01c4012003200a3a00c3012003200b3a00c2012003200c3b01c0012003200d3a00bf012003200e3a00be012003200f3b01bc01200320103a00bb01200320113a00ba01200320123b01b801200320133a00b701200320143600b301200320153a00b201200320163b01b001410e10282202450d122002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341b0016a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a2222420037030020034188046a41086a2223420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a2022290300370300200341d0006a41086a20232903003703002003200329038804370350024020032802f404450d0020032802f004102a0b0240200341d0006a41204101410041001003417f460d0041cc80c500210241192117410121220c530b02402005428080e983b1de165441002004501b450d0041e580c500210241312117410121220c530b200341f0046a41186a200341b0016a41186a290300370300200341f0046a41106a200341b0016a41106a290300370300200341f0046a41086a200341b0016a41086a290300370300200320032903b0013703f004410e10282202450d13200241002900fcae44370000200241066a4100290082af443700002003428e808080e0013702d404200320023602d004200341a0036a200341d0046a108f0120032802d804210220032802d004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802d404450d0020032802d004102a0b200341203602d4042003200341d0006a3602d004200341f0046a200341d0046a10ff01410d10282202450d1420024100290098af44370000200241056a410029009daf443700002003428d808080d0013702f404200320023602f004200341a0036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b024002400240024002400240201941037122024103460d0020020e03010203010b200341d0006a41204101410010070c040b410021170c020b410121170c010b410221170b200320173a00f004410110282202450d16200220173a0000200341d0006a41202002410110072002102a0b2003200341a0036a109101200341086a290300211a200329030021064100210220034198056a41003602002003419e056a20032d00a2033a00002003419f056a20032800a303360000200341a3056a20032d00a7033a0000200341b4056a20032903b803370200200341a4056a20032903a803370200200341ac056a20032903b00337020020034188056a201a20042006200554201a200454201a2004511b22171b221a370300200320032f01a0033b019c0520034208370390052003201a3703f80420032006200520171b221a3703f0042003201a37038005200341b0016a200341f0046a10b50420034194056a280200450d4f200328029005102a0c4f0b200141106a2903002106200141086a29030021042002411a6a290100211a200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d0000212741042117200241046a2d00002128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b410021024100212a0b202a41ffff0371410874200241187472201741ff017172212a0240202b450d00410f211741ea9fc60021020240202a0e0700090a0b0c5152000b20264108742027722025411874722102202341087420247220224118747221170c510b2003201a3703e8042003201b3a00e7042003201c3a00e6042003201d3b01e4042003201e3a00e3042003201f3a00e204200320203b01e004200320213a00df04200320223a00de04200320233b01dc04200320243a00db04200320253a00da04200320263b01d804200320273a00d7042003202a3600d304200320283a00d204200320293b01d004200341f0046a200341d0046a10b1044101212a0240024020032d00f0044101460d00410b211741aa81c50021020c010b2003418a046a20032d00f3043a0000200341b0016a41086a20034184056a290200370300200341bd016a20034189056a290000370000200320032f00f1043b0188042003200341fc046a2902003703b001200341f0046a41086a28020021174100212a20032802f40421020b20034180036a41026a222b20034188046a41026a2d00003a0000200341a8046a41086a2222200341b0016a41086a290300370300200341a8046a41106a200341b0016a41106a290300370300200320032f0188043b018003200320032903b0013703a804202a0d50200341b3036a2022290300370000200341a0036a41186a200341b5046a290000370000200320032f0180033b01a003200320173600a703200320023600a303200320032903a8043700ab032003202b2d00003a00a203410e10282202450d152002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341a0036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006211720032802f0042202417f460d2e200320023602ac04200320173602a804200341f0046a200341a8046a108a02200328029005222a450d16200341f0046a41186a290300212c200341f0046a410c6a350200211a200341bc056a280200212b200341f0046a41c4006a2902002105200341f0046a41c0006a2f01002122200341f0046a413c6a2f01002123200341f0046a41386a2f01002124200341f0046a41346a2f01002125200341f0046a412f6a28000021262003419c056a2f01002127200329038005212d20032902f404212e20032d00b305211b20032d00b205211c20032d00af05211d20032d00ae05211e20032d00ab05211f20032d00aa05212020032d00a705212120032d00a605212820032d00a305212920032d009e052114200329029405212f20032802f004210702402002450d002017102a0b200341b0016a41186a202c370300200341b0016a410c6a201a3e0200200341b0016a41c4006a2005370200200341f3016a201b3a0000200341f2016a201c3a0000200341b0016a41c0006a20223b0100200341ef016a201d3a0000200341ee016a201e3a0000200341b0016a413c6a20233b0100200341eb016a201f3a0000200341ea016a20203a0000200341b0016a41386a20243b0100200341e7016a20213a0000200341e6016a20283a0000200341b0016a41346a20253b0100200341e3016a20293a0000200341b0016a412f6a2026360000200341de016a20143a0000200341d4016a202f3702002003202d3703c0012003202e3702b4012003202b3602fc01200320273b01dc012003202a3602d001200320073602b001200341106a200341d0046a10910102402003290310221a20032903b001222e7d222f201a56200341106a41086a2903002205200341b0016a41086a29030022307d201a202e54ad7d221a200556201a2005511b0d0020032004202f202f200456201a200656201a2006511b22021b2204202d7c22053703c001200341c8016a2006201a20021b221a202c7c2005200454ad7c37030020032004202e7c22063703b0012003201a20307c2006200454ad7c3703b801200341a0036a200341b0016a10b5040b20032802d401450d4d20032802d001102a0c4d0b200141106a2903002106200141086a29030021042002411a6a290100211a200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d0000212741042117200241046a2d00002128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b410021024100212a0b202a41ffff0371410874200241187472201741ff017172212a0240202b450d00410f211741ea9fc60021020240202a0e070008090a0b5051000b20264108742027722025411874722102202341087420247220224118747221170c500b2003201a3703b8032003201b3a00b7032003201c3a00b6032003201d3b01b4032003201e3a00b3032003201f3a00b203200320203b01b003200320213a00af03200320223a00ae03200320233b01ac03200320243a00ab03200320253a00aa03200320263b01a803200320273a00a7032003202a3600a303200320283a00a203200320293b01a003410e10282202450d162002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341a0036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006210220032802f0042217417f460d2d2002450d2d200320173602d404200320023602d004200341f0046a200341d0046a108a02200328029005222a450d17200341f0046a41186a290300211a200341f0046a410c6a350200212d200341bc056a280200212b200341f0046a41c4006a290200212e200341f0046a41c0006a2f01002122200341f0046a413c6a2f01002123200341f0046a41386a2f01002124200341f0046a41346a2f01002125200341f0046a412f6a28000021262003419c056a2f01002127200329038005212c20032902f404212f20032d00b305211b20032d00b205211c20032d00af05211d20032d00ae05211e20032d00ab05211f20032d00aa05212020032d00a705212120032d00a605212820032d00a305212920032d009e052114200329029405210520032802f004210702402017450d002002102a0b200341b0016a41186a201a370300200341b0016a410c6a202d3e0200200341b0016a41c4006a202e370200200341f3016a201b3a0000200341f2016a201c3a0000200341b0016a41c0006a20223b0100200341ef016a201d3a0000200341ee016a201e3a0000200341b0016a413c6a20233b0100200341eb016a201f3a0000200341ea016a20203a0000200341b0016a41386a20243b0100200341e7016a20213a0000200341e6016a20283a0000200341b0016a41346a20253b0100200341e3016a20293a0000200341b0016a412f6a2026360000200341de016a20143a0000200341d4016a20053702002003202c3703c0012003202f3702b4012003202b3602fc01200320273b01dc012003202a3602d001200320073602b0012005a7212b02400240024002402005422088a7411f4b0d00202c2004202c200454201a200654201a2006511b22021b2204201a200620021b220684500d03200341c8016a4200201a20067d202c200454ad7d2205202c20047d222d428080e983b1de165441002005501b22171b37030020034200202d20171b3703c001200341f0046a41086a22024200370300200342003703f00441bb9cc6004112200341f0046a1008200341d0046a41086a2002290300370300200320032903f0043703d004200341003602f004200341d0046a4110200341f0046a1006210220032802f004222a417f470d0141a005212a0c020b41c581c500210241232117202b450d52202a102a0c520b024020020d0041a005212a0c010b202a4104490d1a2002280000212a2002102a202a41a0056a212a0b024020032802d801220220032802d401470d00200241016a222b2002490d4720024101742222202b2022202b4b1b2222ad42187e2205422088a70d472005a7222b4100480d470240024020020d00202b102821020c010b20032802d001200241186c202b102c21020b2002450d1b200320223602d401200320023602d00120032802d80121020b20032802d001200241186c6a2202201a200620171b3703082002202c200420171b3703002002202a360210200320032802d80141016a3602d801200341a0036a200341b0016a10b50420032802d401212b0b202b450d4c20032802d001102a410021020c4d0b2002411a6a290100211a200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d0000212741042117200241046a2d00002128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b410021024100212a0b202a41ffff0371410874200241187472201741ff017172212a0240202b450d00410f211741ea9fc60021020240202a0e07000708090a4f50000b20264108742027722025411874722102202341087420247220224118747221170c4f0b2003201a3703b8032003201b3a00b7032003201c3a00b6032003201d3b01b4032003201e3a00b3032003201f3a00b203200320203b01b003200320213a00af03200320223a00ae03200320233b01ac03200320243a00ab03200320253a00aa03200320263b01a803200320273a00a7032003202a3600a303200320283a00a203200320293b01a003410e10282202450d192002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341a0036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006210220032802f0042217417f460d2c2002450d2c200320173602b401200320023602b001200341f0046a200341b0016a108a022003280290052224450d1a20034188056a290300212c200341fc046a350200211a200341b4056a290200212e200341b0056a2f01002126200341ac056a2f01002127200341a8056a2f0100211b200341a4056a2f0100211c2003419c056a2f0100211d200329038005212d20032902f404210620032d00b305211e20032d00b205211f20032d00af05212020032d00ae05212120032d00ab05212820032d00aa05212920032d00a705211420032d00a605210720032d00a3052108200328009f05210920032d009e05210a200329029405210420032802f004212a02402017450d002002102a0b200341f0046a41086a22024200370300200342003703f00441bb9cc6004112200341f0046a1008200341d0046a41086a2002290300370300200320032903f0043703d0044100212b200341003602f004200341d0046a4110200341f0046a10062102024020032802f0042217417f460d002002450d0020174104490d1d2002280000212b2002102a0b201a422086200642208884211a2006422086202aad8421062004a7210b0240024002402004422088a7222541186c2202450d00202420026a2122200241686a2117202421020340200241086a290300210520022903002104202b200241106a280200222a490d024200201a20057d2006200454ad7d2205200620047d22042006562005201a562005201a511b222a1b211a42002004202a1b2106201741686a2117200241186a22022022470d000b0b410821234100212a0240200b0d00410021250c020b2024102a410021250c010b411810282223450d1e202320043703002023202a360210202320053703080240024020170d004101212a410121250c010b200241186a210c202541186c20246a41686a210e4101212a410121250340200c210202400340200241086a290300210520022903002104202b200241106a2802002217490d014200201a20057d2006200454ad7d2205200620047d22042006562005201a562005201a511b22171b211a4200200420171b2106200241186a22022022470d000c030b0b02402025202a470d00202a41016a2225202a490d48202a410174220c2025200c20254b1b2225ad42187e222f422088a70d48202fa7220c4100480d4802400240202a0d00200c102821230c010b2023202a41186c200c102c21230b2023450d220b200241186a210c2023202a41186c6a220d2005370308200d2004370300200d2017360210202a41016a212a200e2002470d000b0b200b450d002024102a0b200341b4056a202e370200200341b3056a201e3a0000200341b2056a201f3a0000200341b0056a20263b0100200341af056a20203a0000200341ae056a20213a0000200341ac056a20273b0100200341ab056a20283a0000200341aa056a20293a0000200341a8056a201b3b0100200341a7056a20143a0000200341a6056a20073a0000200341a4056a201c3b0100200341a3056a20083a00002003419f056a20093600002003419e056a200a3a000020034198056a202a36020020034194056a20253602002003202d3703800520034188056a202c370300200320063703f0042003201d3b019c0520032023360290052003201a3703f8040240202d202c844200520d00202a450d1c0b200341a0036a200341f0046a10b5040c4a0b200141106a2903002106200141086a29030021042002411a6a290100211a200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d0000212741042117200241046a2d00002128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b410021024100212a0b202a41ffff0371410874200241187472201741ff017172212a0240202b450d00410f211741ea9fc60021020240202a0e0700060708094e4f000b20264108742027722025411874722102202341087420247220224118747221170c4e0b2003201a370398012003201b3a0097012003201c3a0096012003201d3b0194012003201e3a0093012003201f3a009201200320203b019001200320213a008f01200320223a008e01200320233b018c01200320243a008b01200320253a008a01200320263b018801200320273a0087012003202a36008301200320283a008201200320293b018001410e10282202450d1e2002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f00420034180016a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006210220032802f0042217417f460d2b2002450d2b200320173602a403200320023602a003200341f0046a200341a0036a108a02200328029005222a450d1f200341f0046a41186a290300211a200341f0046a410c6a3502002105200341bc056a280200212b200341f0046a41c4006a290200212c200341f0046a41c0006a2f01002122200341f0046a413c6a2f01002123200341f0046a41386a2f01002124200341f0046a41346a2f01002125200341f0046a412c6a2f01002126200329038005212d20032902f404212e20032d00b305212720032d00b205211b20032d00af05211c20032d00ae05211d20032d00ab05211e20032d00aa05211f20032d00a705212020032d00a605212120032d00a3052128200328009f05212920032d009e052114200329029405212f20032802f004210702402017450d002002102a0b200341b0016a41186a201a370300200341b0016a410c6a20053e0200200341b0016a41c4006a202c370200200341f3016a20273a0000200341f2016a201b3a0000200341b0016a41c0006a20223b0100200341ef016a201c3a0000200341ee016a201d3a0000200341b0016a413c6a20233b0100200341eb016a201e3a0000200341ea016a201f3a0000200341b0016a41386a20243b0100200341e7016a20203a0000200341e6016a20213a0000200341b0016a41346a20253b0100200341e3016a20283a0000200341df016a2029360000200341de016a20143a0000200341d4016a202f3702002003202d3703c0012003202e3702b4012003202b3602fc01200320263b01dc012003202a3602d001200320073602b001200341b0016a412c6a222310a7042003200637037820032004370370411210282202450d20200241002900c1ae44370000200241106a41002f00d1ae443b0000200241086a41002900c9ae4437000020034292808080a0023702f404200320023602f0042023200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a100621250240024020032802f0042226417f460d002025450d00200320263602ec03200320253602e803200341386a200341e8036a109f0120032802380d4a20032802ec032202450d4a20032002417f6a222a3602ec03200320032802e803222241016a222b3602e80320222d0000220241014b0d4a410021240240024020020e020100010b41002102200341003a00900503400240202a2002470d00200341003602ec03200241ff0171450d4d200341003a0090050c4d0b200341f0046a20026a202220026a221741016a2d00003a00002003201741026a3602e8032003200241016a22173a0090052017210220174120470d000b200341a0036a41086a200341f0046a41086a290300370300200341a0036a41106a200341f0046a41106a290300370300200341a0036a41186a200341f0046a41186a290300370300200320032903f0043703a0032003202a20176b222a3602ec0341012124202220176a41016a212b0b20034188046a41186a200341a0036a41186a29030037030020034188046a41106a200341a0036a41106a29030037030020034188046a41086a200341a0036a41086a290300370300200320032903a00337038804202a450d4a2003202a417f6a222a3602ec032003202b41016a3602e803202b2d0000221741014b0d4a410021020240024020170e020100010b41002102200341003a00900503400240202a2002470d00200341003602ec03200241ff0171450d4d200341003a0090050c4d0b200341f0046a20026a202b20026a221741016a2d00003a00002003201741026a3602e8032003200241016a22173a0090052017210220174120470d000b200341a0036a41086a200341f0046a41086a290300370300200341a0036a41106a200341f0046a41106a290300370300200341a0036a41186a200341f0046a41186a290300370300200320032903f0043703a0032003202a20176b3602ec03410121020b200341c0026a41186a2222200341a0036a41186a2217290300370300200341c0026a41106a2223200341a0036a41106a222a290300370300200341c0026a41086a2227200341a0036a41086a222b290300370300200341e0026a41086a221b20034188046a41086a290300370300200341e0026a41106a221c20034188046a41106a290300370300200341e0026a41186a221d20034188046a41186a290300370300200320032903a0033703c00220032003290388043703e002200341a0026a41186a221e201d290300370300200341a0026a41106a221d201c290300370300200341a0026a41086a221c201b290300370300200320032903e0023703a00220034180026a41186a221b202229030037030020034180026a41106a2222202329030037030020034180026a41086a22232027290300370300200320032903c00237038002200341f0046a41186a2227201e290300370300200341f0046a41106a221e201d290300370300200341f0046a41086a221d201c290300370300200320032903a0023703f0042017201b290300370300202a2022290300370300202b202329030037030020032003290380023703a00320244102460d4a200341d0046a41186a2027290300370300200341d0046a41106a201e290300370300200341d0046a41086a201d290300370300200341a8046a41086a202b290300370300200341a8046a41106a202a290300370300200341a8046a41186a2017290300370300200320032903f0043703d004200320032903a0033703a80402402026450d002025102a0b200341a0036a41186a200341d0046a41186a290300370300200341a0036a41106a200341d0046a41106a290300370300200341a0036a41086a200341d0046a41086a29030037030020034188046a41086a200341a8046a41086a29030037030020034188046a41106a200341a8046a41106a29030037030020034188046a41186a200341a8046a41186a290300370300200320032903d0043703a003200320032903a804370388040c010b200341e8036a41186a22024200370300200341e8036a41106a22174200370300200341e8036a41086a222a4200370300200342003703e80341d3aec400411a200341e8036a1000200341f0046a41186a222b2002290300370300200341f0046a41106a22222017290300370300200341f0046a41086a2224202a290300370300200320032903e8033703f004200341a0036a200341f0046a412010fd01024020032d00a0030d002002420037030020174200370300202a4200370300200342003703e80341d3aec400411a200341e8036a1000202b2002290300370300202220172903003703002024202a290300370300200320032903e8033703f004200341203602d4042003200341f0046a3602d0042023200341d0046a10ff0141002102410021240c010b200341c8036a41186a200341b9036a290000370300200341c8036a41106a200341b1036a290000370300200341c8036a41086a200341a9036a290000370300200320032900a1033703c80320034180036a200341c8036a10ac01200341003602f00420034180036a4120200341f0046a1006212420032802f0042226417f460d222024450d22200320263602a401200320243602a001200341206a200341a0016a109f012003290320a70d4820032802a4012202450d48200341306a290300211a2003290328210620032002417f6a222a3602a401200320032802a001222241016a222b3602a00120222d0000220241014b0d48410021250240024020020e020100010b41002102200341003a00900503400240202a2002470d00200341003602a401200241ff0171450d4b200341003a0090050c4b0b200341f0046a20026a202220026a221741016a2d00003a00002003201741026a3602a0012003200241016a22173a0090052017210220174120470d000b20034188046a41086a200341f0046a41086a2903002204370300200341d0046a41186a200341f0046a41186a290300370300200341d0046a41106a200341f0046a41106a290300370300200341d0046a41086a20043703002003202a20176b222a3602a401200320032903f004220437038804200320043703d00441012125202220176a41016a212b0b200341e8036a41186a200341d0046a41186a290300370300200341e8036a41106a200341d0046a41106a290300370300200341e8036a41086a200341d0046a41086a290300370300200320032903d0043703e80341002122200341003a00f004202a450d482003202a417f6a222a3602a4012003202b41016a3602a001202b2d0000220241014b0d480240024020020e020100010b41002102200341003a00900503400240202a2002470d00200341003602a401200241ff0171450d4b200341003a0090050c4b0b200341f0046a20026a202b20026a221741016a2d00003a00002003201741026a3602a0012003200241016a22173a0090052017210220174120470d000b200341a8046a41086a200341f0046a41086a2903002204370300200341d0046a41186a200341f0046a41186a290300370300200341d0046a41106a200341f0046a41106a290300370300200341d0046a41086a20043703002003202a20176b3602a401200320032903f00422043703a804200320043703d004410121220b200341c0026a41186a222b200341d0046a41186a2202290300370300200341c0026a41106a2227200341d0046a41106a2217290300370300200341c0026a41086a221b200341d0046a41086a222a290300370300200341e0026a41086a221c200341e8036a41086a290300370300200341e0026a41106a221d200341e8036a41106a290300370300200341e0026a41186a221e200341e8036a41186a290300370300200320032903d0043703c002200320032903e8033703e002200341a0026a41186a221f201e290300370300200341a0026a41106a221e201d290300370300200341a0026a41086a221d201c290300370300200320032903e0023703a00220034180026a41186a221c202b29030037030020034180026a41106a222b202729030037030020034180026a41086a2227201b290300370300200320032903c00237038002200341f0046a41186a221b201f290300370300200341f0046a41106a221f201e290300370300200341f0046a41086a221e201d290300370300200320032903a0023703f0042002201c2903003703002017202b290300370300202a202729030037030020032003290380023703d00420254102460d48200341a8046a41186a201b290300370300200341a8046a41106a201f290300370300200341a8046a41086a201e29030037030020034188046a41086a202a29030037030020034188046a41106a201729030037030020034188046a41186a2002290300370300200320032903f0043703a804200320032903d0043703880402402026450d002024102a0b200341d0046a41186a2224200341a8046a41186a290300370300200341d0046a41106a222b200341a8046a41106a290300370300200341d0046a41086a2226200341a8046a41086a290300370300200341e8036a41086a220220034188046a41086a2227290300370300200341e8036a41106a221720034188046a41106a221b290300370300200341e8036a41186a222a20034188046a41186a221c290300370300200320032903a8043703d00420032003290388043703e803200320253a00f004200341f9046a202629030037000020034181056a202b29030037000020034189056a2024290300370000200320032903d0043700f104200320223a00910520034192056a222520032903e8033701002003419a056a2002290300370100200341a2056a2017290300370100200341aa056a202a29030037010041002124200341e4046a2025410020221b3602002003201a3703d804200320063703d004200320233602e004200341003602b004200342013703a8042003200341d0046a3602880420034188046a200341a8046a10a301202b200341a8046a10aa0120032802ac04212b20034180036a412020032802a804222220032802b00410070240202b450d002022102a0b202a42003703002017420037030020024200370300200342003703e80341d3aec400411a200341e8036a1000200341f0046a41186a202a290300370300200341f0046a41106a2017290300370300200341f0046a41086a2002290300370300200320032903e8033703f004200341203602d4042003200341f0046a3602d0042023200341d0046a10ff012027200341c8036a41086a290300370300201b200341c8036a41106a290300370300201c200341c8036a41186a290300370300200320032903c80337038804410121020b200341fd046a200341a0036a41086a29030037000020034185056a200341a0036a41106a2903003700002003418d056a200341a0036a41186a29030037000020034195056a20023a000020034196056a2003290388043701002003419e056a20034188046a41086a290300370100200341a6056a20034188046a41106a290300370100200341ae056a20034188046a41186a290300370100200320243a00f404200320032903a0033700f5042003200341f0006a3602f004200341003602d804200342013703d0042003200341f0006a3602a804200341a8046a200341d0046a10a301200341f0046a410472200341d0046a10a90120032802d4042102200341d0006a412020032802d004221720032802d804100702402002450d002017102a0b20032802d401450d4a20032802d001102a410021020c4b0b2001410c6a2802002108200141086a280200211b41042117200141046a280200211c2002411a6a290100211a200241196a2d0000211d200241186a2d0000211e200241166a2f0100211f200241156a2d00002120200241146a2d00002121200241126a2f01002128200241116a2d00002129200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d00002127200241046a2d00002114200241026a2f010021070240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b4100212a410021020b202a41ffff0371410874201741ff017172200241187472212a0240202b450d00410f211741ea9fc6002102024002400240024002400240202a0e070001020304054c000b20264108742027722025411874722102202341087420247220224118747221170c4b0b410e211741dc9fc60021020c4a0b410c211741d09fc60021020c490b4109211741c79fc60021020c480b4113211741b49fc60021020c470b4111211741a39fc60021020c460b2003201a370398012003201d3a0097012003201e3a0096012003201f3b019401200320203a009301200320213a009201200320283b019001200320293a008f01200320223a008e01200320233b018c01200320243a008b01200320253a008a01200320263b018801200320273a0087012003202a36008301200320143a008201200320073b018001410e10282202450d212002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f00420034180016a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a10062102024020032802f0042217417f460d002002450d00200320173602a403200320023602a003200341f0046a200341a0036a108a02200328029005222a450d23200341f0046a41186a2903002106200341f0046a410c6a3502002104200341bc056a280200212b200341f0046a41c4006a2902002105200341f0046a41c0006a2f01002122200341f0046a413c6a2f01002123200341f0046a41386a2f01002124200341f0046a41346a2f01002125200341f0046a412c6a2f01002126200329038005212c20032902f404212d20032d00b305212720032d00b205211d20032d00af05211e20032d00ae05211f20032d00ab05212020032d00aa05212120032d00a705212820032d00a605212920032d00a3052114200328009f05210720032d009e052109200329029405211a20032802f004210a02402017450d002002102a0b200341b0016a41186a2006370300200341b0016a410c6a20043e0200200341b0016a41c4006a2005370200200341f3016a20273a0000200341f2016a201d3a0000200341b0016a41c0006a20223b0100200341ef016a201e3a0000200341ee016a201f3a0000200341b0016a413c6a20233b0100200341eb016a20203a0000200341ea016a20213a0000200341b0016a41386a20243b0100200341e7016a20283a0000200341e6016a20293a0000200341b0016a41346a20253b0100200341e3016a20143a0000200341df016a2007360000200341de016a20093a0000200341b0016a41246a201a3702002003202c3703c0012003202d3702b4012003202b3602fc01200320263b01dc012003202a3602d0012003200a3602b0012008450d44200341003a00a804200341103602e0042003201c200841246c6a3602dc042003201c3602d8042003201b3602d4042003201c3602d0042003200341a8046a3602e404200341f0046a200341d0046a1085040240024020032d00f0044101460d0020032802dc04212a20032802d8042102024003400240202a2002470d002002212b0c020b20022d00002117200241246a222b210220174102470d000b0b2003202b3602d8044100212441012123024020032802d4040d00410021020c020b20032802d004102a410021020c010b412010282223450d25202320032900f104370000202341186a20034189056a290000370000202341106a20034181056a290000370000202341086a200341f9046a290000370000200341a0036a41106a200341d0046a41106a290300370300200341a0036a41086a200341d0046a41086a290300370300200320032903d0043703a003200341f0046a200341a0036a1085040240024020032d00f0040d0041012102410121240c010b200341f0046a4101722117410221224120212b4101210241012124034020034188046a41186a2225201741186a29000037030020034188046a41106a2226201741106a29000037030020034188046a41086a2227201741086a2900003703002003201729000037038804024020022024470d00200241016a222a2002490d472022202a2022202a4b1b222441ffffff3f712024470d472024410574222a4100480d470240024020020d00202a102821230c010b2023202b202a102c21230b20230d00202a41011037000b2023202b6a222a200329038804370000202a41186a2025290300370000202a41106a2026290300370000202a41086a2027290300370000202241026a2122202b41206a212b200241016a2102200341f0046a200341a0036a10850420032d00f0040d000b0b20032802ac03212b20032802a8032117024003400240202b2017470d00201721220c020b20172d0000212a201741246a22222117202a4102470d000b0b200320223602a80320032802a403450d0020032802a003102a0b024020032d00a804450d002024450d432023102a0c430b2023450d42200341b0016a412c6a222a10a604200320023602a801200320243602a401200320233602a001411210282202450d2520024100290095ae44370000200241106a41002f00a5ae443b0000200241086a410029009dae4437000020034292808080a0023702f404200320023602f004202a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222b420037030020034188046a41106a2222420037030020034188046a41086a2223420037030020034200370388042017200220034188046a1000200341d0006a41186a202b290300370300200341d0006a41106a2022290300370300200341d0006a41086a20232903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006212b024020032802f0042222417f460d00202b450d00200320223602ec032003202b3602e803200341d0046a200341e8036a106d20032802d0042224450d3f20032802d404212a20032802ec032202450d3e20032002417f6a22233602ec03200320032802e803222541016a22263602e80320252d0000221741014b0d3e410021020240024020170e020100010b41002102200341003a0090050340024020232002470d00200341003602ec03200241ff0171450d41200341003a0090050c410b200341f0046a20026a202520026a221741016a2d00003a00002003201741026a3602e8032003200241016a22173a0090052017210220174120470d000b200341a0036a41086a200341f0046a41086a290300370300200341a0036a41106a200341f0046a41106a290300370300200341a0036a41186a200341f0046a41186a290300370300200320032903f0043703a0032003202320176b22233602ec0341012102202520176a41016a21260b20034188046a41186a200341a0036a41186a29030037030020034188046a41106a200341a0036a41106a29030037030020034188046a41086a200341a0036a41086a290300370300200320032903a003370388042023450d3e20032023417f6a22253602ec032003202641016a3602e80320262d0000222341014b0d3e410021170240024020230e020100010b41002117200341003a0090050340024020252017470d00200341003602ec03201741ff0171450d41200341003a0090050c410b200341f0046a20176a202620176a222341016a2d00003a00002003202341026a3602e8032003201741016a22233a0090052023211720234120470d000b200341a0036a41086a200341f0046a41086a290300370300200341a0036a41106a200341f0046a41106a290300370300200341a0036a41186a200341f0046a41186a290300370300200320032903f0043703a0032003202520236b3602ec03410121170b200341c0026a41186a2223200341a0036a41186a2225290300370300200341c0026a41106a2226200341a0036a41106a2227290300370300200341c0026a41086a221b200341a0036a41086a221c290300370300200341e0026a41086a221d20034188046a41086a290300370300200341e0026a41106a221e20034188046a41106a290300370300200341e0026a41186a221f20034188046a41186a290300370300200320032903a0033703c00220032003290388043703e002200341a0026a41186a2220201f290300370300200341a0026a41106a221f201e290300370300200341a0026a41086a221e201d290300370300200320032903e0023703a00220034180026a41186a221d202329030037030020034180026a41106a2223202629030037030020034180026a41086a2226201b290300370300200320032903c00237038002200341f0046a41186a2020290300370300200341f0046a41106a201f290300370300200341f0046a41086a201e290300370300200320032903a0023703f0042025201d29030037030020272023290300370300201c202629030037030020032003290380023703a0030c400b200341e8036a41186a22024200370300200341e8036a41106a22174200370300200341e8036a41086a222b4200370300200342003703e80341a7aec400411a200341e8036a1000200341f0046a41186a22222002290300370300200341f0046a41106a22232017290300370300200341f0046a41086a2224202b290300370300200320032903e8033703f004200341a0036a200341f0046a412010fd01024020032d00a0030d002002420037030020174200370300202b4200370300200342003703e80341a7aec400411a200341e8036a100020222002290300370300202320172903003703002024202b290300370300200320032903e8033703f004200341203602d4042003200341f0046a3602d004202a200341d0046a10ff01410021170c3c0b200341c8036a41186a200341b9036a290000370300200341c8036a41106a200341b1036a290000370300200341c8036a41086a200341a9036a290000370300200320032900a1033703c80320034180036a200341c8036a10ae01200341003602f00420034180036a4120200341f0046a1006212320032802f0042226417f460d262023450d26200320263602cc04200320233602c804200341f0006a200341c8046a106d20032802702224450d392003280274212220032802cc042202450d38200341f8006a280200212b20032002417f6a22273602cc04200320032802c804221b41016a221c3602c804201b2d0000220241014b0d38410021250240024020020e020100010b41002102200341003a0090050340024020272002470d00200341003602cc04200241ff0171450d3b200341003a0090050c3b0b200341f0046a20026a201b20026a221741016a2d00003a00002003201741026a3602c8042003200241016a22173a0090052017210220174120470d000b20034188046a41086a200341f0046a41086a290300221a370300200341d0046a41186a200341f0046a41186a290300370300200341d0046a41106a200341f0046a41106a290300370300200341d0046a41086a201a3703002003202720176b22273602cc04200320032903f004221a370388042003201a3703d00441012125201b20176a41016a211c0b200341e8036a41186a200341d0046a41186a290300370300200341e8036a41106a200341d0046a41106a290300370300200341e8036a41086a200341d0046a41086a290300370300200320032903d0043703e80341002117200341003a00f0042027450d3820032027417f6a22273602cc042003201c41016a3602c804201c2d0000220241014b0d380240024020020e020100010b41002102200341003a0090050340024020272002470d00200341003602cc04200241ff0171450d3b200341003a0090050c3b0b200341f0046a20026a201c20026a221741016a2d00003a00002003201741026a3602c8042003200241016a22173a0090052017210220174120470d000b200341a8046a41086a200341f0046a41086a290300221a370300200341d0046a41186a200341f0046a41186a290300370300200341d0046a41106a200341f0046a41106a290300370300200341d0046a41086a201a3703002003202720176b3602cc04200320032903f004221a3703a8042003201a3703d004410121170b200341c0026a41186a2202200341d0046a41186a2227290300370300200341c0026a41106a221b200341d0046a41106a221c290300370300200341c0026a41086a221d200341d0046a41086a221e290300370300200341e0026a41086a221f200341e8036a41086a290300370300200341e0026a41106a2220200341e8036a41106a290300370300200341e0026a41186a2221200341e8036a41186a290300370300200320032903d0043703c002200320032903e8033703e002200341a0026a41186a22282021290300370300200341a0026a41106a22212020290300370300200341a0026a41086a2220201f290300370300200320032903e0023703a00220034180026a41186a221f200229030037030020034180026a41106a2202201b29030037030020034180026a41086a221b201d290300370300200320032903c00237038002200341f0046a41186a2028290300370300200341f0046a41106a2021290300370300200341f0046a41086a2020290300370300200320032903a0023703f0042027201f290300370300201c2002290300370300201e201b29030037030020032003290380023703d0040c3a0b4110211741b581c50021020c450b2002411a6a290100211a200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d0000212741042117200241046a2d00002128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b4100212a410021020b202a41ffff0371410874201741ff017172200241187472212a0240202b450d00410f211741ea9fc60021020240202a0e0700040506074c4d000b20264108742027722025411874722102202341087420247220224118747221170c4c0b2003201a3703b8032003201b3a00b7032003201c3a00b6032003201d3b01b4032003201e3a00b3032003201f3a00b203200320203b01b003200320213a00af03200320223a00ae03200320233b01ac03200320243a00ab03200320253a00aa03200320263b01a803200320273a00a7032003202a3600a303200320283a00a203200320293b01a003410e10282202450d252002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341a0036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006211720032802f0042202417f460d29200320023602d404200320173602d004200341f0046a200341d0046a108a02200328029005222a450d26200341f0046a41186a290300211a200341f0046a410c6a3502002106200341bc056a280200212b200341f0046a41c4006a2902002104200341f0046a41c0006a2f01002122200341f0046a413c6a2f01002123200341f0046a41386a2f01002124200341f0046a41346a2f01002125200341f0046a412c6a2f01002126200329038005210520032902f404212c20032d00b305212720032d00b205211b20032d00af05211c20032d00ae05211d20032d00ab05211e20032d00aa05211f20032d00a705212020032d00a605212120032d00a3052128200328009f05212920032d009e052114200329029405212d20032802f004210702402002450d002017102a0b200341b0016a41186a201a370300200341b0016a410c6a20063e0200200341b0016a41c4006a2004370200200341f3016a20273a0000200341f2016a201b3a0000200341b0016a41c0006a20223b0100200341ef016a201c3a0000200341ee016a201d3a0000200341b0016a413c6a20233b0100200341eb016a201e3a0000200341ea016a201f3a0000200341b0016a41386a20243b0100200341e7016a20203a0000200341e6016a20213a0000200341b0016a41346a20253b0100200341e3016a20283a0000200341df016a2029360000200341de016a20143a0000200341d4016a2202202d370200200320053703c0012003202c3702b4012003202b3602fc01200320263b01dc012003202a3602d001200320073602b001200341b0016a412c6a221710a604201710a7042002280200450d4820032802d001102a410021020c490b20012d000121142002411a6a290100211a200241196a2d0000211b200241186a2d0000211c200241166a2f0100211d200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d0000212741042117200241046a2d00002128200241026a2f010021290240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b4100212a410021020b202a41ffff0371410874201741ff017172200241187472212a0240202b450d00410f211741ea9fc60021020240202a0e0700030405064b4c000b20264108742027722025411874722102202341087420247220224118747221170c4b0b2003201a3703b8032003201b3a00b7032003201c3a00b6032003201d3b01b4032003201e3a00b3032003201f3a00b203200320203b01b003200320213a00af03200320223a00ae03200320233b01ac03200320243a00ab03200320253a00aa03200320263b01a803200320273a00a7032003202a3600a303200320283a00a203200320293b01a003410e10282202450d262002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341a0036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006210220032802f0042217417f460d282002450d28200320173602d404200320023602d004200341f0046a200341d0046a108a02200328029005222a450d27200341f0046a41186a290300211a200341f0046a410c6a3502002106200341bc056a280200212b200341f0046a41c4006a2902002104200341f0046a41c0006a2f01002122200341f0046a413c6a2f01002123200341f0046a41386a2f01002124200341f0046a41346a2f01002125200341f0046a412c6a2f01002126200329038005210520032902f404212c20032d00b305212720032d00b205211b20032d00af05211c20032d00ae05211d20032d00ab05211e20032d00aa05211f20032d00a705212020032d00a605212120032d00a3052128200328009f05212920032d009e052107200329029405212d20032802f004210802402017450d002002102a0b200341b0016a41186a201a370300200341b0016a410c6a20063e0200200341b0016a41c4006a2004370200200341f3016a20273a0000200341f2016a201b3a0000200341b0016a41c0006a20223b0100200341ef016a201c3a0000200341ee016a201d3a0000200341b0016a413c6a20233b0100200341eb016a201e3a0000200341ea016a201f3a0000200341b0016a41386a20243b0100200341e7016a20203a0000200341e6016a20213a0000200341b0016a41346a20253b0100200341e3016a20283a0000200341df016a2029360000200341de016a20073a0000200341d4016a202d370200200320053703c0012003202c3702b4012003202b3602fc01200320263b01dc012003202a3602d001200320083602b001410d10282202450d2920024100290098af44370000200241056a410029009daf443700002003428d808080d0013702f404200320023602f004200341b0016a412c6a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b024002400240024002400240201441037122024103460d0020020e03010203010b200341d0006a41204101410010070c040b410021170c020b410121170c010b410221170b200320173a00f004410110282202450d2b200220173a0000200341d0006a41202002410110072002102a0b20032802d401450d4720032802d001102a410021020c480b2001411d6a29000021062001411c6a2d000021072001411b6a2d00002108200141196a2f00002109200141186a2d0000210a200141176a2d0000210b200141156a2f0000210c200141146a2d0000210d200141136a2d0000210e200141116a2f0000210f200141106a2d000021102001410f6a2d000021112001410d6a2f000021122001410c6a2d00002113200141086a280200211b200141076a2d00002115200141056a2f0000211641042117200141046a2d000021182002411a6a290100211a200241196a2d0000211c200241186a2d0000211d200241166a2f0100211e200241156a2d0000211f200241146a2d00002120200241126a2f01002121200241116a2d00002128200241106a2d000021222002410e6a2f010021232002410d6a2d000021242002410c6a2d000021252002410a6a2f01002126200241096a2d00002127200241046a2d00002129200241026a2f010021140240024020022d00000d0020022d00014101470d00200241056a2d00002117200241066a2f0100212a200241086a2d000021024100212b0c010b4101212b4100212a410021020b202a41ffff0371410874201741ff017172200241187472212a202b450d04410f211741ea9fc60021020240202a0e070001020304494a000b20264108742027722025411874722102202341087420247220224118747221170c490b410e211741dc9fc60021020c480b410c211741d09fc60021020c470b4109211741c79fc60021020c460b4113211741b49fc60021020c450b2003201a3703e0032003201c3a00df032003201d3a00de032003201e3b01dc032003201f3a00db03200320203a00da03200320213b01d803200320283a00d703200320223a00d603200320233b01d403200320243a00d303200320253a00d203200320263b01d003200320273a00cf032003202a3600cb03200320293a00ca03200320143b01c803200341f0046a200341c8036a10b1044101212a0240024020032d00f0044101460d00410b211741aa81c50021020c010b2003418a046a20032d00f3043a0000200341b0016a41086a20034184056a290200370300200341bd016a20034189056a290000370000200320032f00f1043b0188042003200341fc046a2902003703b001200341f0046a41086a28020021174100212a20032802f40421020b20034180036a41026a222b20034188046a41026a2d00003a0000200341a8046a41086a2222200341b0016a41086a290300370300200341a8046a41106a200341b0016a41106a290300370300200320032f0188043b018003200320032903b0013703a804202a0d44200341fb036a202229030037000020034180046a200341b5046a290000370000200320032f0180033b01e803200320173600ef03200320023600eb03200320032903a8043700f3032003202b2d00003a00ea030240201841ff01714101470d00200341f0046a201b41067610fe0120032802f00421170240024020032802f804201b413f7122024b0d00410021020c010b201720024105746a2202290018210620022d0017210720022d0016210820022f0014210920022d0013210a20022d0012210b20022f0010210c20022d000f210d20022d000e210e20022f000c210f20022d000b211020022d000a211120022f0008211220022d000721132002280003211b20022d0002211520022f00002116410121020b024020032802f404450d002017102a0b20020d0041dc9fc6002102410e21170c450b200320063703c004200320073a00bf04200320083a00be04200320093b01bc042003200a3a00bb042003200b3a00ba042003200c3b01b8042003200d3a00b7042003200e3a00b6042003200f3b01b404200320103a00b304200320113a00b204200320123b01b004200320133a00af042003201b3600ab04200320153a00aa04200320163b01a804410e10282202450d252002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341a8046a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b0240200341d0006a41204101410041001003417f460d0041cc80c5002102411921170c450b200341a8046a200341e8036a4120109c05450d41410e10282202450d26200241002900fcae44370000200241066a4100290082af443700002003428e808080e0013702f404200320023602f004200341c8036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341203602f4042003200341d0006a3602f004200341a8046a200341f0046a10ff01410e10282202450d272002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702f404200320023602f004200341e8036a200341f0046a108f0120032802f804210220032802f004211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802f404450d0020032802f004102a0b200341003602f004200341d0006a4120200341f0046a1006212a0240024020032802f0042217417f470d00410021020c010b2003201736028c042003202a36028804200341f0046a20034188046a108a022003280290052202450d29200341b0016a41186a200341f0046a41186a290300370300200341b0016a41106a200341f0046a41106a290300370300200341b0016a41086a200341f0046a41086a290300370300200320032903f0043703b0012003419c056a2f010021222003419f056a2800002124200341a4056a2f01002126200341a8056a2f0100211c200341ac056a2f0100211f200341b0056a2f01002128200341b4056a290200212d200341bc056a2802002107200329029405212c20032d009e05212320032d00a305212520032d00a605212720032d00a705211b20032d00aa05211d20032d00ab05211e20032d00ae05212020032d00af05212120032d00b205212920032d00b305211402402017450d00202a102a0b200341d0006a412010090b200341a0036a41186a200341b0016a41186a290300221a370300200341a0036a41106a200341b0016a41106a2903002206370300200341a0036a41086a200341b0016a41086a2903002204370300200320032903b00122053703a003200341f0046a41186a2217201a370300200341f0046a41106a222a2006370300200341f0046a41086a222b2004370300200320053703f0042002450d41200341d0046a41186a2017290300221a370300200341d0046a41106a202a2903002206370300200341d0046a41086a202b2903002204370300200320032903f00422053703d0042017201a370300202a2006370300202b2004370300200341b4056a202d370200200341b3056a20143a0000200341b2056a20293a0000200341b0056a20283b0100200341af056a20213a0000200341ae056a20203a0000200341ac056a201f3b0100200341ab056a201e3a0000200341aa056a201d3a0000200341a8056a201c3b0100200341a7056a201b3a0000200341a6056a20273a0000200341a4056a20263b0100200341a3056a20253a00002003419f056a20243600002003419e056a20233a000020034194056a202c370200200320053703f004200320073602bc05200320223b019c052003200236029005410e10282202450d292002410029008aaf44370000200241066a4100290090af443700002003428e808080e0013702b401200320023602b001200341a8046a200341b0016a108f0120032802b801210220032802b001211720034188046a41186a222a420037030020034188046a41106a222b420037030020034188046a41086a2222420037030020034200370388042017200220034188046a1000200341d0006a41186a202a290300370300200341d0006a41106a202b290300370300200341d0006a41086a20222903003703002003200329038804370350024020032802b401450d0020032802b001102a0b200341203602b4012003200341d0006a3602b001200341f0046a200341b0016a10b604200328029405450d41200328029005102a410021020c420b4101212b024020022d000120022d000072450d0041a39fc600210241112117410121220c450b200141046a2802002102200341f0046a41086a22174200370300200342003703f00441889cc6004116200341f0046a1008200341d0046a41086a2017290300370300200320032903f0043703d004200320023602f004200341d0046a4110200341f0046a410410070c2c0b20022d000120022d0000720d2c200341f0046a41086a22024200370300200342003703f004418e9dc6004110200341f0046a1008200341d0046a41086a2002290300370300200320032903f0043703d004200341023a00f0044101212b410110282202450d28200241023a0000200341d0046a41102002410110072002102a0c2b0b20022d000120022d0000720d2b200341f0046a41086a22024200370300200342003703f004418e9dc6004110200341f0046a1008200341d0046a41086a2002290300370300200320032903f0043703d0044101212b200341013a00f004410110282202450d28200241013a0000200341d0046a41102002410110072002102a0c2a0b200141086a280200212a200141046a2802002123024020022d000120022d000072450d0041a39fc600210241112117410021224101212b202a450d422023102a0c420b2001410c6a2802002102200341f0046a41086a22174200370300200342003703f00441c8ffc4004115200341f0046a1008200341d0046a41086a2017290300370300200320032903f0043703d004200341003602f804200342013703f0042002200341f0046a10b40102402002450d00200241057421172023210203402002200341f0046a108f01200241206a2102201741606a22170d000b0b20032802f4042102200341d0046a411020032802f004221720032802f804100702402002450d002017102a0b4101212b202a450d282023102a0c280b410e41011037000b410e41011037000b410e41011037000b410d41011037000b410141011037000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b41c4d1c3004133200341e0026a419cd9c3001038000b202b41081037000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b200341c8016a200341b4056a290200370300200341c0016a200341ac056a290200370300200341b0016a41086a200341a4056a2902003703002003200329029c053703b001200342f3e885db96cddbb3203703e803200310980136028804200341d0046a200341b0016a109a0220032802d404211720032802d004210220032802d804212a200341e4046a200341e8036a36020020032002202a4105746a3602dc04200320023602d804200320173602d404200320023602d004200320034188046a3602e004200341a8046a200341d0046a108701200341d0046a41086a200341a8046a41086a280200360200200320032903a8043703d004200341b0016a200341d0046a109c02200341b0016a1095020c2e0b41c4d1c3004133200341e0026a419cd9c3001038000b411841081037000b200c41081037000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b411241011037000b41b7b3c0004192011050000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b412041011037000b411241011037000b41b7b3c0004192011050000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b41b581c5002102411021170c210b410d41011037000b410141011037000b410e41011037000b410e41011037000b410e41011037000b41c4d1c3004133200341e0026a419cd9c3001038000b410e41011037000b410141011037000b410141011037000b41002122410021020c180b41002102410121220c170b41a39fc6002102411121170c150b2022450d002024102a0b410221250b20254102460d01200341a8046a41186a221c200341f0046a41186a290300370300200341a8046a41106a221d200341f0046a41106a290300370300200341a8046a41086a221e200341f0046a41086a29030037030020034188046a41086a221f200341d0046a41086a222729030037030020034188046a41106a2220200341d0046a41106a220229030037030020034188046a41186a2221200341d0046a41186a221b290300370300200320032903f0043703a804200320032903d0043703880402402026450d002023102a0b201b201c2903003703002002201d2903003703002027201e290300370300200341e8036a41086a2223201f290300370300200341e8036a41106a22262020290300370300200341e8036a41186a221c2021290300370300200320032903a8043703d00420032003290388043703e803200320253a00f004200341f9046a202729030037000020034181056a200229030037000020034189056a201b290300370000200320032903d0043700f104200320173a00910520034192056a222520032903e8033701002003419a056a2023290300370100200341a2056a2026290300370100200341aa056a201c290300370100200220254100201741ff01714101461b3602002003202a3602dc042003202b3602d804200320223602d404200320243602d004200341003602b004200342013703a804202b200341a8046a10b401200341dc046a21230240202b450d00202b41057421172024210203402002200341a8046a108f01200241206a2102201741606a22170d000b0b2023200341a8046a10aa0120032802ac04210220034180036a412020032802a804221720032802b004100702402002450d002017102a0b02402022450d002024102a0b200341e8036a41186a22024200370300200341e8036a41106a22174200370300200341e8036a41086a222b4200370300200342003703e80341a7aec400411a200341e8036a1000200341f0046a41186a2002290300370300200341f0046a41106a2017290300370300200341f0046a41086a202b290300370300200320032903e8033703f004200341203602d4042003200341f0046a3602d004202a200341d0046a10ff0120034188046a41086a200341c8036a41086a29030037030020034188046a41106a200341c8036a41106a29030037030020034188046a41186a200341c8036a41186a290300370300200320032903c80337038804410121170b410021020c040b41c4d1c3004133200341e0026a419cd9c3001038000b202a450d002024102a0b410221020b20024102460d01200341d0046a41186a2223200341f0046a41186a290300370300200341d0046a41106a2225200341f0046a41106a290300370300200341d0046a41086a2226200341f0046a41086a290300370300200341a8046a41086a2227200341a0036a41086a221b290300370300200341a8046a41106a221c200341a0036a41106a221d290300370300200341a8046a41186a221e200341a0036a41186a221f290300370300200320032903f0043703d004200320032903a0033703a80402402022450d00202b102a0b201f2023290300370300201d2025290300370300201b202629030037030020034188046a41086a202729030037030020034188046a41106a201c29030037030020034188046a41186a201e290300370300200320032903d0043703a003200320032903a80437038804202a450d002024102a0b200341fd046a200341a0036a41086a29030037000020034185056a200341a0036a41106a2903003700002003418d056a200341a0036a41186a29030037000020034195056a20173a000020034196056a2003290388043701002003419e056a20034188046a41086a290300370100200341a6056a20034188046a41106a290300370100200341ae056a20034188046a41186a290300370100200320023a00f404200320032903a0033700f5042003200341a0016a3602f004200341003602d804200342013703d00420032802a001210220032802a8012217200341d0046a10b401200341f0046a410472212a02402017450d002017410574211703402002200341d0046a108f01200241206a2102201741606a22170d000b0b202a200341d0046a10a90120032802d4042102200341d0006a412020032802d004221720032802d804100702402002450d002017102a0b024020032802a401450d0020032802a001102a0b024020032802d401450d0020032802d001102a0b4100212b41012122410021020c0d0b41c4d1c3004133200341e0026a419cd9c3001038000b41dc9fc6002102410e21174100212b20032802d401212a0c020b1031000b201aa7212a41e881c5002102411721174101212b0b0240202a450d0020032802d001102a0b202b0d00410121224100212b0c080b410121224100212b201b450d07201c102a0c070b41c4d1c3004133200341e0026a419cd9c3001038000b41c4d1c3004133200341e0026a419cd9c3001038000b200328029405450d00200328029005102a410021020c010b410021020b4101212b410121220c020b4111211741a39fc60021020b4101212b410121220b0240024020012d0000222a410d4b0d004101202a7441be3f710d010240202a4106460d00202a410d470d012022450d02200141086a280200450d02200141046a280200102a0c020b202b450d01200141086a280200450d01200141046a280200102a0c010b200141086a280200450d00200141046a280200102a0b2000201736020420002002360200200341c0056a24000b990d02067f077e230041b0016b22052400024002400240024002400240411410282206450d00200641002900cfe140370000200641106a41002800dfe140360000200641086a41002900d7e14037000020054294808080c002370234200520063602302001200541306a108f012005280238210620052802302107200541c0006a41186a22084200370300200541c0006a41106a22094200370300200541c0006a41086a220a42003703002005420037034020072006200541c0006a1000200541106a41186a2008290300370300200541106a41106a2009290300370300200541106a41086a200a2903003703002005200529034037031002402005280234450d002005280230102a0b20054100360240200541106a4120200541c0006a100621060240024020052802402207417f470d004200210b4200210c0c010b20074110490d02200641086a290000210c2006290000210b2006102a0b411410282206450d02200641002900cfe140370000200641106a41002800dfe140360000200641086a41002900d7e14037000020054294808080c002370234200520063602302002200541306a108f012005280238210620052802302107200541c0006a41186a22084200370300200541c0006a41106a22094200370300200541c0006a41086a220a42003703002005420037034020072006200541c0006a1000200541106a41186a2008290300370300200541106a41106a2009290300370300200541106a41086a200a2903003703002005200529034037031002402005280234450d002005280230102a0b20054100360240200541106a4120200541c0006a100621060240024020052802402207417f470d004200210d4200210e0c010b20074110490d04200641086a290000210e2006290000210d2006102a0b024020034280a094a58d1d7c220f200354220620042006ad7c2210200454200f20035a1b450d0041f092c1002106412821010c060b0240200b200f7d2211200b56200c20107d200b200f54ad7d220f200c56200f200c511b4101470d00419893c1002106411d21010c060b0240200342ffffe883b1de165620044200522004501b0d00200d200e8450450d0041e293c1002106411f21010c060b200541086a200141022011200f10bc01024020052802082206450d00200528020c21010c060b0240200d20037c220c200d542206200e20047c2006ad7c220b200e54200b200e511b450d0041b593c1002106412d21010c060b41002106024020012002470d000c060b0240200120024120109c050d000c060b20012011200f108f02411410282206450d04200641002900cfe140370000200641106a41002800dfe140360000200641086a41002900d7e14037000020054294808080c002370234200520063602302002200541306a108f012005280238210620052802302107200541c0006a41186a22084200370300200541c0006a41106a22094200370300200541c0006a41086a220a42003703002005420037034020072006200541c0006a1000200541106a41186a2008290300370300200541106a41106a2009290300370300200541106a41086a200a2903003703002005200529034037031002402005280234450d002005280230102a0b0240200541106a41204101410041001003417f470d002002109302200541f8006a200b370300200541f0006a200c370300200541c0006a41086a41003a0000200541c9006a2002290000370000200541d1006a200241086a290000370000200541d9006a200241106a290000370000200541e1006a200241186a290000370000200541023a004041014100200541c0006a10cc010b2002200c200b108f022005420037034820054280a094a58d1d3703402005200541c0006a360210200541106a109d01200541a8016a4200370300200541a0016a4280a094a58d1d37030020054198016a200437030020054190016a2003370300200541c0006a41086a41023a0000200541c9006a2001290000370000200541d1006a200141086a290000370000200541d9006a200141106a290000370000200541e1006a200141186a290000370000200541e9006a2002290000370000200541f1006a200241086a290000370000200541f9006a200241106a29000037000020054181016a200241186a290000370000200541023a00404100210641014100200541c0006a10cc010c050b411441011037000b41c4d1c3004133200541c0006a419cd9c3001038000b411441011037000b41c4d1c3004133200541c0006a419cd9c3001038000b411441011037000b2000200136020420002006360200200541b0016a24000b881201097f230041f0026b22032400024002400240024002400240024002400240411410282204450d00200441002900cfe140370000200441106a41002800dfe140360000200441086a41002900d7e14037000020034294808080c002370294012003200436029001200020034190016a108f0120032802980121042003280290012105200341206a41186a22064200370300200341206a41106a22074200370300200341206a41086a220842003703002003420037032020052004200341206a100020034180026a41186a200629030037030020034180026a41106a200729030037030020034180026a41086a200829030037030020032003290320370380020240200328029401450d00200328029001102a0b200320013703202003200237032820034180026a4120200341206a41101007200142ffffe883b1de165620024200522002501b0d06411410282204450d01200441002900cfe140370000200441106a41002800dfe140360000200441086a41002900d7e14037000020034294808080c002370294012003200436029001200020034190016a108f0120032802980121042003280290012105200341206a41186a22064200370300200341206a41106a22074200370300200341206a41086a220842003703002003420037032020052004200341206a100020034180026a41186a200629030037030020034180026a41106a200729030037030020034180026a41086a200829030037030020032003290320370380020240200328029401450d00200328029001102a0b200341086a20034180026a109402200341086a41106a29030021022003290310210120032802082109410e10282204450d02200441002900fbe140370000200441066a4100290081e2403700002003428e808080e001370294012003200436029001200020034190016a108f0120032802980121042003280290012105200341206a41186a22064200370300200341206a41106a22074200370300200341206a41086a220842003703002003420037032020052004200341206a100020034180026a41186a200629030037030020034180026a41106a200729030037030020034180026a41086a200829030037030020032003290320370380020240200328029401450d00200328029001102a0b20034180026a4120100902402001200284500d002009450d0020032001370320200320023703282003200341206a3602800220034180026a109d010b2000109502411710282204450d03200441002900f1d8433700002004410f6a4100290080d943370000200441086a41002900f9d84337000020034297808080f002370294012003200436029001200020034190016a108f0120032802980121042003280290012105200341206a41186a22064200370300200341206a41106a22074200370300200341206a41086a220842003703002003420037032020052004200341206a100020034180026a41186a200629030037030020034180026a41106a200729030037030020034180026a41086a200829030037030020032003290320370380020240200328029401450d00200328029001102a0b200341206a20034180026a109602024020032d002022044102460d0020034180026a412010090b2003413c6a2802002106200341386a2802002105024020040d002005200341c0006a28020010042006450d060c050b20044103710d0520060d040c050b411441011037000b411441011037000b410e41011037000b411741011037000b2005102a0b200341f0016a2000108b0220032802f001210420032802f8012105410021062003410036022020042005200341206a10062108024002400240024020032802202207417f460d00200320073602e402200320083602e002200341206a200341e0026a10e80120032d00204101460d0120034180026a200341206a41017241e000109a051a02402007450d002008102a0b200341206a20034180026a41e000109a051a200420051009410121060b20034190016a200341206a41e000109a051a200341206a20034190016a41e000109a051a2006450d0120034180026a200341206a41e000109a051a024020032802f401450d002004102a0b200341206a20034180026a41e000109a051a200341c0006a210a200341e0006a210b4104210641e7e485f30621040340200b210702400240200441e9dabdf306460d000240200441e7e485f306470d00200341206a21070c010b200a2107200441e2c289ab06460d00410121084100210541012107410121090c010b41202105410021084120102822090d00412041011037000b200920072005109a0521072003200536029c01200320053602980120032007360294012003200436029001200341f0016a20034190016a108c0220032802f001220420032802f8011009024020032802f401450d002004102a0b024020080d002007102a0b2006410c460d03200641f8c8c0006a2800002104200641046a21060c000b0b41c4d1c3004133200341e8026a419cd9c3001038000b20032802f401450d002004102a0b411810282204450d01200441002900e3e140370000200441106a41002900f3e140370000200441086a41002900ebe140370000200342988080808003370294012003200436029001200020034190016a108f0120032802980121042003280290012105200341206a41186a22064200370300200341206a41106a22074200370300200341206a41086a220842003703002003420037032020052004200341206a100020034180026a41186a200629030037030020034180026a41106a200729030037030020034180026a41086a200829030037030020032003290320370380020240200328029401450d00200328029001102a0b2003410036022020034180026a4120200341206a10062104024020032802202205417f460d0020054110490d03200441086a2900002102200429000021012004102a200120028450450d010b2000109702200341206a41086a41013a0000200341296a2000290000370000200341316a200041086a290000370000200341396a200041106a290000370000200341c1006a200041186a290000370000200341023a002041014100200341206a10cc010b200341f0026a24000f0b411841011037000b41c4d1c3004133200341e8026a419cd9c3001038000bd40801067f230041c0016b220324000240024002400240411810282204450d00200441002900e3e140370000200441106a41002900f3e140370000200441086a41002900ebe140370000200342988080808003370244200320043602402000200341c0006a108f012003280248210420032802402105200341d0006a41186a22064200370300200341d0006a41106a22074200370300200341d0006a41086a220842003703002003420037035020052004200341d0006a1000200341206a41186a2006290300370300200341206a41106a2007290300370300200341206a41086a20082903003703002003200329035037032002402003280244450d002003280240102a0b2003200137035020032002370358200341206a4120200341d0006a411010070240200142ffffe883b1de165620024200522002501b0d00411810282204450d02200441002900e3e140370000200441106a41002900f3e140370000200441086a41002900ebe140370000200342988080808003370244200320043602402000200341c0006a108f012003280248210420032802402105200341d0006a41186a22064200370300200341d0006a41106a22074200370300200341d0006a41086a220842003703002003420037035020052004200341d0006a1000200341206a41186a2006290300370300200341206a41106a2007290300370300200341206a41086a20082903003703002003200329035037032002402003280244450d002003280240102a0b200341086a200341206a109402024020032903102202200341086a41106a290300220184500d002003280208450d0020032002370350200320013703582003200341d0006a360220200341206a109d010b411410282204450d03200441002900cfe140370000200441106a41002800dfe140360000200441086a41002900d7e14037000020034294808080c002370244200320043602402000200341c0006a108f012003280248210420032802402105200341d0006a41186a22064200370300200341d0006a41106a22074200370300200341d0006a41086a220842003703002003420037035020052004200341d0006a1000200341206a41186a2006290300370300200341206a41106a2007290300370300200341206a41086a20082903003703002003200329035037032002402003280244450d002003280240102a0b20034100360250200341206a4120200341d0006a10062104024020032802502205417f460d0020054110490d05200441086a2900002102200429000021012004102a200120028450450d010b2000109702200341d0006a41086a41013a0000200341d9006a2000290000370000200341e1006a200041086a290000370000200341e9006a200041106a290000370000200341f1006a200041186a290000370000200341023a005041014100200341d0006a10cc010b200341c0016a24000f0b411841011037000b411841011037000b411441011037000b41c4d1c3004133200341d0006a419cd9c3001038000b4d01017f230041206b22002400200041146a410136020020004201370204200041ccd1c5003602002000410436021c200041c4d1c5003602182000200041186a360210200041e8b5c300103e000bb30701057f230041106b2203240020034100360208200342013703002002200310b40102400240024002400240024002402002450d00200241c4006c210403400240024020012d00004101460d0002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0a200241017422062005200620054b1b22064100480d0a0240024020020d002006102821050c010b200328020020022006102c21050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a0000200141046a28020021060240024020032802042205200328020822026b4104490d00200328020021050c010b200241046a22072002490d0a200541017422022007200220074b1b22024100480d0a0240024020050d002002102821050c010b200328020020052002102c21050b2005450d062003200236020420032005360200200328020821020b2003200241046a360208200520026a20063600000c010b02400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d09200241017422062005200620054b1b22064100480d090240024020020d002006102821050c010b200328020020022006102c21050b2005450d062003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a00002003200336020c200141016a2003410c6a10c8010240200141216a2d00004101460d0002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0a200241017422062005200620054b1b22064100480d0a0240024020020d002006102821050c010b200328020020022006102c21050b2005450d082003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a00000c010b02400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d09200241017422062005200620054b1b22064100480d090240024020020d002006102821050c010b200328020020022006102c21050b2005450d082003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a0000200141226a2003108f010b200141c4006a2101200441bc7f6a22040d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b200641011037000b200241011037000b200641011037000b200641011037000b200641011037000b1031000bcc0b03057f037e047f230041a0016b22012400200141306a41086a220242003703002001420037033041f5b8c3004113200141306a1008200141206a41086a2002290300370300200120012903303703204100210220014100360230200141206a4110200141306a100621030240024002400240024002400240024002400240024020012802302204417f460d002003450d0020044104490d01200328000021022003102a0b410110282203450d01200320002d00003a0000200341014102102c2203450d02200320002d00013a0001200341024104102c2203450d03200320002d00023a0002200320002d00033a0003200341044108102c2203450d04200320002d00043a0004200320002d00053a0005200320002d00063a0006200320002d00073a0007200341084110102c2203450d05200320002d00083a0008200320002d00093a0009200320002d000a3a000a200320002d000b3a000b200320002d000c3a000c200320002d000d3a000d200320002d000e3a000e200320002d000f3a000f200341104120102c2203450d06200320002d00103a0010200320002d00113a0011200320002d00123a0012200320002d00133a0013200320002d00143a0014200320002d00153a0015200320002d00163a0016200320002d00173a0017200320002d00183a0018200320002d00193a0019200320002d001a3a001a200320002d001b3a001b200320002d001c3a001c200320002d001d3a001d200320002d001e3a001e200320002d001f3a001f20032d0000210420032d000121052003102a200141206a2004200541087472410676220510fe0102402004413f71220320012802284f0d002001200128022020034105746a2203109d022001290300200141086a290300844200520d00200041086a2900002106200041106a2900002107200041186a290000210820032000290000370000200341186a2008370000200341106a2007370000200341086a2006370000200141306a41086a200141206a41086a280200360200200120012903203703302005200141306a10c5030c0a0b02402001280224450d002001280220102a0b200141306a200210fe010240200128023841c000490d000340200241016a210202402001280234450d002001280230102a0b200141306a200210fe012001280238413f4b0d000b0b200141106a41086a200141306a41086a2205280200220336020020012001290330370310200141306a41186a2209200041186a290000370300200141306a41106a220a200041106a2900003703002005200041086a29000037030020012000290000370330024020032001280214470d00200341016a22042003490d092003410174220b2004200b20044b1b220441ffffff3f712004470d092004410574220c4100480d090240024020030d00200c1028210b0c010b20012802102003410574200c102c210b0b200b450d08200120043602142001200b3602100b200320024106746a210b200128021020034105746a22042001290330370000200441086a2005290300370000200441106a200a290300370000200441186a20092903003700002001200341016a22033602180240200341c000470d00200141306a41086a220342003703002001420037033041f5b8c3004113200141306a1008200141206a41086a2003290300370300200120012903303703202001200241016a360230200141206a4110200141306a410410070b200141306a41086a2203200141106a41086a280200360200200120012903103703302002200141306a10c50320032000290000370300200141306a41106a200041086a290000370300200141306a41186a200041106a290000370300200141d0006a200041186a2900003703002001200b360234200141013a003041014100200141306a10cc010c090b41c4d1c3004133200141306a419cd9c3001038000b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000b200c41011037000b1031000b200141a0016a24000b980102037f037e230041106b220224002002410036020420014120200241046a1006210302400240024020022802042204417f470d00420021050c010b20044110490d01200341086a2900002106200329000021072003102a200141201009420121050b2000200537030020002007370308200041106a2006370300200241106a24000f0b41c4d1c3004133200241086a419cd9c3001038000ba00803067f047e027f230041b0016b22012400024002400240410e10282202450d00200241002900fcae44370000200241066a4100290082af443700002001428e808080e00137026c200120023602682000200141e8006a108f01200128027021022001280268210320014188016a41186a2204420037030020014188016a41106a2205420037030020014188016a41086a2206420037030020014200370388012003200220014188016a1000200141286a41186a2004290300370300200141286a41106a2005290300370300200141286a41086a200629030037030020012001290388013703280240200128026c450d002001280268102a0b20014188016a200141286a412010fd01024020012d00880141014722020d00200141286a412010090b200141c8006a41186a2203200141a1016a2900002207370300200141c8006a41106a220420014199016a2900002208370300200141c8006a41086a220520014191016a29000022093703002001200129008901220a370348200141e8006a41186a22062007370300200141e8006a41106a220b2008370300200141e8006a41086a220c20093703002001200a370368024020020d00200141086a41186a20062903002207370300200141086a41106a200b2903002208370300200141086a41086a200c290300220937030020012001290368220a3703082003200737030020042008370300200520093703002001200a370348410e10282202450d022002410029008aaf44370000200241066a4100290090af443700002001428e808080e00137022c20012002360228200141c8006a200141286a108f01200128023021022001280228210320014188016a41186a2204420037030020014188016a41106a2205420037030020014188016a41086a2206420037030020014200370388012003200220014188016a1000200141e8006a41186a2004290300370300200141e8006a41106a2005290300370300200141e8006a41086a200629030037030020012001290388013703680240200128022c450d002001280228102a0b200141e8006a412010090b410d10282202450d0220024100290098af44370000200241056a410029009daf443700002001428d808080d00137024c200120023602482000200141c8006a108f01200128025021022001280248210320014188016a41186a2204420037030020014188016a41106a2205420037030020014188016a41086a2206420037030020014200370388012003200220014188016a1000200141e8006a41186a2004290300370300200141e8006a41106a2005290300370300200141e8006a41086a200629030037030020012001290388013703680240200128024c450d002001280248102a0b200141e8006a41201009200010a604200010a704200141b0016a24000f0b410e41011037000b410e41011037000b410d41011037000bd00a050a7f027e037f027e017f230041e0006b220224002002410036023820014120200241386a1006210302400240024002400240024002400240024020022802382204417f460d0020030d010b200041023a00000c010b2002200436021c200220033602182004450d0520032d0000210120022004417f6a36021c2002200341016a360218200141014b0d0502400240024020010e020001000b200241086a200241186a106c20022802080d07200228021c200228020c2205490d072005417f4c0d030240024020050d0041012106200228021c21070c010b2005102e2206450d092006200228021822012005109a051a200228021c22042005490d052002200420056b220736021c2002200120056a3602180b20074104490d0520022802182208280000210920022007417c6a220a36021c2002200841046a36021841002101200241003a0058417b210b03400240200a2001470d000240200141ff0171450d00200241003a00580b20050d080c090b200241386a20016a200820016a220441046a2d00003a000020022007200b6a36021c2002200441056a3602182002200141016a22043a0058200b417f6a210b2004210120044120470d000b200220022802383602302002200228003b3600330240024002400240200720046b220b417c6a4110490d00200241c7006a290000210c200229003f210d20022d0057210a2002280053210e200228004f210f2002200820046a220141146a22083602182002200b416c6a221036021c20104104490d002001410c6a2900002111200141046a2900002112200828000021082002200b41686a36021c2002200141186a2210360218200741686a2004460d0320102d000021102002200b41676a221336021c2002200141196a360218201041014b0d034100210420100e020201020b20050d090c0a0b20134104490d01200141196a28000021072002200b41636a36021c20022001411d6a360218410121040b2002200228003336002b20022002280230360228200220022802283602382002200228002b36003b200220022800203602102002200241236a280000360013410021012005210b0c020b2005450d070c060b41002101200241003a00582004417f6a21072004417e6a21040340024020072001470d00200141ff0171450d08200241003a00580c080b200241386a20016a200320016a220b41016a2d00003a00002002200b41026a3602182002200141016a220b3a00582002200436021c2004417f6a2104200b2101200b4120470d000b2002200228003b360033200220022802383602302002200228003336002b20022002280230360228200220022802283602102002200228002b360013200241c7006a2900002111200229003f2112200228004f21062002280053210b20022d005721052002200241236a28000036003b20022002280020360238410121010b2002200228021036023020022002280013360033200220022802383602282002200228003b36002b2003102a200041106a2011370300200041086a2012370300200041c3006a200c3700002000413b6a200d370000200020013a0000200041306a20073602002000412c6a2004360200200041286a2008360200200041246a2009360200200041206a20053602002000411c6a200b360200200041186a2006360200200041d3006a200a3a0000200041cf006a200e360000200041cb006a200f36000020002002280230360001200041046a2002280033360000200041346a2002280228360200200041376a200228002b3600000b200241e0006a24000f0b1036000b200520041044000b2005450d010b2006102a0b41c4d1c3004133200241206a419cd9c3001038000b200541011037000b870201057f230041d0006b220124000240411310282202450d00200241002900cef0423700002002410f6a41002800ddf042360000200241086a41002900d6f04237000020014293808080b002370224200120023602202000200141206a108f012001280228210220012802202100200141306a41186a22034200370300200141306a41106a22044200370300200141306a41086a220542003703002001420037033020002002200141306a1000200141186a2003290300370300200141106a2004290300370300200141086a20052903003703002001200129033037030002402001280224450d002001280220102a0b200141201009200141d0006a24000f0b411341011037000bd10402067f037e230041e0006b22052400024002400240411410282206450d00200641002900cfe140370000200641106a41002800dfe140360000200641086a41002900d7e14037000020054294808080c002370234200520063602302001200541306a108f012005280238210620052802302107200541c0006a41186a22084200370300200541c0006a41106a22094200370300200541c0006a41086a220a42003703002005420037034020072006200541c0006a1000200541106a41186a2008290300370300200541106a41106a2009290300370300200541106a41086a200a2903003703002005200529034037031002402005280234450d002005280230102a0b20054100360240200541106a4120200541c0006a100621060240024020052802402207417f470d004200210b4200210c0c010b20074110490d02200641086a290000210c2006290000210b2006102a0b410121060240200b20027d220d200b56200c20037d200b200254ad7d220b200c56200b200c511b4101470d00200041d7dfc000360204200041086a411d3602000c030b024002400240200d428080e983b1de16544100200b501b0d00200541086a20012004200d200b10bc0120052802082206450d02200528020c210120002006360204200041086a20013602000c010b200041f4dfc000360204200041086a411a3602000b410121060c030b2001200d200b108f02200041106a2003370300200041086a2002370300410021060c020b411441011037000b41c4d1c3004133200541c0006a419cd9c3001038000b20002006360200200541e0006a24000bdb0702067f087e23004180016b22022400024002400240411010282203450d0020034100290089e240370000200341086a4100290091e240370000200242908080808002370254200220033602502001200241d0006a108f012002280258210320022802502104200241e0006a41186a22054200370300200241e0006a41106a22064200370300200241e0006a41086a220742003703002002420037036020042003200241e0006a1000200241306a41186a2005290300370300200241306a41106a2006290300370300200241306a41086a20072903003703002002200229036037033002402002280254450d002002280250102a0b20024100360260200241306a4120200241e0006a1006210302400240024020022802602204417f460d002003450d00024020044110490d0020044170714110460d002004417c714120470d020b41c4d1c3004133200241e0006a419cd9c3001038000b42002108420021090c010b200341086a290000210a2003290000210b200341186a290000210c20032900102108200328002021042003102a411410282203450d02200341002900cfe140370000200341106a41002800dfe140360000200341086a41002900d7e14037000020024294808080c002370254200220033602502001200241d0006a108f012002280258210320022802502101200241e0006a41186a22054200370300200241e0006a41106a22064200370300200241e0006a41086a220742003703002002420037036020012003200241e0006a1000200241306a41186a2005290300370300200241306a41106a2006290300370300200241306a41086a20072903003703002002200229036037033002402002280254450d002002280250102a0b20024100360260200241306a4120200241e0006a100621030240024020022802602201417f470d004200210d420021090c010b20014110490d04200341086a29000021092003290000210d2003102a0b4200210e200241106a200c42004100109801220320046b2201200120034b1bad220f4200109f05200241206a200f420020084200109f0520024200420020084200109f054200210802402002290308200229031884420052200241286a290300220f200229030020022903107c7c220c200f54720d00200a200c200b2002290320220e56200a200c56200a200c511b22031b200c7d200b200e20031b220c200e54ad7d2108200c200e7d210e0b20082009200d200e56200920085620092008511b22031b2109200e200d20031b21080b200020083703002000200937030820024180016a24000f0b411041011037000b411441011037000b41c4d1c3004133200241e0006a419cd9c3001038000baf07030b7f037e037f230041f0006b22022400024002400240024002400240410e10282203450d00200341002900fbe140370000200341066a4100290081e2403700002002428e808080e001370234200220033602302001200241306a108f012002280238210320022802302101200241c0006a41186a22044200370300200241c0006a41106a22054200370300200241c0006a41086a220642003703002002420037034020012003200241c0006a1000200241106a41186a2004290300370300200241106a41106a2005290300370300200241106a41086a20062903003703002002200229034037031002402002280234450d002002280230102a0b20024100360240200241106a4120200241c0006a100621070240024020022802402208417f460d002002200836023420022007360230200241086a200241306a106c20022802080d07200228023422034160712201417f4c0d03200228020c2109024002402003410576220a0d004108210b0c010b20011028220b450d050b02402009450d004100210c41002106410021050340200241c0006a200241306a109b020240024020022d00404101460d00200228023422014110490d002002290041210d20022002280230220341106a3602302002200141706a220436023420044104490d00200341086a290000210e2003290000210f20022001416c6a22043602342002200341146a36023020040d010b200a450d0a200b102a0c0a0b200541016a210420032800102110200241e6006a41026a200241ed006a41026a2d000022113a0000200241e2006a41026a221220113a000020022001416b6a3602342002200341156a360230200220022f006d22013b0166200220013b016220032d0014210102402005200a470d00200c2004200c20044b1b220a41ffffff3f71200a470d09200a41057422034100480d090240024020050d0020031028210b0c010b200b20062003102c210b0b200b450d080b200b20066a2203411c6a20013a00002003200e3703082003200f370300200341146a200d370200200341106a20103602002003411d6a20022f01623b00002003411f6a20122d00003a0000200c41026a210c200641206a21062004210520092004470d000b0b200b450d072009ad422086200aad84210d02402008450d002007102a0b2000200d3702042000200b3602000c010b20004100360208200042083702000b200241f0006a24000f0b410e41011037000b1036000b200141081037000b200341081037000b1031000b41c4d1c3004133200241c0006a419cd9c3001038000bf00204027f017e017f077e0240024020012802042202450d0020012802002203310000210420012002417f6a22053602042001200341016a3602002005450d012003310001210620012002417e6a22053602042001200341026a3602002005450d012003310002210720012002417d6a22053602042001200341036a3602002005450d012003310003210820012002417c6a22053602042001200341046a3602002005450d012003310004210920012002417b6a22053602042001200341056a3602002005450d012003310005210a20012002417a6a22053602042001200341066a3602002005450d012003310006210b2001200241796a22053602042001200341076a3602002005450d01200041003a00002003310007210c2001200241786a3602042001200341086a3602002000200c423886200b42308684200a422886842009422086842008421886842007421086842006420886842004843700010f0b200041013a00000f0b200041013a00000bce1003077f027e027f230041d0006b220224000240024002400240024002400240024002400240024002400240410e10282203450d00200341002900fbe140370000200341066a4100290081e2403700002002428e808080e001370224200220033602202000200241206a108f012002280228210320022802202100200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020002003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b200128020021072001280208210320024100360238200242013703302003200241306a10b40102402003450d002003410574210841002106034002400240200228023420022802382203460d00200228023021000c010b200341016a22002003490d0f200341017422042000200420004b1b22044100480d0f0240024020030d002004102821000c010b200228023020032004102c21000b2000450d042002200436023420022000360230200228023821030b2002200341016a360238200020036a200720066a220341146a2d00003a000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d052002200536023420022004360230200228023821000b2002200041016a360238200420006a200341156a2d00003a000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d062002200536023420022004360230200228023821000b2002200041016a360238200420006a200341166a2d00003a000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d072002200536023420022004360230200228023821000b2002200041016a360238200420006a200341176a2d00003a000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d082002200536023420022004360230200228023821000b2002200041016a360238200420006a200341186a2d00003a000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d092002200536023420022004360230200228023821000b2002200041016a360238200420006a200341196a2d00003a000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d0a2002200536023420022004360230200228023821000b2002200041016a360238200420006a2003411a6a2d00003a000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d0b2002200536023420022004360230200228023821000b2002200041016a360238200420006a2003411b6a2d00003a0000200341086a29030021092003290300210a0240024020022802342205200228023822046b4110490d00200228023021000c010b200441106a22002004490d0f200541017422042000200420004b1b220b4100480d0f0240024020050d00200b102821000c010b20022802302005200b102c21000b2000450d0c2002200b3602342002200036023020022802382104200b21050b200020046a220b2009370008200b200a3700002002200441106a2204360238200341106a280200210b0240200520046b41034b0d00200441046a220c2004490d0f20054101742204200c2004200c4b1b22044100480d0f0240024020050d002004102821000c010b200020052004102c21000b2000450d0d2002200436023420022000360230200228023821040b2002200441046a360238200020046a200b36000002400240200228023420022802382200460d00200228023021040c010b200041016a22042000490d0f200041017422052004200520044b1b22054100480d0f0240024020000d002005102821040c010b200228023020002005102c21040b2004450d0e2002200536023420022004360230200228023821000b2002200041016a360238200420006a2003411c6a2d00003a00002008200641206a2206470d000b0b2002280234210320024120200228023022002002280238100702402003450d002000102a0b0240200141046a280200450d002007102a0b200241d0006a24000f0b410e41011037000b200441011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200b41011037000b200441011037000b200541011037000b1031000bd00502067f047e230041d0006b220224000240024002400240411410282203450d00200341002900cfe140370000200341106a41002800dfe140360000200341086a41002900d7e14037000020024294808080c002370224200220033602202001200241206a108f012002280228210320022802202104200241306a41186a22054200370300200241306a41106a22064200370300200241306a41086a220742003703002002420037033020042003200241306a1000200241186a2005290300370300200241106a2006290300370300200241086a20072903003703002002200229033037030002402002280224450d002002280220102a0b2002410036023020024120200241306a100621030240024020022802302204417f470d0042002108420021090c010b20044110490d02200341086a2900002109200329000021082003102a0b411810282203450d02200341002900e3e140370000200341106a41002900f3e140370000200341086a41002900ebe140370000200242988080808003370224200220033602202001200241206a108f012002280228210320022802202101200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020012003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b2002410036023020024120200241306a100621030240024020022802302201417f470d004200210a4200210b0c010b20014110490d04200341086a290000210b2003290000210a2003102a0b2000200a20087c22083703002000200b20097c2008200a54ad7c370308200241d0006a24000f0b411441011037000b41c4d1c3004133200241306a419cd9c3001038000b411841011037000b41c4d1c3004133200241306a419cd9c3001038000bf00906017f037e017f017e017f037e230041c0016b220724004200210842002109024020050d00200741f0006a2006ad42004280c8afa0254200109f05200741f8006a2903002007290370220a4280a094a58d1d7c2208200a54ad7c21090b20074180016a41086a22054200370300200742003703800141bfa0c600411b20074180016a1008200741a0016a41086a220b200529030037030020072007290380013703a001200741e0006a200741a0016a109f02200728026021052007290368210a2007418094ebdc03360284012007200a420020051b220a200a423f87220c7c200c85220c200c428094ebdc037f220c4280ec94a37c7e7ca7220536028001200741d0006a417f2004418094ebdc032004418094ebdc03491b2204417f417f2004ad200ca7417f200c428080808010541bad7e220ca7200c422088a71b220620074180016a2005418094ebdc034b4102746a28020022052004418094ebdc036e220d6c2005ad2004200d4180ec94a37c6c6aad7e428094ebdc0380a76a6a220520052006491b22056a220620062004491b4100200420056b2205200520044b1b200a4200551bad420042e8074200109f0520074180016a2003427f200820072903507c220a20017c220c200c200a5422042009200741d0006a41086a2903007c200a200854ad7c220820027c2004ad7c220a200854200a2008511b22041b220e427f200a20041b220f4101109802024002402007280280014101470d0020004180023b0001200041013a0000200041036a41003a00000c010b200741206a2007290388012209420042044200109f05200741106a4200420020094200109f05200741306a2007290320200741206a41086a290300220820074180016a41106a290300220a42028620072903107c7c220c4205420010a00520072903182101200741306a41086a29030021022007290330211020074180016a10d301200741c0006a20074180016a42b3e6cc99b3e6cc99332010200a200a42ffffffffffffffff3f8352200142005272200c2008547222041b22082009200820095442b3e6cc99b3e6cc9933200220041b220c200a54200c200a511b22041b2208200c200a20041b220c10d001200741a0016a41106a200c200741c0006a41086a29030022027d20082007290340220154ad7d2002200c7d2001200854ad7d20012008582002200c582002200c5122041b22051b3703002007200820017d200120087d20051b3703a801200720012008562002200c5620041b2204ad3703a001200a200c7d2009200854ad7d210a200920087d21080240024020040d002007200b3602bc01200741bc016a109d010c010b2007200b3602bc01200741bc016a109c010b20074180016a10f801200720074180016a2008200a10d001200741b0016a200a200741086a29030022097d20082007290300220c54ad7d2009200a7d200c200854ad7d200c2008582009200a582009200a5122041b22051b37030020072008200c7d200c20087d20051b3703a8012007200c2008562009200a5620041b2204ad3703a001200741a0016a41086a21050240024020040d00200720053602bc01200741bc016a109d010c010b200720053602bc01200741bc016a109c010b200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a200e427f200f501b370300200041003a00000b200741c0016a24000b820102027f027e230041106b220224002002410036020420014110200241046a100621010240024020022802042203417f460d002001450d00024020034108490d00200129000021042001102a420121050c020b41c4d1c3004133200241086a419cd9c3001038000b420021050b2000200437030820002005370300200241106a24000b1300200041033602042000419ce2c0003602000bc70104017f017e027f017e230041206b2201240042002102200141106a41086a220342003703002001420037031041ace1c0004116200141106a1008200141086a2003290300370300200120012903103703002001410036021020014110200141106a1006210302400240024020012802102204417f470d00420021050c010b20044110490d01200341086a2900002105200329000021022003102a0b2000200237030020002005370308200141206a24000f0b41c4d1c3004133200141106a419cd9c3001038000b3400200041b2f3c00036020420004100360200200041146a4105360200200041106a41bcf3c000360200200041086a42083702000b3701017f02404110102822020d00411041011037000b2002420037000820024200370000200042908080808002370204200020023602000b130020004105360204200041d884c1003602000be70302067f037e230041e0006b2204240020042001109d0202400240024002402004290300200441086a29030084500d00411410282205450d02200541002900cfe140370000200541106a41002800dfe140360000200541086a41002900d7e14037000020044294808080c002370234200420053602302001200441306a108f012004280238210520042802302106200441c0006a41186a22074200370300200441c0006a41106a22084200370300200441c0006a41086a220942003703002004420037034020062005200441c0006a1000200441106a41186a2007290300370300200441106a41106a2008290300370300200441106a41086a20092903003703002004200429034037031002402004280234450d002004280230102a0b20044100360240200441106a4120200441c0006a100621050240024020042802402206417f470d004200210a4200210b0c010b20064110490d04200541086a290000210b2005290000210a2005102a0b2001200a20027c220c200b20037c200c200a54ad7c108f02200041106a2003370300200041086a2002370300410021010c010b200041b5dfc000360204200041086a4122360200410121010b20002001360200200441e0006a24000f0b411441011037000b41c4d1c3004133200441c0006a419cd9c3001038000b130020004101360204200041f88ac1003602000b3400200041b18cc10036020420004100360200200041146a4103360200200041106a41bc8cc100360200200041086a42083702000bef0a09037f017e067f037e017f027e077f017e017f230041306b2203240010980121042000280000210520003500042106200341106a2001109a02200328021021072003280214210802400240024002400240024002400240024020032802182209450d0020072009410574220a6a210b200341246a210c200721090340200941086a290300210d200941106a290300210e2009290300210f200341106a41186a200941186a290300370300200341106a41106a200e370300200341106a41086a200d3703002003200f370310200c2000460d02200c2900002000290000510d0202402003280220221020044d0d002003410e6a2003412f6a2d00003a0000200320032f002d3b010c200341186a290300210f427f210e200329031021114201210d20032d002c210c200329022421120c040b200941206a2109200a41606a220a0d000b0b41082113410021102008450d022007102a0c020b2003280220220c2002200c20024b1b211020032d002c410272210c427f21114200210e41002102200329022421124200210d41002105427f210f0b200341026a22142003410c6a41026a2d00003a0000200320032f010c3b010002400240412010282213450d00201320113703002013200c3a001c2013201237021420132010360210201320032f01003b001d2013200f3703082013411f6a20142d00003a000002400240200a4120470d0041012110200e210f410121140c010b200941206a2115200b41606a21162003412d6a2117200341246a210c200e210f4101211041012114034020152109024002400340200341106a41186a200941186a290300370300200341106a41106a200941106a290300370300200341106a41086a220a200941086a2903003703002003200929030037031002400240200c2000460d00200c2900002000290000510d002003280220221820044d0d012003410c6a41026a201741026a2d00003a0000200320172f00003b010c200a29030021112003290310211220032d002c21192003290224211a0c040b200d4201510d024200210e410021024200210f4200210d410021050b200b200941206a2209470d000c040b0b200a290300220d200f20032903102212200e56200d200f56200d200f511b220a1b21112012200e200a1b21122003280220220a2002200a20024b1b211820032d002c41027221194200210e410021022003290224211a4200210f4200210d410021050b200341046a41026a2003410c6a41026a2d0000220a3a0000200320032f010c22153b0104200341106a41026a221b200a3a0000200320153b0110024020142010470d00201041016a220a2010490d0a20104101742214200a2014200a4b1b221441ffffff3f712014470d0a2014410574220a4100480d0a0240024020100d00200a102821130c010b20132010410574200a102c21130b2013450d040b200941206a2115201320104105746a220a20193a001c200a2011370308200a2012370300200a201a370214200a2018360210200a20032f01103b001d200a411f6a201b2d00003a0000201041016a211020162009470d000b0b02402008450d002007102a0b200d4201520d0520102014470d040c030b412041081037000b200a41081037000b427f210e427f210f0b201041016a22092010490d03201041017422002009200020094b1b221441ffffff3f712014470d03201441057422094100480d030240024020100d002009102821130c010b201320104105742009102c21130b2013450d020b201320104105746a2209200f3703082009200e3703002009200536021420092002360210200941186a200642808080802084370300201041016a21100b2003201036021820032014360214200320133602102001200341106a109c02200341306a24000f0b200941081037000b1031000bef0a07037f027e047f087e017f047e027f230022062107200641c0006b41607122062400109801210820062003370310200620023703082006200436021842012109200642013703002006200028000036021c20003500042102200641206a2001109a0220022005ad42ff018342208684210a2006280220210b2006280224210c0240024002400240024020062802282205450d00200b200541057422046a210d200641346a210e2006290300220921032006290308220f2110200629031022112112200629031822132114200b21050340200541086a2903002102200541106a290300211520052903002116200641206a41186a200541186a290300370300200641206a41106a22172015370300200641206a41086a20023703002006201637032002400240200e2000460d00200e2900002000290000510d000240200628023020084b0d0020032102420021030c020b20172903002118200629032821192006290320211a2006290338211b20032102420121030c010b420021094200210f420021114200211342002102200a211b2010211a20122119201421180b20034201510d02200541206a210520022103200441606a22040d000b200620093703002006200f37030820062011370310200620133703180b41002104200c450d01200b102a0c010b200620023703002006201037030820062012370310200620143703180240412010282217450d002017201b3703182017201a37030020172019370308201741106a201837030002400240024020044120470d0041012104200221094101211c0c010b200541206a2105200641346a211d20022109410121044101211c034002400240201d2000460d00200221030340200641206a41186a200541186a290300370300200641206a41106a220e200541106a290300370300200641206a41086a200541086a2903003703002006200529030037032002400240201d2900002000290000510d000240200628023020084b0d0020032102420021030c020b200e290300211b20062903282116200629032021152006290338211a20032102420121030c010b42002109200642003703004200210220102115201221162014211b200a211a0b024020034201510d0020022103200d200541206a2205470d010c050b0b200541206a21050c010b024003402006420037030020024201510d0142002102200d200541206a2205470d000b420021090c030b200541206a2105420021094200210220102115201221162014211b200a211a0b0240201c2004470d00200441016a220e2004490d072004410174221c200e201c200e4b1b221c41ffffff3f71201c470d07201c410574220e4100480d070240024020040d00200e102821170c010b20172004410574200e102c21170b2017450d030b201720044105746a220e2016370308200e2015370300200e41106a201b370300200e41186a201a370300200441016a21042005200d470d000b0b200c450d03200b102a0c030b200e41081037000b412041081037000b4100211c410821170b0240024020094201520d00200641206a41106a22002006410872220541106a290300370300200641206a41086a220e200541086a2903003703002006200529030037032002402004201c470d00200441016a22052004490d03200441017422082005200820054b1b221c41ffffff3f71201c470d03201c41057422054100480d030240024020040d002005102821170c010b201720044105742005102c21170b2017450d020b201720044105746a22052006290320370300200541106a2000290300370300200541086a200e290300370300200541186a200a370300200441016a21040b200620043602282006201c360224200620173602202001200641206a109c02200724000f0b200541081037000b1031000bff0502067f057e230041d0006b220324000240024002400240411810282204450d00200441002900e3e140370000200441106a41002900f3e140370000200441086a41002900ebe140370000200342988080808003370224200320043602202000200341206a108f012003280228210420032802202105200341306a41186a22064200370300200341306a41106a22074200370300200341306a41086a220842003703002003420037033020052004200341306a1000200341186a2006290300370300200341106a2007290300370300200341086a20082903003703002003200329033037030002402003280224450d002003280220102a0b2003410036023020034120200341306a100621040240024020032802302205417f470d00420021094200210a0c010b20054110490d02200441086a290000210a200429000021092004102a0b411410282204450d02200441002900cfe140370000200441106a41002800dfe140360000200441086a41002900d7e14037000020034294808080c002370224200320043602202000200341206a108f012003280228210420032802202105200341306a41186a22064200370300200341306a41106a22074200370300200341306a41086a220842003703002003420037033020052004200341306a1000200341186a2006290300370300200341106a2007290300370300200341086a20082903003703002003200329033037030002402003280224450d002003280220102a0b2003410036023020034120200341306a100621040240024020032802302205417f470d004200210b4200210c0c010b20054110490d04200441086a290000210c2004290000210b2004102a0b2000200b200120092009200156200a200256200a2002511b22041b22017c220d200c2002200a20041b22027c200d200b54ad7c108f022000200920017d200a20027d2009200154ad7d109002200341d0006a24000f0b411841011037000b41c4d1c3004133200341306a419cd9c3001038000b411441011037000b41c4d1c3004133200341306a419cd9c3001038000bc70301047f230041106b2203240020034100360208200342013703002001200310b40102400240024002402001450d00200141216c210403400240024020002d00004101460d0002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d07200141017422062005200620054b1b22064100480d070240024020010d002006102821050c010b200328020020012006102c21050b2005450d052003200636020420032005360200200328020821010b2003200141016a360208200520016a41003a00000c010b02400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d06200141017422062005200620054b1b22064100480d060240024020010d002006102821050c010b200328020020012006102c21050b2005450d052003200636020420032005360200200328020821010b2003200141016a360208200520016a41013a0000200041016a2003108f010b200041216a21002004415f6a22040d000b0b2003280204210020022802002002280204200328020022012003280208100702402000450d002001102a0b200341106a24000f0b200641011037000b200641011037000b1031000bdb0401057f230041106b2203240020034100360208200342013703002002200310b401024002400240024002402002450d0020024190016c2104034020032802042105200328020821020240024020012802004113470d000240024020052002460d00200328020021050c010b200241016a22052002490d08200241017422062005200620054b1b22064100480d080240024020020d002006102821050c010b200328020020022006102c21050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a00000c010b0240024020052002460d00200328020021050c010b200241016a22052002490d07200241017422062005200620054b1b22064100480d070240024020020d002006102821050c010b200328020020022006102c21050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a00002001200310eb0120014188016a28020021060240024020032802042205200328020822026b4104490d00200328020021050c010b200241046a22072002490d07200541017422022007200220074b1b22024100480d070240024020050d002002102821050c010b200328020020052002102c21050b2005450d062003200236020420032005360200200328020821020b2003200241046a360208200520026a20063600000b20014190016a2101200441f07e6a22040d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b200641011037000b200641011037000b200241011037000b1031000b6801037f024041094101200128020022024101461b220310282204450d000240024020020d00200441003a0000410121010c010b200441013a000020042001290204370001410921010b2000200136020820002003360204200020043602000f0b200341011037000bcc0902057f027e230041c0006b22022400024002400240024002402001280200417f6a220341024b0d0020030e03010203010b41a091c1001032000b410121030240024020012d00044101460d00200241026a200141046a220341036a2d00003a0000200241206a41086a200141146a290200370300200241306a2001411c6a290200370300200241386a200141246a2d00003a0000200220032f00013b010020022001410c6a290200370320200141086a2802002104410021030c010b200141086a28020021040b200020033a0004200020022f01003b000520004101360200200041286a2001290328370300200041086a20043602002000410c6a2002290320370200200041306a200141306a290300370300200041076a200241026a2d00003a0000200041146a200241206a41086a2903003702002000411c6a200241306a290300370200200041246a200241386a2802003602000c020b410121030240024020012d00044101460d00200241026a200141046a220341036a2d00003a0000200241206a41086a200141146a290200370300200241306a2001411c6a290200370300200241386a200141246a2d00003a0000200220032f00013b010020022001410c6a290200370320200141086a2802002104410021030c010b200141086a28020021040b200020033a0004200020022f01003b0005200041286a2001290328370300200041386a2001290338370300200041086a20043602002000410c6a2002290320370200200041306a200141306a290300370300200041c0006a200141c0006a290300370300200041076a200241026a2d00003a0000200041146a200241206a41086a2903003702002000411c6a200241306a290300370200200041246a200241386a280200360200200041023602000c010b200141286a2103410121040240024020012d00044101460d002002411e6a200141046a220441036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220042f00013b011c20022001410c6a290200370300200141086a2802002105410021040c010b200141086a28020021050b410121060240024020032d00004101460d002002413e6a200341036a2d00003a0000200241286a200141386a290200370300200241306a200141c0006a290200370300200241386a200141c8006a2d00003a0000200220032f00013b013c2002200141306a2902003703202001412c6a2802002103410021060c010b2001412c6a28020021030b200020043a0004200020022f011c3b0005200020022f013c3b0029200041086a20053602002000410c6a2002290300370200200041286a20063a0000200041076a2002411c6a41026a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602002000412b6a2002413c6a41026a2d00003a0000200141d8006a2903002107200129035021082000412c6a2003360200200041d0006a2008370300200041d8006a200737030020004103360200200041306a2002290320370200200041386a200241206a41086a290300370200200041c0006a200241206a41106a290300370200200041c8006a200241206a41186a2802003602000b200241c0006a24000b960403077f017e067f02400240024002402001410c6a2802002202417f4c0d0020012802042103200128020021040240024020020d0041012105410021060c010b20022106200210282205450d020b200520032002109a052107200141186a2802002208ad420c7e2209422088a70d002009a72203417f4c0d002001280210210a0240024020030d004104210b0c010b20031028220b450d030b0240024020080d004100210c0c010b200a2008410c6c6a210d4100210c200b21050340200a41086a2802002203417f4c0d02200a280200210e0240024020030d004101210f0c010b20031028220f450d060b200f200e2003109a05210e200541086a2003360200200541046a20033602002005200e3602002005410c6a2105200c41016a210c200a410c6a220a200d470d000b0b20002007360204200020043602002000200129021c37021c200041186a200c360200200041146a2008360200200041106a200b3602002000410c6a2002360200200041086a2006360200200020012902243702242000412c6a2001412c6a290200370200200041346a200141346a2902003702002000413c6a2001413c6a290200370200200041c4006a200141c4006a290200370200200041cc006a200141cc006a290200370200200041d4006a200141d4006a290200370200200041dc006a200141dc006a2902003702000f0b1036000b200241011037000b200341041037000b200341011037000bd90303027f017e027f02402001450d00034020002802e40121002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d0020002001410c6c6a220441e4006a2902002105200441e0006a2802002104200141016a21010c010b02400240200028020022010d002003ad210541002106410021010c010b20003301044220862003ad842105410121060b2000102a2005a72103024002402005422088a7220720012f01064f0d00200121040c010b034002400240200128020022040d002003ad2105410021040c010b200641016a210620013301044220862003ad8421050b2001102a2005a72103200421012005422088a7220720042f01064f0d000b0b200741027420046a41e8016a280200210020042007410c6c6a220141e4006a2902002105200141e0006a280200210402402006417f6a2201450d00034020002802e40121002001417f6a22010d000b0b410021010b2004450d012002417f6a210202402005a7450d002004102a0b20020d000b0b0240200041f8b9c000460d00200028020021012000102a2001450d00200128020021042001102a2004450d00024020042802002201450d0003402004102a2001210420012802002200210120000d000b0b2004102a0b0bd308030d7f017e017f230041a0016b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2205200128020422062f01064f0d01200241186a2207200620054105746a220341206a290000370300200241106a2208200341186a290000370300200241086a2209200341106a2900003703002002200341086a290000370300200241206a41286a220a2006200541306c6a22034190036a290300370300200241206a41206a220b20034188036a290300370300200241206a41186a220c20034180036a290300370300200241206a41106a220d200341f8026a290300370300200241206a41086a220e200341f0026a290300370300200341e8026a290300210f2001200541016a36020c20012004360208200120063602042002200f370320200241d0006a41186a2007290300370300200241d0006a41106a2008290300370300200241d0006a41086a200929030037030020022002290300370350200241d0006a41286a200e290300370300200241d0006a41306a200d29030037030020024188016a200c29030037030020024190016a200b29030037030020024198016a200a290300370300200220022903203703702000200241d0006a41d000109a051a0c020b200041003602400c010b2001280200210702400240200628020022030d002004ad210f410021030c010b200741016a210720063301044220862004ad84210f0b2006102a200fa7210502400240200f422088a7220420032f01064f0d00200321060c010b034002400240200328020022060d002005ad210f410021060c010b200741016a210720033301044220862005ad84210f0b2003102a200fa7210520062103200f422088a7220420062f01064f0d000b0b200241186a2208200620044105746a220341206a290000370300200241106a2209200341186a290000370300200241086a220a200341106a2900003703002002200341086a290000370300200241206a41286a220b2006200441306c6a22034190036a290300370300200241206a41206a220c20034188036a290300370300200241206a41186a220d20034180036a290300370300200241206a41106a220e200341f8026a290300370300200241206a41086a2210200341f0026a2903003703002002200341e8026a290300370320200441027420066a41fc066a280200210302402007417f6a2206450d00034020032802f80621032006417f6a22060d000b0b2001410036020c200120053602082001200336020420014100360200200241d0006a41186a2008290300370300200241d0006a41106a2009290300370300200241d0006a41086a200a290300370300200241d0006a41286a2010290300370300200241d0006a41306a200e29030037030020024188016a200d29030037030020024190016a200c29030037030020024198016a200b29030037030020022002290300370350200220022903203703702000200241d0006a41d000109a051a0b200241a0016a24000bbd0301057f230041106b2203240002400240024002400240200141046a2204417f4c0d000240024020040d00410121050c010b200410282205450d020b2003410036020820032004360204200320053602002001200310b4010240024020032802042206200328020822056b2001490d00200328020021040c010b200520016a22042005490d05200641017422072004200720044b1b22074100480d050240024020060d002007102821040c010b200328020020062007102c21040b2004450d032003200736020420032004360200200721060b200420056a20002001109a051a02400240200241046a2802002207200241086a28020022006b200520016a2201490d00200228020021050c010b200020016a22052000490d05200741017422002005200020054b1b22004100480d050240024020070d002000102821050c010b200228020020072000102c21050b2005450d0420022005360200200241046a2000360200200241086a28020021000b200241086a200020016a360200200520006a20042001109a051a02402006450d002004102a0b200341106a24000f0b1036000b200441011037000b200741011037000b200041011037000b1031000b880201057f230041d0006b220224000240411710282203450d00200341002900f1d8433700002003410f6a4100290080d943370000200341086a41002900f9d84337000020024297808080f002370224200220033602202000200241206a108f012002280228210320022802202100200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020002003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b2002200110e203200241d0006a24000f0b411741011037000b1000200028020020002802042001105f0baf0201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad41012001103f21000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000b20024180016a240020000f0b20044180011044000b20044180011044000b130020004101360204200041cc9ac1003602000b130020004102360204200041849cc1003602000b3101017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241e8073600000b3101017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241e5003600000bd20903067f017e057f230041f0016b22022400024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002005417f6a220541014b0d0520050e020102010b200041023a00000c050b20064104490d012004280001210720012003417b6a22053602042001200441056a36020020054108490d02200429000521082001200341736a36020420012004410d6a36020041002105200241003a00b001410d20036b2109200341726a210603400240200920056a0d000240200541ff0171450d00200241003a00b0010b200041023a00000c060b20024190016a20056a200420056a220a410d6a2d00003a0000200120063602042001200a410e6a3602002002200541016a220a3a00b0012006417f6a2106200a2105200a4120470d000b200241f0006a41186a20024190016a41186a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41086a20024190016a41086a290300370300200220022903900137037041002105200241003a00d0012004200a6a2109200a20036b410d6a210a03400240200a20056a0d000240200541ff0171450d00200241003a00d0010b200041023a00000c060b20024190016a20056a200920056a2204410d6a2d00003a00002001200636020420012004410e6a3602002002200541016a22043a00d0012006417f6a210620042105200441c000470d000b200241106a41386a220120024190016a41386a290300370300200241106a41306a220520024190016a41306a290300370300200241106a41286a220620024190016a41286a290300370300200241106a41206a220420024190016a41206a290300370300200241106a41186a220a20024190016a41186a290300370300200241106a41106a220320024190016a41106a290300370300200241106a41086a220920024190016a41086a290300370300200241d0006a41086a220b200241f0006a41086a290300370300200241d0006a41106a220c200241f0006a41106a290300370300200241d0006a41186a220d200241f0006a41186a290300370300200220022903900137031020022002290370370350200041003a000020002002290350370001200041096a200b290300370000200041116a200c290300370000200041196a200d290300370000200041216a2002290310370000200041296a2009290300370000200041316a2003290300370000200041396a200a290300370000200041c1006a2004290300370000200041c9006a2006290300370000200041d1006a2005290300370000200041d9006a2001290300370000200041e3006a2002410f6a2d00003a0000200041e1006a20022f000d3b0000200041e8006a2008370300200041e4006a20073602000c040b0240024020064104490d002004280001210620012003417b6a22053602042001200441056a360200200541084f0d010b200041023a00000c040b200041013a0000200020022f00103b0001200429000521082001200341736a36020420012004410d6a360200200041086a2008370300200041046a2006360200200041036a200241126a2d00003a0000200041106a20024190016a41e000109a051a0c030b200041023a00000c020b200041023a00000c010b200041023a00000b200241f0016a24000be71207027f017e057f027e017f017e0a7f230041b0036b2202240020002802102203200328020041016a36020020002902142104200028020c2103200028020821052000280200210620002802042100200241f0016a41086a2207200141086a280200360200200220012902003703f001024002400240024020002f01062201410b490d00200241d0026a410272410041da001099051a200241386a41004184011099051a0240024041e40110282208450d0020084100360200200841046a200241d0026a41dc00109a051a200841e0006a200241386a418401109a052107200241386a41086a2209200041b0016a280200360200200220002902a8013703382000413c6a330000210a2000413e6a310000210b20002d003f210c2000350038210d200841086a200041c0006a20002f010641796a2201410374109a05210e2007200041b4016a2001410c6c109a052107200041063b0106200820013b0106200241d0026a41086a2009280200360200200220022903383703d002200d200a200b4210868442208684210a0240024020034107490d002003410374200e6a41506a200e200341796a22094103746a220e200141ffff037120096b410374109b051a200e20043700002003410c6c20076a220341b87f6a200341ac7f6a2203200841066a22012f010020096b410c6c109b051a200341086a200241f0016a41086a280200360200200320022903f0013702000c010b200041086a20034103746a220741086a2007200041066a22012f010020036b410374109b051a20072004370000200041e0006a2003410c6c6a2207410c6a200720012f010020036b410c6c109b051a200741086a200241f0016a41086a280200360200200720022903f0013702000b200120012f010041016a3b0100200241286a41086a220f200241d0026a41086a22102802002203360200200241086a221120033602002002200c3a0017200220022903d00222043703282002200a3e02102002200a4230883c00162002200a4220883d011420022004370300200229031021042000280200220c450d0320002f01042112200241d0026a410272211303402002200641016a22063602202002200c360224200f201128020036020020022002290300370328201241ffff03712109024002400240200c2f01062200410b490d002013410041da001099051a200241f0016a200241d0026a41dc00109a051a200241386a410041b4011099051a41940210282207450d0520074100360200200741046a200241f0016a41dc00109a051a200741e0006a200241386a41b401109a052103200c41386a290000210a200241386a41086a2214200c41b0016a2802003602002002200c41a8016a290200370338200741086a200c41c0006a200c2f0106220141796a2200410374109a0521152003200c41b4016a2000410c6c109a052116200741e4016a200c4180026a2001417a6a220e410274109a052117200c41063b0106200720003b01060240200e450d00410021002017210303402003280200220120003b010420012007360200200341046a2103200e200041016a2200470d000b0b20102014280200220036020020022002290338220b3703d002201420003602002002200b370338201241ffff037122034107490d0120152009417a6a22034103746a2015200941796a22004103746a220120072f010620006b410374109b051a200120043700002009410c6c20166a220141b87f6a200141ac7f6a220120072f0106220e20006b410c6c109b051a200141086a200f280200360200200120022903283702002007200e41016a22013b01062009410274221220176a416c6a201720034102746a220e200141ffff0371220920036b410274109b051a200e200836020020092003490d02200720126a41cc016a2103034020032802002201200041016a22003b010420012007360200200341046a210320002009490d000c030b0b200c41086a2201200941016a22034103746a200120094103746a2201200020096b2207410374109b051a20012004370000200c2009410c6c6a220141ec006a200141e0006a220e2007410c6c109b051a200141e8006a200241286a41086a280200360200200e2002290328370200200c200041016a22003b01062009410274200c41e4016a22016a41086a200120034102746a2201200041ffff0371220720036b410274109b051a20012008360200201241ffff037120074f0d07200c2003417f6a22004102746a41e8016a2103034020032802002201200041016a22003b01042001200c360200200341046a210320002007490d000c080b0b200c41086a2200200941016a220e4103746a200020094103746a2200200c2f0106220120096b2212410374109b051a20002004370000200c41e0006a2009410c6c6a2200410c6a20002012410c6c109b051a200041086a200f28020036020020002002290328370200200c200141016a22003b010620094102742217200c41e4016a22016a41086a2001200e4102746a2212200041ffff03712201200e6b410274109b051a20122008360200200320014f0d00200c20176a41e8016a2100034020002802002203200941016a22093b01042003200c360200200041046a210020012009470d000b0b200241106a41086a2014280200220036020020112000360200200220022903382204370310200220043703000240200c28020022000d0020072108200a21040c050b200c2f010421122000210c200a2104200721080c000b0b41e40141041037000b41940241041037000b200020034103746a220941106a200941086a2209200120036b410374109b051a2009200437000020002003410c6c6a220141ec006a200141e0006a220920002f010620036b410c6c109b051a200141e8006a2007280200360200200920022903f001370200200020002f010641016a3b01060c010b200241d0026a410272410041da001099051a200241f0016a200241d0026a41dc00109a051a200241386a410041b4011099051a41940210282200450d0120004100360200200041046a200241f0016a41dc00109a051a200041e0006a200241386a41b401109a0521012000200528020022033602e401200520003602002005200528020441016a360204200341003b010420032000360200200120002f01062203410c6c6a22012002290300370200200020034103746a41086a2004370000200141086a200241086a280200360200200041e4016a200341016a22034102746a2008360200200020033b0106200820033b0104200820003602000b200241b0036a24000f0b41940241041037000b8b0303017f017e027f02402001450d00034020002802940321002001417f6a22010d000b0b02402002450d00410021034100210103402002417f6a210202400240200120002f01064f0d00200141016a21010c010b02400240200028020022010d002003ad210441002105410021010c010b20003301044220862003ad842104410121050b2000102a2004a72103024002402004422088a7220620012f01064f0d00200121000c010b034002400240200128020022000d002003ad2104410021000c010b200541016a210520013301044220862003ad8421040b2001102a2004a72103200021012004422088a7220620002f01064f0d000b0b200641027420006a4198036a280200210002402005417f6a2201450d00034020002802940321002001417f6a22010d000b0b410021010b20020d000b0b0240200041f8b9c000460d00200028020021012000102a2001450d00200128020021002001102a2000450d00024020002802002201450d0003402000102a2001210020012802002203210120030d000b0b2000102a0b0be480010d067f017e017f027e0b7f017e027f017e017f017e067f017e127f230041e0026b22012400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020004180c20370450d00200141e8006a21020c010b20014190026a41086a22034200370300200142003703900241f490c600411420014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a001200141e8006a4110200141a0016a100621030240024020012802a0012204417f460d0020030d010b200141e8006a21020c010b024002400240024002400240024020044104490d00200328000021042003102a200141e8006a21022004450d0720014190026a41086a22034200370300200142003703900241a9a2c100410f20014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a001200141e8006a4110200141a0016a100621030240024020012802a0012205417f460d002003450d0020012005360294022001200336029002200141a0016a20014190026a107d20012802a0012206450d0320012902a40121072005450d012003102a0c010b41042106420021070b20014190026a41086a22034200370300200142003703900241b8a2c100411420014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141a0016a200141e8006a10be020240024020012802a8012208450d002007422088a720012902ac012209422088a76b20012903a001220a422088a7220b6a2105200aa721032009a7450d012008102a0c010b2007422088a721054100210b10980121030b200520044f0d020c030b41c4d1c3004133200141d8026a419cd9c3001038000b41c4d1c3004133200141d8026a419cd9c3001038000b0240200b20044f0d00200b20046b22032007422088a722056a220420034f0d032006200441246c6a28022021030c010b20014190026a41086a22044200370300200142003703900241dca2c100411420014190026a1008200141e8006a41086a2004290300370300200120012903900237036841002105200141003602a001200141e8006a4110200141a0016a10062104024020012802a001220b417f460d002004450d00200b4104490d02200428000021052004102a0b200520036a21030b200341ffc1036a220320034180c203706b210302402007a7450d002006102a0b20032000470d0320014190026a41086a22034200370300200142003703900241a9a2c100410f20014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a001200141e8006a4110200141a0016a1006210302400240024020012802a0012204417f460d002003450d0020012004360294022001200336029002200141a0016a20014190026a107d20012802a001220c450d0220012902a401210a2004450d012003102a0c010b4104210c4200210a0b20014190026a41086a22034200370300200142003703900241f490c600411420014190026a1008200141e8006a41086a200329030037030020012001290390023703684100210d200141003602a001200141e8006a4110200141a0016a100621030240024020012802a0012204417f460d002003450d0020044104490d012003280000210d2003102a0b109801210e02400240200a422088a7220f41246c2204450d00200c41206a280200200e4d0d010b4101210b41002105410021060c050b200141a0016a41186a2203200c41186a290200370300200141a0016a41106a2205200c41106a290200370300200141a0016a41086a2206200c41086a2902003703002001200c2902003703a001024041201028220b450d00200b20012903a001370000200b41186a2003290300370000200b41106a2005290300370000200b41086a20062903003700000240200c41246a2203200c20046a470d0041012105410121060c060b200c200f41246c6a211041202108410121044101210503400240200341206a280200200e4d0d00200421060c070b200141b8026a41186a2211200341186a290200370300200141b8026a41106a2212200341106a290200370300200141b8026a41086a2213200341086a290200370300200120032902003703b8020240024020052004460d00200421060c010b200441016a22062004490d1e200441017422142006201420064b1b220641ffffff3f712006470d1e200641057422144100480d1e0240024020040d0020141028210b0c010b200b20044105742014102c210b0b200b0d00201441011037000b200b20086a220420012903b802370000200441186a2011290300370000200441106a2012290300370000200441086a2013290300370000200841206a2108200541016a2105200621042010200341246a2203460d060c000b0b412041011037000b41c4d1c3004133200141d8026a419cd9c3001038000b41c4d1c3004133200141d8026a419cd9c3001038000b41c4d1c3004133200141d8026a419cd9c3001038000b41cca2c100200420051034000b024002400240024002400240024002400240200d200f20056b22044d0d0020014190026a41086a22034200370300200142003703900241f0a2c100411c20014190026a1008200141e8006a41086a2003290300370300200120012903900237036841002108200141003602a001200141e8006a4110200141a0016a10062103024020012802a0012211417f460d002003450d0020114104490d02200328000021082003102a0b20014190026a41086a22034200370300200142003703900241b8a2c100411420014190026a1008200141e8006a41086a20032903003703002001200129039002370368410810282203450d0220014288808080c0003702a401200120033602a00120032008200e6a3600000240024020012802a401220820012802a80122036b4104490d0020012802a00121080c010b200341046a22112003490d20200841017422032011200320114b1b22034100480d200240024020080d002003102821080c010b20012802a00120082003102c21080b2008450d04200120033602a401200120083602a00120012802a80121030b2001200341046a3602a801200820036a200d20046b22133600002005200141a0016a10b40102402005450d0020054105742104200b210303402003200141a0016a108f01200341206a2103200441606a22040d000b0b20012802a4012103200141e8006a411020012802a001220420012802a801100702402003450d002004102a0b02402006450d00200b102a0b200141a8026a4200370300200141a0026a420037030020014198026a42003703002001420037039002201341066a220ead42307e2207422088a70d172007a72203417f4c0d170240024020030d0041082110410821040c010b200310282210450d05201021040b200141a0016a41186a221120014190026a41186a290300370300200141a0016a41106a221220014190026a41106a290300370300200141a0016a41086a20014190026a41086a29030037030020012001290390023703a001200e4102490d05200d20056a200f6b41056a2105200421030340200141b8026a41186a22062011290300370300200141b8026a41106a220b2012290300370300200141b8026a41086a2208200141a0016a41086a290300370300200120012903a0013703b8022003420037030820034200370300200341106a20012903b802370300200341186a2008290300370300200341206a200b290300370300200341286a2006290300370300200341306a21032005417f6a22050d000b201341056a21050c060b2006450d07200b102a0c070b41c4d1c3004133200141d8026a419cd9c3001038000b410841011037000b200341011037000b200341081037000b4100210520042103200e450d010b2003420037030820034200370300200320012903a001370310200341186a200141a8016a290300370300200341206a200141b0016a290300370300200341286a200141a0016a41186a290300370300200541016a21050b20014190026a41086a220342003703002001420037039002418ca3c100411320014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a801200142013703a0012005200141a0016a10b40102402005450d002004200541306c6a210b0340200441086a2903002107200429030021090240024020012802a401220520012802a80122036b4110490d0020012802a00121050c010b200341106a22062003490d1a200541017422032006200320064b1b22034100480d1a0240024020050d002003102821050c010b20012802a00120052003102c21050b2005450d05200120033602a401200120053602a00120012802a80121030b200520036a22052007370008200520093700002001200341106a3602a801200441106a200141a0016a108f01200441306a2204200b470d000b0b20012802a4012103200141e8006a411020012802a001220420012802a801100702402003450d002004102a0b0240200e450d002010102a0b200141083a00a001200141a0016a41086a2013360200200141023a00a40141014100200141a0016a10cc010b200aa7450d00200c102a0b20014190026a41086a22034200370300200142003703900241b8a2c100411420014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141a0016a200210be0220012802a8012215450d1820012902ac01211620012802a0012000470d1720014190026a41086a22034200370300200142003703900241b8a2c100411420014190026a1008200141e8006a41086a220020032903003703002001200129039002370368200141a0016a200210be02024020012802a80122170d0002402016a7450d002015102a0b41d5a3c100410f100b41e4a3c1004135100b0c190b20024110100920012802a401211820012902ac012119200342003703002001420037039002418ca3c100411320014190026a1008200020032903003703002001200129039002370368200141003602a00120024110200141a0016a100621030240024020012802a0012200417f460d002003450d0020012000360294022001200336029002200141a0016a20014190026a107820012802a001221a450d0320012902a401211b02402000450d002003102a0b2002411010090c010b4200211b4108211a0b109801211c20014190026a41086a22034200370300200142003703900241dca2c100411420014190026a1008200141e8006a41086a200329030037030020012001290390023703684100211d200141003602a00120024110200141a0016a10062103024020012802a0012200417f460d002003450d0020004104490d032003280000211d2003102a0b201a201b422088a7221e41306c6a210e0240024020180d004100211341002106410021000c010b2018417f6a2106410021000240201e450d000240201a201e41306c6a220341506a220e290300200e41086a2903008450450d00410121130c020b20014190026a41186a200341606a220341186a29000037030020014190026a41106a200341106a29000037030020014190026a41086a200341086a2900003703002001200329000037039002410121000b410021130b200141a9016a20014190026a41086a290300370000200141b1016a20014190026a41106a290300370000200141b9016a20014190026a41186a290300370000200120003a00a00120012001290390023700a101200141a0016a41017221032000450d0a20034280809aa6eaafe301420010aa02200141e8006a41086a200341086a290000370300200141e8006a41106a200341106a290000370300200141e8006a41186a200341186a2900003703002001200329000037036820012d00a0014101470d0b41201028221f450d03201f2001290368370000201f41186a200141e8006a41186a290300370000201f41106a200141e8006a41106a290300370000201f41086a200141e8006a41086a290300370000200141a0016a4101722103410221054120210441012120410121210340024002400240024020060d00410021060c010b2006417f6a2106201341ff01710d000240201a200e470d00410021130c010b200e41506a220b290300200b41086a290300844200520d0141012113200b210e0b200320012903b802370000200341086a200141b8026a41086a290300370000200341106a200141b8026a41106a290300370000200341186a200141b8026a41186a29030037000041002100200141003a00a0010c010b200141b8026a41186a200e41606a220041186a2900002207370300200141b8026a41106a200041106a2900002209370300200141b8026a41086a200041086a290000220a3703002001200029000022223703b80220032022370000200341086a200a370000200341106a2009370000200341186a2007370000200141013a00a00120034280809aa6eaafe301420010aa024100211320012d00a0012100200b210e0b20014190026a41186a220b200341186a29000037030020014190026a41106a2208200341106a29000037030020014190026a41086a2211200341086a29000037030020012003290000370390020240200041ff0171450d00200141a0016a41186a2212200b290300370300200141a0016a41106a220b2008290300370300200141a0016a41086a2208201129030037030020012001290390023703a001024020202021470d00202041016a22002020490d1820052000200520004b1b222141ffffff3f712021470d18202141057422004100480d180240024020200d0020001028211f0c010b201f20042000102c211f0b201f450d0c0b201f20046a220020012903a001370000200041186a2012290300370000200041106a200b290300370000200041086a2008290300370000200541026a2105200441206a2104202041016a21200c010b0b201f20046a21232020450d0c200141a0016a41086a2104201f210f0340200141306a200f10bf02024020012802304101470d002001280238210520014190016a10c002200128029001212402402001280298012203450d00200341216c2100202441016a21032005410876210841012005411f7174212520054105764107712211417f732126034002402003417f6a2d00004101470d00200141a0016a41186a200341186a290000370300200141a0016a41106a200341106a2900003703002004200341086a290000370300200120032900003703a001200120083602c00120014190026a200141a0016a10c1020240201120012802980222054f0d00200520266a220620054f0d0a200128029002220b20064102746a28020020257121050240200128029402450d00200b102a0b2005450d01411310282205450d0b200541002900c2a34122073700002005410f6a41002800d1a341220c360000200541086a41002900caa341220937000020014293808080b0023702a401200120053602a0012003200141a0016a108f0120012802a801211220012802a0012113200141b8026a41186a22054200370300200141b8026a41106a22064200370300200141b8026a41086a220b4200370300200142003703b80220132012200141b8026a1000200141106a41186a22102005290300370300200141106a41106a220d2006290300370300200141106a41086a2214200b290300370300200120012903b802370310024020012802a401450d0020012802a001102a0b200141003602a001200141106a4120200141a0016a1006210e024020012802a0012213417f460d00200120133602bc022001200e3602b802200141a0016a200141b8026a10c20220012903a0014201510d0d20014190026a41206a2227200441206a222828020036020020014190026a41186a2229200441186a222a29030037030020014190026a41106a222b200441106a222c29030037030020014190026a41086a2212200441086a222d290300370300200120042903003703900220012802cc01212e02402013450d00200e102a0b200141e8006a41206a20272802002213360200200141c0006a41086a220e2012290300370300200141c0006a41106a2227202b290300370300200141c0006a41186a222b2029290300370300200141c0006a41206a222920133602002001200129039002370340201242003703002001420037039002418891c600411120014190026a1008200141e8006a41086a20122903003703002001200129039002370368200141003602a00120024110200141a0016a1006211202400240024020012802a0012213417f470d00410021130c010b20134104490d01201228000021132012102a0b20042001290340370300202d200e290300370300202c2027290300370300202a202b29030037030020282029280200360200200142013703a0012001201341016a3602cc01411310282212450d10201220073700002012410f6a200c360000201241086a200937000020014293808080b002370294022001201236029002200320014190026a108f01200128029802211220012802900221132005420037030020064200370300200b4200370300200142003703b80220132012200141b8026a100020102005290300370300200d20062903003703002014200b290300370300200120012903b8023703100240200128029402450d00200128029002102a0b20014120360294022001200141106a36029002200420014190026a10c3020c030b41c4d1c3004133200141d8026a419cd9c3001038000b20042001290340370300200441086a200141c0006a41086a290300370300200441106a200141c0006a41106a290300370300200441186a200141c0006a41186a290300370300200441206a200141c0006a41206a280200360200200142003703a0012001202e3602cc01411310282212450d0d201220073700002012410f6a200c360000201241086a200937000020014293808080b002370294022001201236029002200320014190026a108f01200128029802211220012802900221132005420037030020064200370300200b4200370300200142003703b80220132012200141b8026a100020102005290300370300200d20062903003703002014200b290300370300200120012903b8023703100240200128029402450d00200128029002102a0b200141106a412010090c010b200128029402450d00200128029002102a0b200341216a21032000415f6a22000d000b0b200128029401450d002024102a0b2023200f41206a220f470d000c0d0b0b200341011037000b41c4d1c3004133200141d8026a419cd9c3001038000b41c4d1c3004133200141d8026a419cd9c3001038000b412041011037000b41cca2c100200620051034000b411341011037000b41c4d1c3004133200141d8026a419cd9c3001038000b411341011037000b411341011037000b200041011037000b200141e8006a41186a200341186a290000370300200141e8006a41106a200341106a290000370300200141e8006a41086a200341086a290000370300200120032900003703680b41002121410121234101211f410021200b20014190026a41086a22034200370300200142003703900241a9a2c100410f20014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a00120024110200141a0016a10062103024002400240024002400240024020012802a0012200417f460d002003450d0020012000360294022001200336029002200141a0016a20014190026a107d20012802a0012225450d0220012902a40121072000450d012003102a0c010b42002107410421250b20252007422088a7220841246c6a210d02402019422088a722050d004100212f41012130410021310c050b410021314100212f4101213002402005200d20256b41246e2203200320054b1b2203450d00200341057422004100480d0e200010282230450d022003212f0b20252103200521042030210003400240200d20036b41ec004b0d00200d2003460d062025200841246c6a21114101210b0240034020002003290000370000200041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a2900003700002004200b2206460d01200641016a210b200041206a21002011200341246a2203470d000b0b203120066a21310c060b20002003290000370000200041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a290000370000024020044101470d00203141017221310c060b20002003290024370020200041386a2003413c6a290000370000200041306a200341346a290000370000200041286a2003412c6a29000037000020044102460d0420002003290048370040200041d8006a200341e0006a290000370000200041d0006a200341d8006a290000370000200041c8006a200341d0006a29000037000020044103460d032000200329006c370060200041f8006a20034184016a290000370000200041f0006a200341fc006a290000370000200041e8006a200341f4006a290000370000203141046a213120004180016a210020034190016a21032004417c6a22040d000c050b0b41c4d1c3004133200141d8026a419cd9c3001038000b200041011037000b203141037221310c010b203141027221310b201d201c6a21262007a721270240024002400240024002402005450d00202521032008450d03200541016a2100200841246c2104202521030340200141b8026a41186a200341186a290200370300200141b8026a41106a200341106a290200370300200141b8026a41086a200341086a290200370300200120032902003703b8022000417f6a2200450d02200341246a21032004415c6a22040d000b200d21030c030b202521032008450d02200141a0016a41186a202541186a290200370300200141a0016a41106a202541106a290200370300200141a0016a41086a202541086a290200370300200120252902003703a001202541246a2103202528022021060c010b200341206a2802002106200141a0016a41186a200141b8026a41186a290300370300200141a0016a41106a200141b8026a41106a290300370300200141a0016a41086a200141b8026a41086a290300370300200120012903b8023703a001200341246a21030b20014190026a41186a200141a0016a41186a2200290300220737030020014190026a41106a200141a0016a41106a2204290300220937030020014190026a41086a200141a0016a41086a2205290300220a370300200120012903a00122223703900220002007370300200420093703002005200a370300200120223703a001417f200d20036b41246d22002023201f6b4105766a220420042000491b21054100210b200141a0016a2100201f21040c010b0240201f2023470d0002402027450d002025102a0b4100211c410421284100212c0c020b201f41086a2900002107201f41106a2900002109201f290000210a20014190026a41186a201f41186a290000222237030020014190026a41106a200937030020014190026a41086a20073703002001200a37039002200141a0016a41186a2022370300200141a0016a41106a2009370300200141a0016a41086a20073703002001200a3703a0012023201f41206a22046b41057621054102210b200141a0016a2100202621060b417f200541016a220820082005491b221cad42247e2207422088a70d012007a72205417f4c0d010240024002400240024002400240024020050d00410421280c010b200510282228450d010b20282000290200370200202841186a200041186a290200370200202841106a200041106a290200370200202841086a200041086a290200370200202820063602200240200b450d00024020042023470d004101212c0c050b200441086a2900002107200441106a29000021092004290000210a20014190026a41186a200441186a29000037030020014190026a41106a200937030020014190026a41086a20073703002001200a37039002200441206a21040c020b0240200d2003460d00200141a0016a41186a200341186a2902002209370300200141a0016a41106a200341106a290200220a370300200141a0016a41086a200341086a29020022223703002003290200210720014190026a41086a202237030020014190026a41106a200a37030020014190026a41186a2009370300200120073703a0012001200737039002200328022021134100210b200341246a21030c030b024020042023460d00200441086a2900002107200441106a29000021092004290000210a20014190026a41186a200441186a29000037030020014190026a41106a200937030020014190026a41086a20073703002001200a37039002200441206a21040c020b4101212c0c030b200541041037000b4102210b202621130b4102210641022100412421050340200141a0016a41186a220820014190026a41186a220e290300370300200141a0016a41106a221120014190026a41106a220c290300370300200141a0016a41086a221220014190026a41086a221029030037030020012001290390023703a00102402000222c417f6a2200201c470d000240024002400240200b41ff01710e03010200010b202320046b41057621140c020b417f200d20036b41246d2214202320046b4105766a220f200f2014491b21140c010b200d20036b41246d21140b2000417f201441016a220f200f2014491b6a22142000490d0e20062014200620144b1b221cad42247e2207422088a70d0e2007a722004100480d0e02400240202c4101470d002000102821280c010b202820052000102c21280b2028450d030b202820056a220020012903a001370200200041186a2008290300370200200041106a2011290300370200200041086a2012290300370200200041206a20133602000240024002400240200b41ff01710e03010200010b20042023460d04200441086a2900002107200441106a29000021092004290000210a200e200441186a290000370300200c2009370300201020073703002001200a37039002200441206a2104410121084102210b202621130c020b0240200d2003460d002008200341186a29020022093703002011200341106a290200220a3703002012200341086a29020022223703002003290200210720102022370300200c200a370300200e2009370300200120073703a001200120073703900220032802202113410121084100210b200341246a21030c020b4102210b024020042023470d00410021080c020b200441086a2900002107200441106a29000021092004290000210a200e200441186a290000370300200c2009370300201020073703002001200a37039002200441206a210441012108202621130c010b200d2003460d02200e200341186a290200370300200c200341106a2902003703002010200341086a2902003703002001200329020037039002200328022021134101210b200341246a2103410121080b200641026a2106202c41016a2100200541246a210520080d000b0b02402027450d002025102a0b202c4115490d01202c4101762232ad42247e2207422088a70d032007a72203417f4c0d0302400240024020030d004104212e410421080c010b20031028222e450d01202e21080b2028415c6a2133202841b47f6a21344104210c410021244100212641002113202c2125034020252106410021254101210502402006417f6a221d450d000240024002400240024002402028201d41246c6a41206a280200200641246c221220286a41586a2802002203490d002006417e6a2111203420126a210441002125410021000340024020112000470d00200621050c080b200041016a21002003200428020022054f210b2004415c6a210420052103200b0d000b200041016a21052000417f7320066a21040c010b203420126a2100201d210402400340024020044101470d00410021040c020b2004417f6a210420032000280200220549210b2000415c6a210020052103200b0d000b0b20062004490d012006202c4b0d03200620046b2205410176220b450d00203320126a21032028200441246c6a21000340200141a0016a41206a2211200041206a2212280200360200200141a0016a41186a220e200041186a2210290200370300200141a0016a41106a220d200041106a2214290200370300200141a0016a41086a220f200041086a2225290200370300200120002902003703a001200341206a22272802002129200341186a222a2902002107200341106a222b2902002109200341086a222d290200210a200020032902003702002025200a37020020142009370200201020073702002012202936020020272011280200360200202a200e290300370200202b200d290300370200202d200f290300370200200320012903a0013702002003415c6a2103200041246a2100200b417f6a220b0d000b0b024020040d00200421250c050b0240200541094d0d00200421250c050b2006202c4b0d012028200441246c6a2111034020062004417f6a2225490d040240200620256b22054102490d002028200441246c6a220041206a22032802002028202541246c6a221241206a220b280200220e4f0d00200141b8026a41186a2210201241186a220d290200370300200141b8026a41106a2214201241106a220f290200370300200141b8026a41086a2227201241086a2229290200370300200120122902003703b802201220002902003702002029200041086a290200370200200f200041106a290200370200200d200041186a290200370200200b2003280200360200024020054103490d00201d210b20112103201241e8006a280200200e4f0d000340200341206a200341c4006a280200360200200341186a2003413c6a290200370200200341106a200341346a290200370200200341086a2003412c6a2902003702002003200341246a22002902003702002004200b417f6a220b460d01200341e8006a2112200021032012280200200e490d000b0b200020012903b8023702002000200e360220200041186a2010290300370200200041106a2014290300370200200041086a20272903003702000b2025450d052011415c6a2111202521042005410a4f0d050c000b0b200420061044000b20062004417f6a2225490d010b2006202c103c000b202520061044000b02400240024020132024470d00202441016a22032024490d10202441017422002003200020034b1b220341ffffffff01712003470d10200341037422004100480d100240024020240d0020001028210c0c010b200c20244103742000102c210c0b200c450d0120032124202621130b200c20134103746a2203200536020420032025360200202641016a2213212620134102490d01024003400240024002400240200c2013417f6a22264103746a2203280200450d002013410374200c6a220541746a2802002204200328020422004d0d000240201341024b0d0020132126410221130c080b200c2013417d6a22104103746a2802042203200020046a4d0d010240201341034b0d0020132126410321130c080b200541646a280200200320046a4d0d01201321260c070b20134103490d0120032802042100200c2013417d6a22104103746a28020421030b20032000490d010b2013417e6a21100b0240024002400240024002402013201041016a22274b2229450d00201320104b222a450d01200c20104103746a220d280204222b200d2802006a2203200c20274103746a2214280200220f490d022003202c4b0d032028200f41246c6a22122014280204220e41246c22006a2106200341246c21042003200f6b220b200e6b2203200e4f0d04202e2006200341246c2200109a051a200820006a210502400240200e4101480d00200341014e0d010b20062103200821000c060b203320046a210420062103034020042003415c6a220b2005415c6a22112005417c6a2802002003417c6a2802004922061b2200290200370200200441206a200041206a280200360200200441186a200041186a290200370200200441106a200041106a290200370200200441086a200041086a2902003702002005201120061b210502402012200b200320061b2203490d00200821000c070b2004415c6a21042008210020082005490d000c060b0b41b8dbc000202720131034000b41b8dbc000201020131034000b200f20031044000b2003202c103c000b202e20122000109a051a200820006a210502400240200e4101480d00200b200e4a0d010b20122103200821000c010b202820046a211120082100201221030340200320062000200641206a280200200041206a28020049220b1b2204290200370200200341206a200441206a280200360200200341186a200441186a290200370200200341106a200441106a290200370200200341086a200441086a2902003702002000200041246a200b1b2100200341246a2103200641246a2006200b1b220620114f0d01200520004b0d000b0b20032000200520006b220420044124706b109a051a0240202a450d00200d200f360200200d41046a202b200e6a3602002029450d022014201441086a20132027417f736a410374109b051a20262113202641014d0d040c010b0b41c8dbc000201020131034000b41b0b1c0001032000b200041041037000b20250d000b02402024450d00200c102a0b2032450d03202e102a0c030b200341041037000b200041041037000b202c4102490d00202c417f6a21042028202c41246c6a21064100210b0340024002400240202c20042203417f6a2204490d00202c20046b22004102490d022028200341246c6a220341206a22052802002028200441246c6a220841206a221228020022114f0d02200141b8026a41186a2213200841186a220e290200370300200141b8026a41106a220c200841106a2210290200370300200141b8026a41086a220d200841086a2214290200370300200120082902003703b802200820032902003702002014200341086a2902003702002010200341106a290200370200200e200341186a2902003702002012200528020036020020004103490d01200b210520062100200841e8006a28020020114f0d01034020002203415c6a22002003290200370200200041206a200341206a280200360200200041186a200341186a290200370200200041106a200341106a290200370200200041086a200341086a2902003702002005417f6a2205450d02200341246a2100200341c4006a28020020114f0d020c000b0b2004202c1044000b200320012903b80237020020032011360220200341186a2013290300370200200341106a200c290300370200200341086a200d2903003702000b200b41016a210b2006415c6a210620040d000b0b20014190026a41086a22034200370300200142003703900241a9a2c100410f20014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a801200142013703a001202c200141a0016a10b4010240202c450d002028202c41246c6a210b2028210003402000200141a0016a108f01200041206a28020021050240024020012802a401220420012802a80122036b4104490d0020012802a00121040c010b200341046a22062003490d0b200441017422032006200320064b1b22034100480d0b0240024020040d002003102821040c010b20012802a00120042003102c21040b2004450d04200120033602a401200120043602a00120012802a80121030b2001200341046a3602a801200420036a2005360000200b200041246a2200470d000b0b20012802a40121032002411020012802a001220020012802a801100702402003450d002000102a0b202c41246c220341246d2106410021040240024020030d004101210b410021060c010b200641ffffff3f712006470d09200641057422034100480d0920031028220b450d030b0240202c450d00202c41246c210541002104200b2103202821000340200041086a2900002107200041106a29000021092000290000210a200341186a200041186a290000370000200341106a2009370000200341086a20073700002003200a370000200441016a2104200341206a2103200041246a21002005415c6a22050d000b0b0240201c450d002028102a0b200b2004410041202004676b10c40220302031200b200410c50202402006450d00200b102a0b20014190026a41086a22034200370300200142003703900241b0a3c100411220014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a00120024110200141a0016a100621030240024020012802a0012200417f460d002003450d0020012000360294022001200336029002200141a0016a20014190026a106d20012802a0012208450d0520012902a401210a2000450d012003102a0c010b4200210a410121080b200141b8016a4200370300200141b0016a4200370300200141a8016a4200370300200142003703a001200a422088a7221041ffffff3f712010470d0020104105742203417f4c0d000240024020030d00410121060c010b200310282206450d050b200141b8026a41186a2204200141a0016a41186a290300370300200141b8026a41106a2205200141a0016a41106a290300370300200141b8026a41086a220b200141a0016a41086a290300370300200120012903a0013703b80220104102490d052010417f6a2100200621030340200320012903b802370000200341186a2004290300370000200341106a2005290300370000200341086a200b290300370000200341206a21032000417f6a22000d000b2010417f6a210c0c060b1036000b200341011037000b200341011037000b41c4d1c3004133200141d8026a419cd9c3001038000b200341011037000b4100210c200621032010450d010b200320012903b802370000200341186a200141b8026a41186a290300370000200341106a200141b8026a41106a290300370000200341086a200141b8026a41086a290300370000200c41016a210c0b201a201e41306c6a2103201ba7210e410021140c010b1031000b0240024002400240034002402018450d002003201a460d02200341506a2203290300200341086a29030084500d022018417f6a2200450d000340201a2003460d03200341506a2203290300200341086a29030084500d032000417f6a22000d000b0b2003201a460d0102400340200341506a22042903002107200441086a290300210920014190026a41186a2205200341606a220041186a29030037030020014190026a41106a220b200041106a29030037030020014190026a41086a2211200041086a29030037030020012000290300370390022007200984500d01200141a0016a41186a22002005290300370300200141a0016a41106a2205200b290300370300200141a0016a41086a220b201129030037030020012001290390023703a00120014190016a200141a0016a10bf02200141c0006a41186a22112000290300370300200141c0006a41106a22122005290300370300200141c0006a41086a2213200b290300370300200120012903a00137034002402001280290014101460d0020042103201a2004470d010c040b0b200141106a41086a220d2013290300370300200141106a41106a22132012290300370300200141106a41186a221220112903003703002001200129034022073703b8022001200737031020012802980121042000201229030037030020052013290300370300200b200d290300370300200120012903103703a001200c20044d0d03200341506a2103200620044105746a220420012903a001370000200441186a2000290300370000200441106a2005290300370000200441086a200b290300370000201441016a2114410021180c010b0b200141b8026a41086a200141e8006a41086a290300370300200141b8026a41106a200141e8006a41106a290300370300200141b8026a41186a200141e8006a41186a290300370300200120012903683703b8020b0240200e450d00201a102a0b200c201041ffffff3f7122032003200c4b1b2211450d022008210b410021050340024020082006460d002008200541057422036a2200200620036a4120109c05450d00411610282203450d0320034100290093a2413700002003410e6a41002900a1a241370000200341086a410029009ba24137000020014296808080e0023702a401200120033602a0012000200141a0016a108f0120012802a801210320012802a0012104200141b8026a41186a22124200370300200141b8026a41106a22134200370300200141b8026a41086a220e4200370300200142003703b80220042003200141b8026a1000200141106a41186a2012290300370300200141106a41106a2013290300370300200141106a41086a200e290300370300200120012903b802370310024020012802a401450d0020012802a001102a0b200141106a41201009201f210303400240202320036b41e0004b0d00024020032023460d000340200b2003460d04200320004120109c05450d042023200341206a2203470d000b0b200120004280809aa6eaafe3014200108202200129030021072001200141086a2903003703a801200120073703a0012001200141a0016a3602900220014190026a109d010c020b20002003460d01200320004120109c05450d01200341206a22042000460d01200420004120109c05450d01200341c0006a22042000460d01200420004120109c05450d01200341e0006a22042000460d0120034180016a2103200420004120109c050d000b0b200b41206a210b200541016a22052011490d000c030b0b41a0a3c1002004200c1034000b411641011037000b2006200c4105746a2103200c2111024002400240200c4104490d00200141a0016a41206a2112200141e0016a2113200141a0016a41e0006a210e200141a0026a210d200141b8016a2104200141b0016a2105200141a8016a210b20032100200c211103402004420037030020054200370300200b4200370300200142003703a001024020122000460d00200041606a200141a0016a4120109c05450d002011417f6a21000c030b2004420037030020054200370300200b4200370300200142003703a001024020132000460d00200041406a200141a0016a4120109c05450d002011417e6a21000c030b2004420037030020054200370300200b4200370300200142003703a0010240200e2000460d00200041a07f6a200141a0016a4120109c05450d002011417d6a21000c030b2004420037030020054200370300200b4200370300200142003703a001200041807f6a210302400240200d2000460d002003200141a0016a4120109c050d010b2011417c6a211120032100200320066b41e0004b0d010c020b0b2011417c6a21000c010b20032006460d012011417f6a2100200141a0016a41206a2104200141b8016a2105200141b0016a210b200141a8016a2111034020054200370300200b420037030020114200370300200142003703a001024020042003460d00200341606a200141a0016a4120109c050d020b2000417f6a21002006200341606a2203470d000c020b0b200041016a210c0b200141bc016a2031360200200141b8016a202f360200200141b4016a2030360200200141a0016a41106a2020360200200141ac016a2021360200200141083a00a001200141a0016a41086a201f360200200141033a00a40141014100200141a0016a10cc0120014190026a41086a22034200370300200142003703900241b0a3c100411220014190026a1008200141e8006a41086a20032903003703002001200129039002370368200141003602a801200142013703a001200c200141a0016a10b4010240200c450d00200c41057421002006210303402003200141a0016a108f01200341206a2103200041606a22000d000b0b20012802a40121032002411020012802a001220020012802a801100702402003450d002000102a0b02402010450d002006102a0b20014190026a41086a22034200370300200142003703900241bf91c600411620014190026a1008200141e8006a41086a220020032903003703002001200129039002370368200120143602a00120024110200141a0016a41041007200342003703002001420037039002418891c600411120014190026a1008200020032903003703002001200129039002370368200141003602a00120024110200141a0016a100621030240024020012802a0012200417f470d00410121030c010b024020030d00410121030c010b20004104490d03200328000021002003102a200041016a21030b20014190026a41086a220042003703002001420037039002418891c600411120014190026a1008200141e8006a41086a20002903003703002001200129039002370368200120033602a00120024110200141a0016a410410070240200aa7450d002008102a0b2019a7450d002017102a0b2016a7450d002015102a0b200141e0026a24000f0b41c4d1c3004133200141d8026a419cd9c3001038000bef0101047f230041206b220224002002410036021020014110200241106a10062101024002400240024020022802102203417f460d0020010d010b200041003602080c010b200220013602082002200336020c20034104490d012002200141046a36020820022003417c6a220436020c20044104490d01200128000021042002200341786a36020c2002200141086a36020820012800042103200241106a200241086a106d20022802102205450d012000200229021437020c2000200536020820002003360204200020043602002001102a0b200241206a24000f0b41c4d1c3004133200241106a419cd9c3001038000bb70201057f230041d0006b220224000240411610282203450d0020034100290093a2413700002003410e6a41002900a1a241370000200341086a410029009ba24137000020024296808080e002370224200220033602202001200241206a108f012002280228210320022802202101200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020012003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b200241306a2002412010c6020240024020022802304101460d00200041003602000c010b20002002290234370204200041013602000b200241d0006a24000f0b411641011037000ba50708027f017e047f027e017f017e037f017e230041d0006b220124000240024002400240024002400240410e10282202450d00200241066a41002900b2a441370000200241002900aca4413700002002410e411c102c2202450d012002410036000e42002103200141286a41186a22044200370300200141286a41106a22054200370300200141286a41086a220642003703002001420037032820024112200141286a1000200141186a2004290300370300200141106a2005290300370300200141086a2006290300370300200120012903283703002002102a2001410036022820014120200141286a100621040240024020012802282202417f470d00410121070c010b2001200236022420012004360220200141286a200141206a107420012802282207450d03200129022c21032002450d002004102a0b02400240410e10282202450d0041002900b2a441210841002900aca4412109410121040340200241066a2008370000200220093700002002410e411c102c2202450d062002200436000e200141286a41186a22054200370300200141286a41106a22064200370300200141286a41086a220a42003703002001420037032820024112200141286a1000200141186a2005290300370300200141106a2006290300370300200141086a200a290300370300200120012903283703002002102a2001410036022820014120200141286a100621060240024020012802282202417f470d00410121054200210b0c010b2001200236022420012006360220200141286a200141206a107420012802282205450d08200129022c210b2002450d002006102a0b200b422088a72206450d0202402003a7220a2003422088a722026b200641216c220c41216d22064f0d00200220066a220d2002490d0a200a410174220e200d200e200d4b1bad220342217e220f422088a70d0a200fa7220d4100480d0a02400240200a0d00200d102821070c010b2007200a41216c200d102c21070b2007450d090b2007200241216c6a2005200c109a051a200342ffffffff0f832103200220066aad422086210f0240200ba7450d002005102a0b200441016a21042003200f842103410e102822020d000b0b410e41011037000b0240200ba7450d002005102a0b2000200337020420002007360200200141d0006a24000f0b410e41011037000b411c41011037000b41c4d1c3004133200141c8006a419cd9c3001038000b411c41011037000b41c4d1c3004133200141c8006a419cd9c3001038000b200d41011037000b1031000bcc0402057f017e230041e0006b220224000240024002400240411310282203450d0020034100290099a4413700002003410f6a41002800a8a441360000200341086a41002900a1a44137000020024293808080b00237022c200220033602282001200241286a108f012001280220210402400240200228022c2201200228023022036b4104490d00200228022821010c010b200341046a22052003490d03200141017422032005200320054b1b22034100480d030240024020010d002003102821010c010b200228022820012003102c21010b2001450d022002200336022c20022001360228200228023021030b2002200341046a360230200120036a20043600002002280230210320022802282101200241386a41186a22044200370300200241386a41106a22054200370300200241386a41086a220642003703002002420037033820012003200241386a1000200241086a41186a2004290300370300200241086a41106a2005290300370300200241086a41086a2006290300370300200220022903383703080240200228022c450d002002280228102a0b20024100360238200241086a4120200241386a100621010240024020022802382203417f460d002002200336022c20022001360228200241386a200241286a10820120022802382204450d05200229023c210702402003450d002001102a0b20002007370204200020043602000c010b20004100360208200042043702000b200241e0006a24000f0b411341011037000b200341011037000b1031000b41c4d1c3004133200241d8006a419cd9c3001038000bf70103017e057f027e420121020240200128020422034104490d0020012802002204280000210520012003417c6a22063602042001200441046a360200200641034d0d00200428000421072001200341786a22063602042001200441086a36020020064110490d00200441106a2900002108200429000821092001200341686a22063602042001200441186a36020020064110490d0020002009370308200041186a2004290018370300200041106a20083703002000412c6a2007360200200041286a2005360200200041206a200441206a2900003703002001200341586a3602042001200441286a360200420021020b200020023703000bd30102027f027e200028022021020240024002400240410410282203450d002003200236000020002802242102200341044108102c2203450d0120032002360004200041086a290300210420002903002105200341084118102c2203450d0220032005370008200341106a2004370000200041186a290300210420002903102105200341184130102c2200450d0320002005370018200041206a2004370000200128020020012802042000412810072000102a0f0b410441011037000b410841011037000b411841011037000b413041011037000b942103157f037e077f230041c0026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d002000200110da032003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00200a200a417f6a220d2000200a4105746a2000200d4105746a4120109c05220e410048220f1b2210200a41016a2211200d200a200f1b220a200020114105746a2000200a4105746a4120109c05220f4100481b220a2000200a4105746a200020104105746a4120109c0522104100481b210a200c200c417f6a220d2000200c4105746a2000200d4105746a4120109c05221141004822121b2213200c4101722214200d200c20121b220c200020144105746a2000200c4105746a4120109c0522124100481b220c2000200c4105746a200020134105746a4120109c0522134100481b210c200b200b417f6a220d2000200b4105746a2000200d4105746a4120109c05221441004822151b2216200b41016a2217200d200b20151b220b200020174105746a2000200b4105746a4120109c05220d4100481b220b2000200b4105746a200020164105746a4120109c0522154100481b210b200f411f76200e411f766a2010411f766a2011411f766a2012411f766a2013411f766a2014411f766a200d411f766a2015411f766a210d0b2000200c4105746a2000200a4105746a4120109c05220e411f76200d6a2000200b4105746a2000200a200c200e410048220e1b220f4105746a4120109c052210411f766a210d2000200b200f20104100481b220b4105746a2000200c200a200e1b22184105746a4120109c05417f4c0d01200b21180c020b2000200110db030c0f0b200d41016a220d410c490d0002402001410176220b450d00200020014105746a41606a210a2000210c0340200441206a41186a220d200c41186a220e290000370300200441206a41106a220f200c41106a2210290000370300200441206a41086a2211200c41086a22122900003703002004200c290000370320200a41086a22132900002119200a41106a2214290000211a200a41186a2215290000211b200c200a290000370000200e201b3700002010201a370000201220193700002015200d2903003700002014200f29030037000020132011290300370000200a2004290320370000200a41606a210a200c41206a210c200b417f6a220b0d000b0b20012018417f736a21184101210a0c010b200d45210a0b0240200a452009724101710d002000200110dc030d0d0b2002450d02201820014f0d0102402002200020184105746a220a4120109c0541004e0d0020002108200121070c040b200441206a41186a2212200041186a220f290000370300200441206a41106a2213200041106a2210290000370300200441206a41086a2214200041086a221129000037030020042000290000370320200a41086a220c2900002119200a41106a220b290000211a200a41186a220d290000211b2000200a290000370000200f201b3700002010201a37000020112019370000200d2012290300370000200b2013290300370000200c2014290300370000200a2004290320370000200441c0016a41186a2217200f290000370300200441c0016a41106a221c2010290000370300200441c0016a41086a22182011290000370300200420002900003703c001200041606a2115200041206a21164100210c2001210b03400240200c200b417f6a220d4f0d002016200c4105746a210a0340200441c0016a200a4120109c05417f4c0d01200a41206a210a200d200c41016a220c470d000b200d210c0b2015200b4105746a210a02400340200c200b417f6a220b4f0d01200441c0016a200a4120109c05210d200a41606a220e210a200d4100480d000b20122016200c4105746a220a41186a220d2900003703002013200a41106a221d2900003703002014200a41086a22062900003703002004200a290000370320200e41286a221e2900002119200e41306a221f290000211a200e41386a2220290000211b200a200e41206a220e290000370000200d201b370000201d201a3700002006201937000020202012290300370000201f2013290300370000201e2014290300370000200e2004290320370000200c41016a210c0c010b0b200020042903c001370000200f20172903003700002010201c2903003700002011201829030037000002402001200c41016a220a490d002000200a4105746a21002001200a6b220141154f0d010c0c0b0b200a20011044000b41a0cec300201820011034000b2007450d010b201820074f0d01200441206a41186a2216200841186a221e290000370300200441206a41106a2217200841106a221f290000370300200441206a41086a221c200841086a222029000037030020042008290000370320200820184105746a220a41086a220c2900002119200a41106a220b290000211a200a41186a220d290000211b2008200a290000370000201e201b370000201f201a37000020202019370000200d2016290300370000200b2017290300370000200c201c290300370000200a2004290320370000200441186a2205201e290000370300200441106a2209201f290000370300200441086a2221202029000037030020042008290000370300200841206a21014100211d2007417f6a220d450d022001210a0340200a20044120109c0541004e0d03200a41206a210a200d201d41016a221d470d000b200d211d0c020b4180cec300410041001034000b4190cec300201820071034000b200820074105746a210c200d210b02400340200c2100200b220a201d4d22060d01200a417f6a210b200041606a220c20044120109c05417f4a0d000b0b0240200a201d490d00200d200a490d0241800121144100210e410021124100210d4100211141800121152001201d4105746a2222210103400240200020016b220a419fc0004b22180d00200a410576220a41807f6a200a2012200e492011200d49220c72220b1b210a0240200b450d002015200a200c1b2115200a2014200c1b21140c010b200a200a41017622156b21140b02402011200d470d00024020150d00200441c0006a220d21110c010b4100210a200441c0006a2211210d2001210c0340200d200a3a0000200d200c20044120109c05417f73411f766a210d200c41206a210c2015200a41016a220a470d000b0b02402012200e470d00024020140d00200441c0016a220e21120c010b200041606a210a4100210c200441c0016a2212210e0340200e200c3a0000200e200a20044120109c05411f766a210e200a41606a210a2014200c41016a220c470d000b0b0240200e20126b220a200d20116b220c200c200a4b1b2213450d002016200120112d00004105746a220a41186a2900003703002017200a41106a290000370300201c200a41086a2900003703002004200a290000370320200120112d00004105746a220a200020122d0000417f734105746a220c290000370000200a41186a200c41186a290000370000200a41106a200c41106a290000370000200a41086a200c41086a290000370000024020134101460d004100210a034020002012200a6a220f2d0000417f734105746a220c20012011200a6a41016a22102d00004105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200120102d00004105746a220c2000200f41016a2d0000417f734105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200a41026a210c200a41016a220b210a200c2013490d000b2012200b6a21122011200b6a21110b200020122d0000417f734105746a220a2004290320370000200a41186a2016290300370000200a41106a2017290300370000200a41086a201c290300370000201241016a2112201141016a21110b200020144105746b20002012200e461b2100200120154105746a20012011200d461b210120180d000b024002402011200d4f0d002000210a034020162001200d417f6a220d2d00004105746a220c41186a220b2900003703002017200c41106a220e290000370300201c200c41086a22002900003703002004200c290000370320200a41606a220a41086a220f2900002119200a41106a2210290000211a200a41186a2212290000211b200c200a290000370000200b201b370000200e201a370000200020193700002012201629030037000020102017290300370000200f201c290300370000200a20042903203700002011200d490d000c020b0b2001210a2012200e4f0d000340200e417f6a220e2d0000210c2016200a41186a220b2900003703002017200a41106a220d290000370300201c200a41086a22012900003703002004200a2900003703202000200c417f734105746a220c41086a220f2900002119200c41106a2210290000211a200c41186a2211290000211b200a200c290000370000200b201b370000200d201a370000200120193700002011201629030037000020102017290300370000200f201c290300370000200c2004290320370000200a41206a210a2012200e490d000b0b20082004290300370000201e2005290300370000201f2009290300370000202020212903003700002007200a20226b410576201d6a22014d0d032016201e2900003703002017201f290000370300201c202029000037030020042008290000370320200820014105746a220a41086a220c2900002119200a41106a220b290000211a200a41186a220d290000211b2008200a290000370000201e201b370000201f201a37000020202019370000200d2016290300370000200b2017290300370000200c201c290300370000200a2004290320370000200720016b220c450d04200c20012001200c4b1b210b2007410376210d200a41206a2100024002402001200c417f6a220c490d002000200c200a200310c402200821000c010b200820012002200310c402200a2102200c21010b200b200d4f2105200141154f0d010c050b0b201d200a1044000b200a200d103c000b4190cec300200120071034000b41dc83c6001032000b20014102490d00200041406a210f410021104101210d0340200d410574210a200d417f6a210b200d41016a210d02402000200a6a220e2000200b4105746a220a4120109c05417f4a0d00200441c0016a41186a2211200e41186a220c290000370300200441c0016a41106a2212200e41106a2213290000370300200441c0016a41086a2214200e41086a22152900003703002004200e2900003703c001200e200a2900003700002015200a41086a2900003700002013200a41106a290000370000200c200a41186a29000037000002400240200b0d004100210b0c010b2010210c200f210a200441c0016a200e41406a4120109c05417f4a0d0002400340200a41d8006a200a41386a290000370000200a41d0006a200a41306a290000370000200a41c8006a200a41286a290000370000200a41c0006a200a41206a290000370000200c4101460d01200441c0016a200a4120109c05210e200c417f6a220b210c200a41606a210a200e4100480d000c020b0b4100210b0b2000200b4105746a220a20042903c001370000200a41186a2011290300370000200a41106a2012290300370000200a41086a20142903003700000b201041016a2110200f41206a210f200d2001470d000b0b200441c0026a24000bd9140a057f017e067f037e037f017e017f027e077f057e23002204210520044180026b4160712204240002400240200141ffffff3f712001470d0020014105742206417f4c0d0002400240024020060d00410121070c010b200610282207450d010b410021084100210602402001450d002001410574210820072106034020062000290000370000200641186a200041186a290000370000200641106a200041106a290000370000200641086a200041086a290000370000200641206a2106200041206a2100200841606a22080d000b200141057441606a41057641016a2106200121080b20042006360218200420083602142004200736021020072006410041202006676b10c40242002109200441b0016a41086a22004200370300200442003703b001419896c300411d200441b0016a1008200441e0016a41086a2000290300370300200420042903b0013703e001200441003602b001200441e0016a4110200441b0016a1006210602400240024020042802b0012200417f460d0020042000360294012004200636029001200441b0016a20044190016a106d20042802b001220a450d0220042902b40121092000450d012006102a0c010b4101210a0b2009422088a72200450d032000410574210b200441e0016a410c6a210c200441e0016a411472210d200441e0016a410872210e200441c0006a410c72210f200a210002400340200041086a2900002110200041106a290000211120002900002112200441206a41186a2213200041186a290000370300200441206a41106a22142011370300200441206a41086a22152010370300200420123703200240024002400240411a10282206450d00200641002900b596432216370000200641186a41002f00cd964322173b0000200641106a41002900c596432218370000200641086a41002900bd964322193700002004429a808080a0033702b401200420063602b0012004200441b0016a3602e001200441206a200441e0016a10c80120042802b001210720042802b801211a200441e0016a41186a22014200370300200441e0016a41106a22064200370300200441e0016a41086a22084200370300200442003703e0012007201a200441e0016a100020044190016a41186a221b200129030037030020044190016a41106a221c200629030037030020044190016a41086a221a2008290300370300200420042903e00137039001024020042802b401450d0020042802b001102a0b200441003602e00120044190016a4120200441e0016a1006211d20042802e0012207417f460d02200420073602642004201d360260200441e0016a200441e0006a10b30320042802e801221e450d01200441b0016a41086a221f200c41086a290200370300200441b0016a41106a2220200c41106a2802003602002004200c2902003703b00120042903e001211002402007450d00201d102a0b200f20042903b00122113702002006202028020022073602002008201f2903002212370300200f41086a2012370200200f41106a2007360200200420113703e001200420103703400c030b411a41011037000b41c4d1c3004133200441d0016a419cd9c3001038000b2006200441b0016a41106a2802003602002008200441b0016a41086a290300370300200420042903b0013703e0014100211e0b2004201e360248200441003602e80120042903582112200420042903f801222137035820042903502122200420042903f001222337035020042903402124200420042903e001221137034020042903482110200420042903e80122253703482025a72107024002402010a7221d0d002025211020232122202121120c010b200420243703e001200420103703e801200420223703f001200420123703f8012004201d2022a74105746a3602bc012004201d3602b80120042010422088a73602b4012004201d3602b0012004200441106a3602c00120044190016a200441b0016a108401200e41086a201a280200360200200e20042903900137020020042022422088a7221d2012422088a74105746a3602bc012004201d3602b80120042012a73602b4012004201d3602b0012004200441106a3602c00120044190016a200441b0016a108401200d41086a201a280200360200200d20042903900137020020042903e801211020042903e001211120042903f801211220042903f001212202402007450d002021a7211d02402025422088a7450d002007102a0b201d450d002023422088a7102a0b200420113703402004201037034820042022370350200420123703582010a721070b2004201137036020042010370368200420223703702004201237037802400240024020070d00200441b0016a41186a2013290300370300200441b0016a41106a2014290300370300200441b0016a41086a2015290300370300200420042903203703b001411a10282207450d0220072016370000200741186a20173b0000200741106a2018370000200741086a20193700002004429a808080a0033702d401200420073602d0012004200441d0016a3602e001200441b0016a200441e0016a10c80120042802d001210720042802d801211d200142003703002006420037030020084200370300200442003703e0012007201d200441e0016a1000201b2001290300370300201c2006290300370300201a2008290300370300200420042903e00137039001024020042802d401450d0020042802d001102a0b20044190016a412010090c010b200441b0016a41186a2013290300370300200441b0016a41106a2014290300370300200441b0016a41086a2015290300370300200420042903203703b001411a10282207450d0320072016370000200741186a20173b0000200741106a2018370000200741086a20193700002004429a808080a0033702d401200420073602d0012004200441d0016a3602e001200441b0016a200441e0016a10c80120042802d001210720042802d801211d200142003703002006420037030020084200370300200442003703e0012007201d200441e0016a1000201b2001290300370300201c2006290300370300201a2008290300370300200420042903e00137039001024020042802d401450d0020042802d001102a0b200441203602e401200420044190016a3602e001200441e0006a200441e0016a10b4030b02402010a72206450d002012a7210802402010422088a7450d002006102a0b2008450d002022422088a7102a0b200041206a2100200b41606a220b0d010c060b0b411a41011037000b411a41011037000b41c4d1c3004133200441d0016a419cd9c3001038000b200641011037000b1036000b02402009a7450d00200a102a0b200441003602e801200442013703e0012003200441e0016a10b40102402003450d002003410574210003402002200441e0016a108f01200241206a2102200041606a22000d000b0b20042802e401210620042802e801210820042802e0012100200441b0016a41086a22014200370300200442003703b00141fbefc200411b200441b0016a1008200441e0016a41086a2001290300370300200420042903b0013703e001200441e0016a411020002008100702402006450d002000102a0b02402004280214450d002004280210102a0b200524000ba50101027f230041206b22032400410021042003410036021420012002200341146a100621010240024020032802142202417f460d002001450d002003410036020c20024104490d0120012800002104200341003602102002417c714104460d01200128000421022001102a200041086a200236020020002004360204410121040b20002004360200200341206a24000f0b41c4d1c3004133200341186a419cd9c3001038000b13002000410a36020420004188a5c1003602000b3400200041fecbc10036020420004100360200200041146a4110360200200041106a4188ccc100360200200041086a42073702000b3001017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241003600000b2201017f230041106b22022400200241003602002000200210ad02200241106a24000b13002000410b360204200041c0e5c1003602000b3101017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241c0003600000b3d01017f02404110102822020d00411041011037000b200242003700082002428080e983b1de16370000200042908080808002370204200020023602000b3201017f02404104102822020d00410441011037000b20004284808080c0003702042000200236020020024180c2033600000b3001017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241013600000b3001017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241063600000b3d01017f02404110102822020d00411041011037000b200242003700082002428080d287e2bc2d370000200042908080808002370204200020023602000b3e01017f02404110102822020d00411041011037000b2002420037000820024280809aa6eaafe301370000200042908080808002370204200020023602000b9f0a01047f230041206b220224000240024002400240024002400240024002400240024002400240024002402001280200417f6a220341094b0d0020030e0a0102030405060708090a010b41c4f7c1001032000b2001410c6a2802002203417f4c0d0a200128020421044101210502402003450d00200310282205450d0c0b200520042003109a0521052000410c6a2003360200200041086a20033602002000200536020420004101360200200041206a200141206a290300370300200041186a2001290318370300200041106a20012902103703000c090b2001410c6a2802002203417f4c0d09200128020421050240024020030d00410121040c010b200310282204450d0c0b200420052003109a0521052000410c6a2003360200200041086a20033602002000200536020420004102360200200041206a200141206a290300370300200041186a2001290318370300200041106a20012902103703000c080b200128020421054101210302400240200141086a22042d00004101460d002002411e6a200441036a2d00003a0000200241086a200141186a290200370300200241106a200141206a290200370300200241186a200141286a2d00003a0000200220042f00013b011c2002200141106a2902003703002001410c6a2802002104410021030c010b2001410c6a28020021040b20002005360204200020022f011c3b0009200041086a20033a00002000410c6a2004360200200041106a20022903003702002000412c6a200129022c3702002000410b6a2002411e6a2d00003a0000200041186a200241086a290300370200200041206a200241106a290300370200200041286a200241186a280200360200200041033602000c070b20004104360200200020012802043602040c060b20004105360200200020012802043602040c050b410121030240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002105410021030c010b200141086a28020021050b200020033a0004200020022f011c3b0005200041306a2001290330370300200041086a20053602002000410c6a2002290300370200200041386a200141386a290300370300200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602002001280228210120004106360200200041286a20013602000c040b20004107360200200020012802043602040c030b410121030240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002101410021030c010b200141086a28020021010b200020033a0004200020022f011c3b000520004108360200200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c020b20004109360200200020012802043602040c010b2000410a360200200020012802043602040b200241206a24000f0b1036000b200341011037000b200341011037000bbf4305047f027e037f017e067f23004190026b22072400200741f0006a41086a220842003703002007420037037041b0a3c1004112200741f0006a1008200741a0016a41086a2008290300370300200720072903703703a0014100210920074100360270200741a0016a4110200741f0006a1006210802402007280270220a417f460d002008450d002007200a36027420072008360270200741306a200741f0006a106c0240024020072802300d00200728023421090c010b410021090b200a450d002008102a0b200741f0006a41086a220842003703002007420037037041b8a2c1004114200741f0006a1008200741a0016a41086a220a2008290300370300200720072903703703a001024002400240200741a0016a41104101410041001003417f460d0041effec1002108412e210a0c010b2008420037030020074200370370418891c6004111200741f0006a1008200a2008290300370300200720072903703703a00120074100360270200741a0016a4110200741f0006a1006210802400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402007280270220a417f470d004100210a0c010b024020080d004100210a0c010b200a4104490d012008280000210a2008102a0b0240200a2003460d00419dffc10021084114210a0c1e0b024020090d0041b1ffc100210841c100210a0c1e0b02402009200241086a2802004f0d0041f2ffc1002108413c210a0c1e0b02402005428080e983b1de165441002006501b450d0041ae80c20021084124210a0c1e0b200741206a2001109d02200741206a41086a290300210b2007290320210c411310282208450d01200c200554200b200654200b2006511b210a200841002900c2a3413700002008410f6a41002800d1a341360000200841086a41002900caa34137000020074293808080b002370274200720083602702001200741f0006a108f012007280278210820072802702109200741a0016a41186a220d4200370300200741a0016a41106a220e4200370300200741a0016a41086a220f4200370300200742003703a00120092008200741a0016a1000200741c0006a41186a200d290300370300200741c0006a41106a200e290300370300200741c0006a41086a200f290300370300200720072903a00137034002402007280274450d002007280270102a0b200b2006200a1b210b200c2005200a1b210620074100360270200741c0006a4120200741f0006a100621080240024002402007280270220a417f460d002008450d002007200a3602a401200720083602a001200741f0006a200741a0016a10c20220072903704201510d0520074180016a29030021052007290378210c0240200a450d002008102a0b410e10282208450d06200841066a41002900b2a441370000200841002900aca4413700002008410e411c102c2208450d072008200441067636000e200741a0016a41186a220a4200370300200741a0016a41106a22094200370300200741a0016a41086a220d4200370300200742003703a00120084112200741a0016a1000200741f0006a41186a200a290300370300200741f0006a41106a2009290300370300200741f0006a41086a200d290300370300200720072903a0013703702008102a200741003602a001200741f0006a4120200741a0016a1006210820072802a001220a417f460d1b2008450d1b2007200a3602dc01200720083602d801200741a0016a200741d8016a107420072802a001220d450d082004413f71210920072902a40121100240200a450d002008102a0b4100210420092010422088a7490d010c190b200741106a20011091012007290310428080e983b1de1656200741186a29030022054200522005501b0d0141e380c20021084134210a0c1f0b200d200941216c6a22082d00004101470d17200741da016a200841036a2d00003a0000200741a0016a41086a200841146a290000370300200741ad016a200841196a290000370000200720082f00013b01d80120072008410c6a2900003703a001200841086a280000210a200841046a2800002108410121040c180b410e10282208450d06200841066a41002900b2a441370000200841002900aca4413700002008410e411c102c2208450d0720082004410676220e36000e200741a0016a41186a220a4200370300200741a0016a41106a22094200370300200741a0016a41086a220d4200370300200742003703a00120084112200741a0016a1000200741c0006a41186a200a290300370300200741c0006a41106a2009290300370300200741c0006a41086a200d290300370300200720072903a0013703402008102a20074100360270200741c0006a4120200741f0006a1006210802402007280270220a417f460d002008450d002007200a3602a401200720083602a001200741f0006a200741a0016a10742007280270220d450d092004413f712109200729027421050240200a450d002008102a0b41002108024020092005422088a74f0d0041014102200d200941216c6a2d00001b21080b02402005a7450d00200d102a0b20084102490d00410e10282208450d0a200841066a41002900b2a441370000200841002900aca4413700002008410e411c102c2208450d0b2008200e36000e42002105200741a0016a41186a220a4200370300200741a0016a41106a22044200370300200741a0016a41086a220d4200370300200742003703a00120084112200741a0016a1000200741c0006a41186a200a290300370300200741c0006a41106a2004290300370300200741c0006a41086a200d290300370300200720072903a0013703402008102a20074100360270200741c0006a4120200741f0006a100621080240024020072802702204417f470d004101210a0c010b024020080d004101210a0c010b200720043602a401200720083602a001200741f0006a200741a0016a10742007280270220a450d0d200729027421052004450d002008102a0b200741c0006a41186a2204200141186a290000370300200741c0006a41106a220d200141106a290000370300200741c0006a41086a220f200141086a2900003703002007200129000037034020092005422088a722114f0d0d200a200941216c6a220841013a000020082007290340370001200841096a200f290300370000200841116a200d290300370000200841196a2004290300370000410e102821080240200a0d002008450d0f200841066a41002900b2a441370000200841002900aca4413700002008410e411c102c2208450d102008200e36000e200741a0016a41186a220a4200370300200741a0016a41106a22094200370300200741a0016a41086a22044200370300200742003703a00120084112200741a0016a1000200741c0006a41186a200a290300370300200741c0006a41106a2009290300370300200741c0006a41086a2004290300370300200720072903a0013703402008102a200741c0006a412010090c170b2008450d10200841066a41002900b2a441370000200841002900aca4413700002008410e411c102c2208450d112008200e36000e200741a0016a41186a22094200370300200741a0016a41106a22044200370300200741a0016a41086a220d4200370300200742003703a00120084112200741a0016a1000200741c0006a41186a2009290300370300200741c0006a41106a2004290300370300200741c0006a41086a200d290300370300200720072903a0013703402008102a200741203602742007200741c0006a360270200a2011200741f0006a10ab022005a7450d16200a102a0c160b200741f0006a41086a2208420037030020074200370370419991c6004114200741f0006a1008200741a0016a41086a2008290300370300200720072903703703a0014100210a20074100360270200741a0016a4110200741f0006a10062108024020072802702209417f460d002008450d0020094104490d122008280000210a2008102a0b410e10282208450d12200841066a41002900b2a441370000200841002900aca4413700002008410e411c102c2208450d132008200a36000e200741a0016a41186a22094200370300200741a0016a41106a22044200370300200741a0016a41086a220d4200370300200742003703a00120084112200741a0016a1000200741c0006a41186a2009290300370300200741c0006a41106a2004290300370300200741c0006a41086a200d290300370300200720072903a0013703402008102a20074100360270200741c0006a4120200741f0006a1006210802400240024020072802702209417f460d002008450d002007200936027420072008360270200741086a200741f0006a106c0240024020072802080d00200728020c210d410021040c010b4101210441b8aec600210d0b02402009450d002008102a0b20040d00200d413f460d01200d0d170b200741f0006a2001428080d287e2bc2d4200410810980220072802704101470d012007280278210a200728027421080c1f0b200741f0006a41086a2208420037030020074200370370419991c6004114200741f0006a1008200741a0016a41086a2008290300370300200720072903703703a0012007200a41016a360270200741a0016a4110200741f0006a410410070c150b20072903782105200720074180016a29030037037820072005370370200b2006428080aef89dc3527c2205200654ad7c427f7c210b2007200741f0006a3602a001200741a0016a109d01200521060c140b41c4d1c3004133200741c0016a419cd9c3001038000b411341011037000b41c4d1c3004133200741c0016a419cd9c3001038000b410e41011037000b411c41011037000b41c4d1c3004133200741c0016a419cd9c3001038000b410e41011037000b411c41011037000b41c4d1c3004133200741c0016a419cd9c3001038000b410e41011037000b411c41011037000b41c4d1c3004133200741c0016a419cd9c3001038000b41a0a3c100200920111034000b410e41011037000b411c41011037000b410e41011037000b411c41011037000b41c4d1c3004133200741c0016a419cd9c3001038000b410e41011037000b411c41011037000b200741f9006a200141086a29000037000020074181016a200141106a29000037000020074189016a200141186a290000370000200741013a00702007200129000037007102400240024002400240024002400240024002400240024002400240024002400240410e10282208450d00200841066a41002900b2a441370000200841002900aca4413700002008410e411c102c2208450d012008200a36000e200741a0016a41186a22094200370300200741a0016a41106a22044200370300200741a0016a41086a220d4200370300200742003703a00120084112200741a0016a1000200741c0006a41186a2009290300370300200741c0006a41106a2004290300370300200741c0006a41086a200d290300370300200720072903a0013703402008102a200741003602a001200741c0006a4120200741a0016a100621080240024020072802a0012204417f460d002004210920080d010b200741003602a801200742013703a0014100200741a0016a10b40120072802a801210920072802a401210420072802a00121080b200720093602682007200436026420072008360260024002402009450d00200741a0016a20082009410110d60220072802a0014101470d012007280264450d122007280260102a0c120b4101200741e0006a10b401024020072d00704101460d0002400240200728026420072802682208460d00200728026021090c010b200841016a22092008490d1b200841017422042009200420094b1b22044100480d1b0240024020080d002004102821090c010b200728026020082004102c21090b2009450d052007200436026420072009360260200728026821080b2007200841016a360268200920086a41003a00000c100b02400240200728026420072802682208460d00200728026021090c010b200841016a22092008490d1a200841017422042009200420094b1b22044100480d1a0240024020080d002004102821090c010b200728026020082004102c21090b2009450d052007200436026420072009360260200728026821080b2007200841016a360268200920086a41013a0000200741f0006a410172200741e0006a108f010c0f0b20072802a401210d0240200741ac016a2802002208200741a8016a2802002209460d002007280268200820096b6a220441216a220e417f4c0d0502400240200e0d004101210f0c010b200e1028220f450d070b2007200e3602c4012007200f3602c001200720043602c8012007200741c0016a3602a001200d200741a0016a200810d70120042008490d0720072802c801220d2004490d082007280268220d2009490d0920072802c001210e2007280260210f2007200420086b22043602d0012007200d20096b220d3602d4012004200d470d0a200e20086a200f20096a2004109a051a0240024020072d00704101460d000240024020072802c40120072802c8012208460d0020072802c00121090c010b200841016a22092008490d1c200841017422042009200420094b1b22044100480d1c0240024020080d002004102821090c010b20072802c00120082004102c21090b2009450d0e200720043602c401200720093602c00120072802c80121080b2007200841016a3602c801200920086a41003a00000c010b0240024020072802c40120072802c8012208460d0020072802c00121090c010b200841016a22092008490d1b200841017422042009200420094b1b22044100480d1b0240024020080d002004102821090c010b20072802c00120082004102c21090b2009450d0e200720043602c401200720093602c00120072802c80121080b2007200841016a3602c801200920086a41013a0000200741f0006a410172200741c0016a108f010b20072802c801210920072802c401210420072802c00121082007280264450d102007280260102a0c100b2007200741e0006a3602a001200d200741a0016a200910d701024020072d00704101460d0002400240200728026420072802682208460d00200728026021090c010b200841016a22092008490d1a200841017422042009200420094b1b22044100480d1a0240024020080d002004102821090c010b200728026020082004102c21090b2009450d0e2007200436026420072009360260200728026821080b2007200841016a360268200920086a41003a00000c0f0b02400240200728026420072802682208460d00200728026021090c010b200841016a22092008490d19200841017422042009200420094b1b22044100480d190240024020080d002004102821090c010b200728026020082004102c21090b2009450d0e2007200436026420072009360260200728026821080b2007200841016a360268200920086a41013a0000200741f0006a410172200741e0006a108f010c0e0b410e41011037000b411c41011037000b200441011037000b200441011037000b1036000b200e41011037000b200820041044000b2004200d103c000b2009200d1044000b200741f0016a41146a4108360200200741fc016a4125360200200741d8016a41146a4103360200200742033702dc01200741c8afc6003602d801200741253602f4012007200741d0016a360288022007200741d4016a36028c02200742043703b001200742013702a4012007419cb0c6003602a0012007200741f0016a3602e8012007200741a0016a3602800220072007418c026a3602f801200720074188026a3602f001200741d8016a41d8b0c600103e000b200441011037000b200441011037000b200441011037000b200441011037000b2007280268210920072802642104200728026021080b2008450d00200741c0006a41202008200910072004450d012008102a0c010b024002400240412110282208450d0041002109024020072d00704101470d00200741b8016a20074189016a290000370300200741b0016a20074181016a290000370300200741a8016a200741f9006a290000370300200720072900713703a001410121090b200820093a0000200820072903a001370001200841096a200741a8016a290300370000200841116a200741b0016a290300370000200841196a200741b8016a290300370000410e10282209450d01200941066a41002900b2a441370000200941002900aca4413700002009410e411c102c2209450d022009200a36000e200741a0016a41186a220a4200370300200741a0016a41106a22044200370300200741a0016a41086a220d4200370300200742003703a00120094112200741a0016a1000200741c0006a41186a200a290300370300200741c0006a41106a2004290300370300200741c0006a41086a200d290300370300200720072903a0013703402009102a200741203602a4012007200741c0006a3602a00120084101200741a0016a10ab022008102a0c030b412141011037000b410e41011037000b411c41011037000b20072001428080e983b1de164200108302024020072802002208450d002007280204210a0c080b200741f0006a41086a220842003703002007420037037041ad91c6004112200741f0006a1008200741a0016a41086a2008290300370300200720072903703703a0014100210a20074100360270200741a0016a4110200741f0006a100621080240024020072802702209417f460d002008450d0020094104490d012008280000210a2008102a0b4200210c200741f0006a41086a220842003703002007420037037041ad91c6004112200741f0006a1008200741a0016a41086a2008290300370300200720072903703703a0012007200a41016a360270200741a0016a4110200741f0006a41041007420021050c060b41c4d1c3004133200741c0016a419cd9c3001038000b0b02402010a7450d00200d102a2004450d010c020b20040d010b410121094113210a419781c20021080c010b200741c0016a41026a200741d8016a41026a2d00003a0000200741f0006a41086a200741a0016a41086a290300370300200741f0006a410d6a200741a0016a410d6a290000370000200720072f01d8013b01c001200720072903a001370370410021090b200741e0006a41026a2204200741c0016a41026a2d00003a0000200741f0016a41086a220d200741f0006a41086a290300370300200741f0016a41106a200741f0006a41106a290300370300200720072f01c0013b0160200720072903703703f00120090d02200741d3006a200d290300370000200741d8006a200741fd016a290000370000200720072f01603b01402007200a36004720072008360043200720072903f00137004b200720042d00003a0042200741c0006a2001460d00200741c0006a20014120109c05450d0041d280c20021084111210a0c020b200742f0f2bda9c6add9b1f400370338200741386a20012006200b417f410f10a902200741f0006a41186a200b3703002007200637038001200720053703782007200c370370200720033602940120072003360290010240024002400240411310282208450d00200841002900c2a3413700002008410f6a41002800d1a341360000200841086a41002900caa34137000020074293808080b0023702f401200720083602f0012001200741f0016a108f0120072802f801210820072802f001210a200741a0016a41186a22094200370300200741a0016a41106a22034200370300200741a0016a41086a22044200370300200742003703a001200a2008200741a0016a1000200741c0006a41186a2009290300370300200741c0006a41106a2003290300370300200741c0006a41086a2004290300370300200720072903a001370340024020072802f401450d0020072802f001102a0b200741203602a4012007200741c0006a3602a001200741f0006a200741a0016a10c3022002280204210f20022802002103024002400240200241086a280200220941057622120d0041042113410421140c010b2012410274220810282213450d01201321140b2009450d030240024020120d00410410282213450d0141012112201321140b201441003602002009417f6a210441012115410021084100210a024003402014200a4102746a2202200320086a2d00002008411f717420022802006a360200024002400240024020042008460d00200841016a2202411f710d0320152012470d02201541016a220d2015490d0c2015410174220e200d200e200d4b1b221241ffffffff03712012470d0c2012410274220d41004e0d010c0c0b0240200f450d002003102a0b41002116024002400240024003402015410820154108491b220a410274220f10282208450d0120082014200f109a052111200741f0006a41186a200141186a290000370300200741f0006a41106a200141106a290000370300200741f0006a41086a200141086a290000370300200720163602900120072001290000370370411310282208450d0220084100290099a4413700002008410f6a41002800a8a441360000200841086a41002900a1a44137000020074293808080b0023702f401200720083602f001200741f0006a200741f0016a108f0120072802900121090240024020072802f401220220072802f80122086b4104490d0020072802f00121020c010b200841046a22032008490d11200241017422082003200820034b1b22084100480d110240024020020d002008102821020c010b20072802f00120022008102c21020b2002450d04200720083602f401200720023602f00120072802f80121080b2007200841046a3602f801200220086a200936000020072802f801210820072802f0012102200741a0016a41186a22094200370300200741a0016a41106a22034200370300200741a0016a41086a22044200370300200742003703a00120022008200741a0016a1000200741c0006a41186a2009290300370300200741c0006a41106a2003290300370300200741c0006a41086a2004290300370300200720072903a001370340024020072802f401450d0020072802f001102a0b2015200a6b21152014200f6a2114410021082007410036027820074201370370200a200741f0006a10b4014100200728027822046b210a200728027421030340200420086a2109201120086a280200210d024002402003200a6a4104490d00200728027021020c010b200941046a22022009490d122003410174220e2002200e20024b1b220e4100480d120240024020030d00200e102821020c010b20072802702003200e102c21020b2002450d062007200e36027420072002360270200e21030b2007200941046a360278200220046a20086a200d360000200a417c6a210a200f200841046a2208470d000b200741c0006a41202002200420086a100702402003450d002002102a0b2011102a201641016a211620150d000b410021082012450d0e2013102a0c0e0b200f41041037000b411341011037000b200841011037000b200e41011037000b0240024020150d00200d102821130c010b20132015410274200d102c21130b2013450d03201321140b201420154102746a4100360200200a41016a210a201541016a21150b200920024d0d05200221082015200a4b0d000b41a0a3c100200a20151034000b200d41041037000b410441041037000b200841041037000b411341011037000b41cca2c100200841016a20091034000b0240200f450d002003102a0b410021080b0c020b1031000b200241046a280200450d002002280200102a0b2000200a3602042000200836020020074190026a24000b810f03037f017e097f23004190016b2202240002400240024002400240024002400240024002400240410e10282203450d00200341066a41002900b2a441370000200341002900aca4413700002003410e411c102c2203450d0120032001410676220436000e42002105200241f0006a41186a22064200370300200241f0006a41106a22074200370300200241f0006a41086a220842003703002002420037037020034112200241f0006a1000200241086a41186a2006290300370300200241086a41106a2007290300370300200241086a41086a2008290300370300200220022903703703082003102a20024100360238200241086a4120200241386a100621030240024020022802382207417f470d00410121060c010b024020030d00410121060c010b2002200736027420022003360270200241386a200241f0006a107420022802382206450d03200229023c21052007450d002003102a0b2001413f7122032005422088a722074f0d032006200341216c6a220341003a000020032002290038370001200341096a200241c0006a290000370000200341116a200241c8006a290000370000200341196a200241d0006a290000370000410e10282203450d04200341066a41002900b2a441370000200341002900aca4413700002003410e411c102c2203450d052003200436000e200241f0006a41186a22044200370300200241f0006a41106a22084200370300200241f0006a41086a220142003703002002420037037020034112200241f0006a1000200241086a41186a2004290300370300200241086a41106a2008290300370300200241086a41086a2001290300370300200220022903703703082003102a2002412036023c2002200241086a36023820062007200241386a10ab0202402005a7450d002006102a0b200241386a41086a220342003703002002420037033841ad91c6004112200241386a1008200120032903003703002002200229033837037020024100360238200241f0006a4110200241386a10062103417f2106024020022802382201417f460d002003450d0020014104490d07200328000021062003102a2006417f6a21060b200241386a41086a220442003703002002420037033841ad91c6004112200241386a1008200241f0006a41086a220720042903003703002002200229033837037020022006360238200241f0006a4110200241386a41041007200241386a41186a2208200041186a2209290000370300200241386a41106a220a200041106a220b2900003703002004200041086a220c2900003703002002410036025820022000290000370338200241286a200241386a10c10202402002280230450d0041012106034020082009290000370300200a200b2900003703002004200c29000037030020022006417f6a36025820022000290000370338411310282203450d0920034100290099a4413700002003410f6a41002800a8a441360000200341086a41002900a1a44137000020024293808080b00237026420022003360260200241386a200241e0006a108f012002280258210d0240024020022802642201200228026822036b4104490d00200228026021010c010b200341046a220e2003490d0c20014101742203200e2003200e4b1b22034100480d0c0240024020010d002003102821010c010b200228026020012003102c21010b2001450d0b2002200336026420022001360260200228026821030b2002200341046a360268200120036a200d3600002002280268210320022802602101200241f0006a41186a220d4200370300200241f0006a41106a220e4200370300200742003703002002420037037020012003200241f0006a1000200241086a41186a200d290300370300200241086a41106a200e290300370300200241086a41086a20072903003703002002200229037037030802402002280264450d002002280260102a0b200241086a412010090240200228022c450d002002280228102a0b20082009290000370300200a200b2900003703002004200c2900003703002002200029000037033820022006360258200641016a2106200241286a200241386a10c10220022802300d000b0b0240200228022c450d002002280228102a0b411310282203450d0a200341002900c2a3413700002003410f6a41002800d1a341360000200341086a41002900caa34137000020024293808080b00237023c200220033602382000200241386a108f012002280240210320022802382106200241f0006a41186a22014200370300200241f0006a41106a22004200370300200241f0006a41086a220442003703002002420037037020062003200241f0006a1000200241086a41186a2001290300370300200241086a41106a2000290300370300200241086a41086a2004290300370300200220022903703703080240200228023c450d002002280238102a0b200241086a4120100920024190016a24000f0b410e41011037000b411c41011037000b41c4d1c3004133200241e0006a419cd9c3001038000b41a0a3c100200320071034000b410e41011037000b411c41011037000b41c4d1c3004133200241e0006a419cd9c3001038000b411341011037000b200341011037000b1031000b411341011037000bd40201027f0240024002402002450d002002417f6a2104024020012d0000220241037122054103460d000240024020050e03040001040b2004450d0220012d0001410874200272220241ffff0371418002490d02200241fcff037141027621020c040b20044103490d0120012f0001200141036a2d000041107472410874200272220241808004490d01200241027621020c030b200241034b0d0020044104490d002001280001220241ffffffff034b0d020b200041013602000f0b200241027621020b0240200220036a220120024f0d00200041013602000f0b41012103410121050240200241c000490d0041022105200241808001490d00410441052002418080808004491b21050b0240200141c000490d0041022103200141808001490d00410441052001418080808004491b21030b20002001360204200041003602002000410c6a2003360200200041086a20053602000b130020004101360204200041f486c2003602000b3400200041f487c20036020420004100360200200041146a4107360200200041106a418488c200360200200041086a420f3702000b2201017f230041106b22022400200241003602002000200210da02200241106a24000bd60201037f0240024002400240024002400240024002400240024002400240024020012802000e0400010203000b41012102410110282201450d05200141003a0000410121030c040b410110282202450d05200241013a000020012802042103200241014105102c2202450d062002200336000120012802082104410a210320024105410a102c2201450d07200120043600050c020b41012102410110282201450d07200141023a0000410121030c020b410110282202450d07200241033a000020012802042103200241014105102c2202450d082002200336000120012802082104410a210320024105410a102c2201450d09200120043600050b410921020b2000200236020820002003360204200020013602000f0b410141011037000b410141011037000b410541011037000b410a41011037000b410141011037000b410141011037000b410541011037000b410a41011037000b130020004101360204200041cc92c2003602000b34002000419596c20036020420004100360200200041146a4107360200200041106a419c96c200360200200041086a42073702000b130020004101360204200041aca3c2003602000b890201057f230041106b22022400024002400240411110282203450d002002421137020420022003360200410d200210b4010240024020022802042204200228020822036b410d490d002003410d6a2105200228020021040c010b2003410d6a22052003490d03200441017422062005200620054b1b22064100480d030240024020040d002006102821040c010b200228020020042006102c21040b2004450d0220022006360204200220043602000b20022005360208200420036a22034100290082a542370000200341056a4100290087a54237000020002002290300370200200041086a2002280208360200200241106a24000f0b411141011037000b200641011037000b1031000bce04010b7f230041106b220324002003420037030820012002200341086a102720032003290308370300200120026a21040240024002400240200241086a220520024f0d00200341086a2106200321074100210841002105410121094100210a0340200841017421022006200741016a220b6b210c034020072d00002107024002400240024020082005470d00200c2105024002400240200a41ff01710e03010200010b200420016b21050c010b417f200c200420016b6a22052005200c491b21050b2008417f200541016a220d200d2005491b6a22052008490d0920022005200220054b1b22054100480d090240024020080d002005102821090c010b200920082005102c21090b2009450d010b200920086a20073a00000240024002400240200a41ff01710e03010300010b20042001460d010c050b0240200b2006460d004100210a0c040b20042001470d040b200841016a21080c070b4101210a200b2006470d01200841016a21080c060b200541011037000b200841016a2108200b21070c020b200841016a21084102210a200241026a21022001220741016a21010c000b0b0b4101210902402005450d0020054100480d03200510282209450d020b410021080340200920086a200320086a2d00003a0000200841016a22084108470d000b024020020d00410821080c010b200920086a210a410021080340200a20086a200120086a2d00003a00002002200841016a2208470d000b200420016b41086a21080b200020083602082000200536020420002009360200200341106a24000f0b200541011037000b1031000bc30401047f230041206b22022400024002400240024002400240410110282203450d00200320012d00003a0000200341014102102c2203450d01200320012d00013a0001200341024104102c2203450d02200320012d00023a0002200320012d00033a0003200341044108102c2203450d03200320012d00043a0004200320012d00053a0005200320012d00063a0006200320012d00073a0007200341084110102c2203450d04200320012d00083a0008200320012d00093a0009200320012d000a3a000a200320012d000b3a000b200320012d000c3a000c200320012d000d3a000d200320012d000e3a000e200320012d000f3a000f200341104120102c2203450d05200320012d00103a0010200320012d00113a0011200320012d00123a0012200320012d00133a0013200320012d00143a0014200320012d00153a0015200320012d00163a0016200320012d00173a0017200320012d00183a0018200320012d00193a0019200320012d001a3a001a200320012d001b3a001b200320012d001c3a001c200320012d001d3a001d200320012d001e3a001e200320012d001f3a001f200241186a22014200370300200241106a22044200370300200241086a22054200370300200242003703002003412020021000200041186a2001290300370000200041106a2004290300370000200041086a2005290300370000200020022903003700002003102a200241206a24000f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000bd40201087f230041206b2203240020034100360208200342013703002001200310b401024002400240024020010d002003280208210420032802042105200328020021060c010b200141246c210720032802042105200328020821010340200341106a200010ec012003280210210802400240200520016b20032802182209490d00200120096a2104200328020021060c010b200120096a22042001490d04200541017422062004200620044b1b220a4100480d040240024020050d00200a102821060c010b20032802002005200a102c21060b2006450d032003200a36020420032006360200200a21050b20032004360208200620016a20082009109a051a02402003280214450d002008102a0b200041246a2100200421012007415c6a22070d000b0b2002280200200228020420062004100702402005450d002006102a0b200341206a24000f0b200a41011037000b1031000b130020004103360204200041a0a5c2003602000b340020004185acc20036020420004100360200200041146a4103360200200041106a4190acc200360200200041086a42083702000b130020004104360204200041a8b0c2003602000b0b00200041a0c21e10e6020b3001017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200220013600000b3201017f02404104102822020d00410441011037000b20004284808080c0003702042000200236020020024180e1013600000b0b00200041d0860310e6020bdd0301047f230041d0026b2202240002400240024002400240411210282203450d00200341106a41002f008086423b0000200341086a41002900f88542370000200341002900f08542370000200341124124102c2203450d0120032001360012200241e8016a41186a22014200370300200241e8016a41106a22044200370300200241e8016a41086a22054200370300200242003703e80120034116200241e8016a1000200241e8006a41186a2001290300370300200241e8006a41106a2004290300370300200241e8006a41086a2005290300370300200220022903e8013703682003102a200241003602e801200241e8006a4120200241e8016a1006210120022802e8012203417f460d032002200336020c20022001360208200241e8016a200241086a10810220022903e8014201510d0220024188016a200241e8016a41086a41e000109a051a02402003450d002001102a0b200241086a20024188016a41e000109a051a200241e8016a200241086a41e000109a051a20004201370300200041086a200241e8016a41e000109a051a0c040b411241011037000b412441011037000b41c4d1c300413320024188016a419cd9c3001038000b200241e8016a200241086a41e000109a051a200042003703000b200241d0026a24000bc06709017f017e017f027e157f017e037f017e037f230041a0056b2201240010eb020240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020004101460d0042002102200141206a41086a2200420037030020014200370320418efcc5004110200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a100621000240024002400240024002400240024002400240024020012802e8032203417f460d002000450d0020034108490d01200029000021022000102a0b42002104200141206a41086a220042003703002001420037032041dffbc500410f200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a10062100024020012802e8032203417f460d002000450d0020034108490d02200029000021042000102a0b42002105200141206a41086a220042003703002001420037032041fefbc5004110200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a10062100024020012802e8032203417f460d002000450d0020034108490d03200029000021052000102a0b420020022005200442c8017e7c7d220420042002561b42c801540d0a200141206a41086a2200420037030020014200370320419499c6004114200141206a100820014188036a41086a2000290300370300200120012903203703880341002106200141003602e80320014188036a4110200141e8036a10062100024020012802e8032203417f460d002000450d0020034104490d04200028000021062000102a0b200141206a41086a220042003703002001420037032041a899c6004115200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a100621000240024020012802e8032203417f470d00410221070c010b024020000d00410221070c010b2003450d0520002d000021072000102a0b10fb01210820014188036a41086a22004200370300200142003703880341c2e1c000410d20014188036a1008200141e8036a41086a200029030037030020012001290388033703e80320014100360220200141e8036a4110200141206a100621000240024020012802202203417f460d002000450d00200120033602a401200120003602a001200141206a200141a0016a107c20012802202209450d07200129022421052003450d012000102a0c010b41012109420021050b200141206a41086a220042003703002001420037032041c785c2004112200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a100621000240024020012802e8032203417f460d002000450d002001200336022420012000360220200141e8036a200141206a106d20012802e803220a450d0820012902ec0321042003450d012000102a0c010b4101210a420021040b02402004422088a722000d004108210b4100210c4100210d0c0a0b2000410574210e200141e8036a41206a210f4100210c4100210d4108210b41002103200a2100034020014188026a41186a2210200041186a29000037030020014188026a41106a2211200041106a29000037030020014188026a41086a2212200041086a2900003703002001200029000037038802200141e8036a2008200310fc0120012802e803221320012802f00341014100410010032114024020012802ec03450d002013102a0b02402014417f470d00200141206a41186a22142010290300370300200141206a41106a22132011290300370300200141206a41086a221520122903003703002001200129038802370320200141e8036a200141206a10ec02200128028804450d09200141206a41286a2216200141e8036a41286a290300370300200141206a41206a2217200f2903003703002014200141e8036a41186a22182903003703002013200141e8036a41106a22192903003703002015200141e8036a41086a221a290300370300200120012903e8033703202018201029030037030020192011290300370300201a201229030037030020012001290388023703e803200f2001290320370300200f41086a2015290300370300200f41106a2013290300370300200f41186a2014290300370300200f41206a2017290300370300200f41286a20162903003703000240200c200d470d00200c41016a2214200c490d26200c41017422102014201020144b1b220dad42d0007e2202422088a70d262002a722144100480d2602400240200c0d0020141028210b0c010b200b200c41d0006c2014102c210b0b200b450d0b0b200b200c41d0006c6a200141e8036a41d000109a051a200c41016a210c0b200341016a2103200041206a2100200e41606a220e450d0a0c000b0b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b41f187c1004192021050000b201441081037000b02402004a7450d00200a102a0b02400240200c450d002001410036022820014201370320200141f8036a200c360200200141f4036a200d3602002001200b3602f003200120054220883e02ec03200120083602e803200141206a200141e8036a10c5012005a7450d012009102a0c010b02402005a7450d002009102a0b200d450d00200b102a0b200141206a41086a220042003703002001420037032041f5b6c2004112200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a1006210b024002400240024002400240024002400240024002400240024002400240024002400240024020012802e8032216417f460d00200b450d00200120163602ac022001200b3602a802200141086a200141a8026a106c20012802080d2b20012802ac02220f41807f712200417f4c0d14200128020c211202400240200f41077622140d00410121150c010b200010282215450d100b02402012450d00200141e8036a41206a2113200141a0016a41017221084100210c0340200141003a00c001200c41016a210e4100210002400240024002400340200f2000460d01200141a0016a20006a20012802a80222032d00003a00002001200341016a3602a8022001200041016a22033a00c0012003210020034120470d000b20014188026a41086a2200200141a0016a41086a29030037030020014188026a41106a2210200141a0016a41106a29030037030020014188026a41186a2211200141a0016a41186a290300370300200120012903a001370388022001200f20036b3602ac02200141a0016a200141a8026a10e80120012d00a0014101460d01200141e8036a41186a2011290300370300200141e8036a41106a2010290300370300200141e8036a41086a200029030037030020012001290388023703e8032013200841e000109a051a200141206a200141e8036a418001109a051a2014200c470d03200c4101742200200e2000200e4b1b221441ffffff0f712014470d322014410774220041004e0d020c320b200141003602ac02200041ff0171450d00200141003a00c0010b2014450d2f2015102a0c2f0b02400240200c0d002000102821150c010b2015200c4107742000102c21150b2015450d050b2015200c4107746a200141206a418001109a051a200e2012460d0120012802ac02210f200e210c0c000b0b2015450d2b2012ad42208621022014ad210402402016450d00200b102a0b2002200484211b0c010b410121154200211b0b4100210002400240201b422088a72218410774220c0d004101211c4100211d0c010b200c41027622031028221c450d0d201841ffffff0f71211d0b200741ff0171210e02402018450d002018410774210f201c210020152103034020002003290000370000200041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a290000370000200041206a210020034180016a2103200f41807f6a220f0d000b201841077441807f6a41077641016a21000b200e410247210f200141206a41086a220342003703002001420037032041c785c2004112200141206a100820014188036a41086a20032903003703002001200129032037038803200141003602f003200142013703e8032000200141e8036a10b40102402000450d0020004105742103201c210003402000200141e8036a108f01200041206a2100200341606a22030d000b0b2007200f71211a20012802ec03210020014188036a411020012802e803220320012802f003100702402000450d002003102a0b0240201a450d00200141206a41086a220042003703002001420037032041bd99c600411a200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a1006210020012802e8032203417f460d002000450d002001200336022420012000360220200141e8036a200141206a10820120012802e803220f450d0c20012902ec03210202402003450d002000102a0b20014188036a411010092002a7450d00200f102a0b200141106a200641026a10ed02024002402001280210221e0d00200141206a41086a220042003703002001420037032041c785c2004112200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a10062100024020012802e8032203417f460d002000450d002001200336022420012000360220200141e8036a200141206a106d20012802e803220d450d0d20012902ec03211f02402003450d002000102a0b410021200c020b410021204101210d4200211f0c010b410121202001290214211f201e210d0b200141206a41086a2200420037030020014200370320419499c6004114200141206a100820014188036a41086a20002903003703002001200129032037038803410121162001200641016a22063602e80320014188036a4110200141e8036a41041007200120203a001f20012015200c6a22073602ec04200120153602e8042001200141e8046a3602fc0420012001411f6a3602f8044100210e410021210240201f422088a722004105742203450d002003410575222141ffffff0f712021470d2b202141077422034100480d2b200310282216450d0a0b02402000450d002000410574210c200141206a410172210b200141e8036a41206a2108200141a8026a41c0006a2119200141a8026a41206a21174100210e20162114200d21000340200041086a2900002102200041106a29000021042000290000210520014188026a41186a2210200041186a29000037030020014188026a41106a2211200437030020014188026a41086a22122002370300200120053703880220014188056a20014188026a108b02200128029005210f2001280288052103200141003602202003200f200141206a1006210f0240024020012802202213417f460d00200f450d002001201336028c032001200f36028803200141206a20014188036a10e80120012d00204101460d0c200141a0016a200b41e000109a051a02402013450d00200f102a0b20014188036a200141a0016a41e000109a051a200141206a20014188036a41e000109a051a200141a0016a200141206a41e000109a051a4101210f0c010b200141206a20014188036a41e000109a051a4100210f0b0240200128028c05450d002003102a0b02400240200f0d00200141a8026a410041e0001099051a0c010b200141a8026a200141a0016a41e000109a051a0b024020012802f8042d00000d0020012802fc04220f2802002203200f280204460d00200f20034180016a36020002400240200141a8026a200341206a220f460d00200f200141a8026a4120109c050d010b02402017200341c0006a220f460d00200f20174120109c050d010b2019200341e0006a2203460d01200320194120109c05450d010b20012802f80441013a00000b200041206a2100200141e8036a41186a2010290300370300200141e8036a41106a2011290300370300200141e8036a41086a201229030037030020012001290388023703e8032008200141a8026a41e000109a051a200e41016a210e2014200141e8036a418001109a054180016a2114200c41606a220c0d000b0b0240201fa7450d00200d102a0b200e41ffffff0f71200e470d12200e4107742200417f4c0d1220012d001f21120240024020000d00410121110c010b200010282211450d080b410021000240200e450d002016200e4107746a2110200141e8036a41e0006a2103200141e8036a41c0006a210f200141e8036a41206a210c20112114201621000340200141e8036a41186a200041186a290000370300200141e8036a41106a200041106a290000370300200141e8036a41086a200041086a290000370300200120002900003703e803200c41186a200041386a290000370000200c41106a200041306a290000370000200c41086a200041286a290000370000200c200041206a290000370000200f41186a200041d8006a290000370000200f41106a200041d0006a290000370000200f41086a200041c8006a290000370000200f200041c0006a2900003700002003200041e0006a290000370000200341086a200041e8006a290000370000200341106a200041f0006a290000370000200341186a200041f8006a2900003700002014200141e8036a418001109a054180016a211420004180016a22002010470d000b200e41077441807f6a41077641016a21000b200141206a41086a220342003703002001420037032041f5b6c2004112200141206a100820014188036a41086a20032903003703002001200129032037038803200141003602f003200142013703e8032000200141e8036a10b40102402000450d00201120004107746a21032011210003402000200141e8036a108f01200041206a200141e8036a108f01200041c0006a200141e8036a108f01200041e0006a200141e8036a108f0120004180016a22002003470d000b0b20012802ec03210020014188036a411020012802e803220320012802f003100702402000450d002003102a0b0240200e450d002011102a0b200120123a00e803200141206a41086a220042003703002001420037032041a899c6004115200141206a100820014188036a41086a2000290300370300200120012903203703880320014188036a4110200141e8036a41011007200120063602ec03200141043a00e80341014100200141e8036a10cc01410810282203450d0620032007360204200320153602000240201a0d0042002102200141206a41086a220042003703002001420037032041e194c600411c200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a10062100024020012802e803220f417f460d002000450d00200f4108490d07200029000021022000102a0b200141206a41086a2200420037030020014200370320419499c6004114200141206a100820014188036a41086a200029030037030020012001290320370388034100210f200141003602e80320014188036a4110200141e8036a10062100024020012802e803220c417f460d002000450d00200c4104490d062000280000210f2000102a0b411c10282200450d04200041186a41002800959546360000200041106a410029008d9546370000200041086a41002900859546370000200041002900fd94463700002000411c4138102c2200450d032000200237001c20014188026a41186a220c420037030020014188026a41106a2214420037030020014188026a41086a2210420037030020014200370388022000412420014188026a1000200141e8036a41186a200c290300370300200141e8036a41106a2014290300370300200141e8036a41086a201029030037030020012001290388023703e8032000102a2001200f360220200141e8036a4120200141206a410410072003102a0c110b024002402018450d00200320154180016a2210360200200120152900223701ea032001201529002a3701f20320014188026a41086a220020012903f003370300200120152900323701fa0320014188026a41106a220f20012903f8033703002001201528003a36018204200120152f003e3b01860420014188026a41186a220c200129038004370300200141003a008804200120152d00213a00e903200120152d00203a00e803200120012903e8033703880220014188036a41186a2214200c29030037030020014188036a41106a220c200f29030037030020014188036a41086a220f2000290300370300200120012903880237038803200141206a41186a22002014290300370300200141206a41106a2214200c290300370300200141206a41086a220c200f290300370300200120012903880337032020150d010b2003102a4108211241002110410021000c100b200141a0016a41186a2000290300370300200141a0016a41106a2014290300370300200141a0016a41086a200c290300370300200120012903203703a001200720106b41077641016a220041286c220f417f4c0d12200f10282212450d01201220012903a00137030020124201370320201241186a200141a0016a41186a220a290300370300201241106a200141a0016a41106a2209290300370300201241086a200141a0016a41086a222229030037030002402003280200220f2003280204220d470d00410121100c0f0b2003200f4180016a22063602002001200f2900223701ea032001200f29002a3701f20320014188026a41086a221320012903f0033703002001200f2900323701fa0320014188026a41106a220820012903f8033703002001200f28003a360182042001200f2f003e3b01860420014188026a41186a220b200129038004370300200141003a0088042001200f2d00213a00e9032001200f2d00203a00e803200120012903e8033703880220014188036a41186a220f200b29030037030020014188036a41106a220c200829030037030020014188036a41086a22142013290300370300200120012903880237038803200141206a41186a2217200f290300370300200141206a41106a2218200c290300370300200141206a41086a2219201429030037030020012001290388033703204102211041c80021110340200a2017290300220237030020092018290300220437030020222019290300220537030020012001290320221f3703a001200f2002370300200c2004370300201420053703002001201f3703880302400240024002402010417f6a2000460d002000211a0c010b200d20066b41077620006a41016a221a2000490d2e2000410174220d201a200d201a4b1b221aad42287e2202422088a70d2e2002a7220d4100480d2e0240024020000d00200d102821120c010b2012200041286c200d102c21120b2012450d010b201220116a220d41606a220020012903880337030020142903002102200c2903002104200f2903002105200d4201370300200041186a2005370300200041106a2004370300200041086a2002370300200328020022002003280204220d470d01201a21000c110b200d41081037000b200320004180016a2206360200200120002900223701ea032001200029002a3701f203201320012903f003370300200120002900323701fa03200820012903f8033703002001200028003a36018204200120002f003e3b018604200b200129038004370300200141003a008804200120002d00213a00e903200120002d00203a00e803200120012903e80337038802200f200b290300370300200c2008290300370300201420132903003703002001200129038802370388032017200f2903003703002018200c290300370300201920142903003703002001200129038803370320201141286a2111201041016a2110201a21000c000b0b200041011037000b200f41081037000b413841011037000b411c41011037000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b410841041037000b200041011037000b41c4d1c300413320014198056a419cd9c3001038000b200341011037000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b200341011037000b200041011037000b2003102a0b200141206a41086a220342003703002001420037032041d985c2004117200141206a100820014188036a41086a20032903003703002001200129032037038803200141e8036a20014188036a411010c6020240024020012802e8034101460d00200120103602f003200120003602ec03200120123602e803200141e8036a41004100200110ee020c010b20014188036a4110100920012902ec032102200120103602f003200120003602ec03200120123602e803200141e8036a2002a741012002422088a710ee020b42002102200141206a41086a220042003703002001420037032041e194c600411c200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a10062100024020012802e8032203417f460d002000450d0020034108490d04200029000021022000102a0b200141206a41086a220042003703002001420037032041e194c600411c200141206a100820014188036a41086a2203200029030037030020012001290320370388032001200242017c22023703e80320014188036a4110200141e8036a410810072000420037030020014200370320419499c6004114200141206a100820032000290300370300200120012903203703880341002103200141003602e80320014188036a4110200141e8036a10062100024020012802e803220f417f460d002000450d00200f4104490d05200028000021032000102a0b411c10282200450d05200041186a41002800959546360000200041106a410029008d9546370000200041086a41002900859546370000200041002900fd94463700002000411c4138102c2200450d062000200237001c20014188026a41186a220f420037030020014188026a41106a220c420037030020014188026a41086a2214420037030020014200370388022000412420014188026a1000200141e8036a41186a200f290300370300200141e8036a41106a200c290300370300200141e8036a41086a201429030037030020012001290388023703e8032000102a20012003360220200141e8036a4120200141206a410410070b410810282200450d062000200736020420002015360200410810282219450d0720192016200e4107746a221a3602042019201636020042002102200141206a41086a220342003703002001420037032041dffbc500410f200141206a100820014188036a41086a20032903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a10062103024020012802e803220f417f460d002003450d00200f4108490d09200329000021022003102a0b200242017c22042002540d09200141206a41086a220342003703002001420037032041dffbc500410f200141206a100820014188036a41086a220f20032903003703002001200129032037038803200120043703e80320014188036a4110200141e8036a41081007200141e8046a20004188b7c20010880120012802ec04211020012802e804211420012802f0042100200342003703002001420037032041eefbc5004110200141206a1008200f20032903003703002001200129032037038803200141003602f003200142013703e8032000200141e8036a10b40102402000450d002014200041286c6a210e2014210303402003200141e8036a108f01200341206a29030021020240024020012802ec03220f20012802f00322006b4108490d0020012802e803210f0c010b200041086a220c2000490d1c200f4101742200200c2000200c4b1b22004100480d1c02400240200f0d0020001028210f0c010b20012802e803200f2000102c210f0b200f450d0d200120003602ec032001200f3602e80320012802f00321000b2001200041086a3602f003200f20006a2002370000200e200341286a2203470d000b0b20012802ec03210020014188036a411020012802e803220320012802f003100702402000450d002003102a0b02402010450d002014102a0b200442017c22022004540d0b200141206a41086a220042003703002001420037032041adfcc5004113200141206a100820014188036a41086a20002903003703002001200129032037038803200141e8036a20014188036a10ef0220012d00e803210020014188026a41186a220320014181046a29000037030020014188026a41106a220f200141f9036a29000037030020014188026a41086a220c200141f1036a290000370300200120012900e903370388020240024020004101460d00200141a0016a41186a4200370300200141a0016a41106a4200370300200141a0016a41086a4200370300200142003703a0010c010b200141a0016a41186a2003290300370300200141a0016a41106a200f290300370300200141a0016a41086a200c29030037030020012001290388023703a0010b200141206a41086a220042003703002001420037032041c0fcc5004111200141206a100820014188036a41086a2000290300370300200120012903203703880341002112200141003602e80320014188036a4110200141e8036a10062100024020012802e8032203417f460d002000450d0020034104490d0d200028000021122000102a0b200141206a41086a220042003703002001420037032041c0fcc5004111200141206a100820014188036a41086a20002903003703002001200129032037038803200141003602e80320014188036a4110200141e8036a41041007200141206a41186a200141a0016a41186a290300370300200141206a41106a200141a0016a41106a2903003703002000200141a0016a41086a290300370300200120012903a001370320417f201241016a220020002012491b410d74412872220b417f4c0d01200b10282208450d0d2008200129032037000020082002370020200841186a200141206a41186a290300370000200841106a200141206a41106a290300370000200841086a200141206a41086a2903003700004128211341002103410021004100211102400240024003400240024002400240024002402000450d00200f200c470d010b03402000210c200320124f0d02411610282200450d182000410e6a41002900dffc45370000200041086a41002900d9fc45370000200041002900d1fc4537000020004116412c102c2200450d192000200336001620014188026a41186a220f420037030020014188026a41106a220e420037030020014188026a41086a2214420037030020014200370388022000411a20014188026a100020014188036a41186a200f29030037030020014188036a41106a200e29030037030020014188036a41086a20142903003703002001200129038802370388032000102a200141003602a80220014188036a4120200141a8026a1006210e0240024020012802a802220f417f470d0041012100420021020c010b2001200f36028c022001200e36028802200141a8026a20014188026a107320012802a8022200450d1b20012902ac0221020240200f450d00200e102a0b20014188036a412010090b20002002422088a74105746a210f0240200c450d002010450d002011102a0b200341016a21032002a7211020002111200f2000460d000b200021112000210c0b200c41086a2900002102200c41106a2900002104200c2900002105200141e8036a41186a200c41186a290000221f370300200141e8036a41106a2004370300200141e8036a41086a2002370300200120053703e80320014188036a41186a2214201f37030020014188036a41106a2217200437030020014188036a41086a221820023703002001200537038803200b20136b411f4b0d03201341206a220e2013490d21200b410174220d200e200d200e4b1b220e4100480d21200b0d01200e102821080c020b0240200c450d002010450d002000102a0b20014188026a41186a2203420037030020014188026a41106a220f420037030020014188026a41086a220c420037030020014200370388022008201320014188026a1000200141e8036a41186a22142003290300370300200141e8036a41106a2210200f290300370300200141e8036a41086a2211200c29030037030020012001290388023703e8030240200b450d002008102a0b200141206a41086a220042003703002001420037032041adfcc5004113200141206a100820014188036a41086a220e2000290300370300200120012903203703880320014110360224200120014188036a360220200141e8036a200141206a10f002200141a8026a41186a200141a0016a41186a2903002202370300200141a8026a41106a200141a0016a41106a2903002204370300200141a8026a41086a200141a0016a41086a2903002205370300200120012903a001221f3703a8022014200237030020102004370300201120053703002001201f3703e8032000420037030020014200370320419efcc500410f200141206a1008200e2000290300370300200120012903203703880320014110360224200120014188036a360220200141e8036a200141206a10f002200141f8046a20194194b9c200108801200042003703002001420037032041adfcc5004113200141206a1008200e20002903003703002001200129032037038803200141e8036a20014188036a10ef0220012d00e8032100200320014181046a290000370300200f200141f9036a290000370300200c200141f1036a290000370300200120012900e9033703880220004101460d05200141a0036a420037030020014198036a420037030020014190036a420037030020014200370388030c060b2008200b200e102c21080b2008450d02200e210b0b200c41206a210c200820136a220e200129038803370000200e41186a2014290300370000200e41106a2017290300370000200e41086a2018290300370000201341206a21130c000b0b200e41011037000b20014188036a41186a20014188026a41186a29030037030020014188036a41106a20014188026a41106a29030037030020014188036a41086a20014188026a41086a2903003703002001200129038802370388030b200141206a41086a2200200141f8046a41086a280200360200200141206a41246a20014188036a41186a290300370200200141206a411c6a20014188036a41106a290300370200200141206a41146a20014188036a41086a290300370200200120012903f8042202370320200120012903880337022c20014194046a200141206a41286a280200360200200141e8036a41246a200141c0006a290300370200200141e8036a411c6a200141206a41186a290300370200200141e8036a41146a200141206a41106a290300370200200141f4036a220f2000290300370200200120023702ec03200141003602e803200141003602a801200142013703a001410110282200450d11200141013602a401200120012802a801220341016a3602a801200120003602a001200020036a41013a000020012802ec032103200f2802002200200141a0016a10b40102402000450d002003200041286c6a210e03402003200141a0016a108f01200341206a29030021020240024020012802a401220f20012802a80122006b4108490d0020012802a001210f0c010b200041086a220c2000490d1c200f4101742200200c2000200c4b1b22004100480d1c02400240200f0d0020001028210f0c010b20012802a001200f2000102c210f0b200f450d15200120003602a4012001200f3602a00120012802a80121000b2001200041086a3602a801200f20006a2002370000200e200341286a2203470d000b0b200141f8036a200141a0016a10f10220014193026a200141a0016a41086a280200360000200120012903a0012202370388052001200237008b02200141ac016a2001418f026a290000370000200141c28289aa043600a101200141023a00a00120012001290088023700a501200141a0016a10ce01024020012802e8030d00200141e8036a41086a280200450d0020012802ec03102a0b410810282203450d13200320073602042003201536020041081028220f450d14200f201a360204200f201636020010fb01210c411b10282200450d15200041176a41002800d89646360000200041106a41002900d19646370000200041086a41002900c99646370000200041002900c196463700002000411b4136102c2200450d162000200c36001b20014188026a41186a220c420037030020014188026a41106a220e420037030020014188026a41086a2214420037030020014200370388022000411f20014188026a100020014188036a41186a200c29030037030020014188036a41106a200e29030037030020014188036a41086a220c20142903003703002001200129038802370388032000102a20014188036a4120100e109801210e200141206a41086a2200420037030020014200370320419be1c0004111200141206a1008200c200029030037030020012001290320370388032001200e3602e80320014188036a4110200141e8036a41041007200141a0016a200341a0bbc200108301200042003703002001420037032041c2e1c000410d200141206a1008200c2000290300370300200120012903203703880320012802a001210c20012802a8012100200141003602f003200142013703e8032000200141e8036a10b40102402000450d0020004105742103200c210003402000200141e8036a108f01200041206a2100200341606a22030d000b0b20012802ec03210020014188036a411020012802e803220320012802f003100702402000450d002003102a0b024020012802a401450d00200c102a0b200f102a410810282200450d172000201a36020420002016360200200141a0016a200041acbdc200108301200141206a41086a2200420037030020014200370320419695c4004117200141206a1008200141e8036a41086a2000290300370300200120012903203703e80320012802a001210f20012802a801210020014100360228200142013703202000200141206a10b40102402000450d0020004105742103200f210003402000200141206a108f01200041206a2100200341606a22030d000b0b20012802242100200141e8036a4110200128022022032001280228100702402000450d002003102a0b024020012802a401450d00200f102a0b02402021450d002016102a0b02402020201e45720d002001280214450d00201e102a0b0240201d450d00201c102a0b201ba7450d002015102a0b200141a0056a24000f0b1036000b41c4d1c300413320014198056a419cd9c3001038000b41c4d1c300413320014198056a419cd9c3001038000b411c41011037000b413841011037000b410841041037000b410841041037000b41c4d1c300413320014198056a419cd9c3001038000b41c0c7c20041c9001050000b200041011037000b41c0c7c20041c9001050000b41c4d1c300413320014198056a419cd9c3001038000b200b41011037000b411641011037000b412c41011037000b41c4d1c300413320014198056a419cd9c3001038000b410141011037000b200041011037000b410841041037000b410841041037000b411b41011037000b413641011037000b410841041037000b41c4d1c300413320014198056a419cd9c3001038000b1031000bd11906047f017e037f027e027f037e23004190046b22002400200041e8036a41086a22014200370300200042003703e80341e7fcc5004110200041e8036a100820004188036a41086a2001290300370300200020002903e80337038803200041e0016a20004188036a109a03024002400240024002400240024020002d00e0014102470d00200041e0016a41086a22024200370300200042003703e00141b1f0c200410d200041e0016a100820012002290300370300200020002903e0013703e803200041003602e001200041e8036a4110200041e0016a1006210102400240024002400240024020002802e0012202417f460d002001450d002000200236027420002001360270200041e0016a200041f0006a107620002802e0012203450d0220002902e40121042002450d012001102a0c010b41042103420021040b20032004422088a7220541246c22066a2102200321010240200641ed00490d00200321010340024020012d00004101470d00200141016a2800002106200141086a28020021072000200141106a28020036020c20002007360208200641c28289aa04470d00200041e0016a200041086a10ba0220002d00e00122074102460d00200041e0016a2101200041f0006a21020c050b0240200141246a2d00004101470d00200141256a28000021062001412c6a28020021072000200141346a28020036020c20002007360208200641c28289aa04470d00200041e0016a200041086a10ba0220002d00e00122074102460d00200041e0016a2101200041f0006a21020c050b0240200141c8006a2d00004101470d00200141c9006a2800002106200141d0006a28020021072000200141d8006a28020036020c20002007360208200641c28289aa04470d00200041e0016a200041086a10ba0220002d00e00122074102460d00200041e0016a2101200041f0006a21020c050b0240200141ec006a2d00004101470d00200141ed006a2800002106200141f4006a28020021072000200141fc006a28020036020c20002007360208200641c28289aa04470d00200041e0016a200041086a10ba0220002d00e00122074102460d00200041e0016a2101200041f0006a21020c050b200220014190016a22016b41ec004b0d000b0b20012002460d012003200541246c6a21020340024020012d00004101470d00200141016a2800002106200141086a28020021072000200141106a28020036020c20002007360208200641c28289aa04470d00200041e0016a200041086a10ba0220002d00e00122074102460d00200041e0016a2101200041f0006a21020c040b2002200141246a2201460d020c000b0b41c4d1c3004133200041e8026a419cd9c3001038000b410221070c010b20002002200141016a41ef00109a0522012800003602602000200141036a28000036006320002900772108200041086a200041ff006a41d800109a051a20002900d70121090b02402005450d00200541246c21022003210103400240024020012d0000220641034b0d0002400240024020060e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012002415c6a22020d000b0b02402004a7450d002003102a0b200020002802603602682000200028006336006b200041f0006a200041086a41d800109a051a41002101024020074102460d00200020002802683602e0022000200028006b3600e302200020083703d802200041e0016a200041f0006a41d800109a051a200020093703d002200041e8036a41086a22014200370300200042003703e80341fefbc5004110200041e8036a100820004188036a41086a2001290300370300200020002903e80337038803200041003602a80320004188036a4110200041a8036a100621010240024020002802a8032202417f460d002001450d0020024108490d04200129000021042001102a200450450d010b200041d8026a200041d0026a20074101461b2903002104200041e8036a41086a22014200370300200042003703e80341fefbc5004110200041e8036a100820004188036a41086a22022001290300370300200020002903e80337038803200020043703a80320004188036a4110200041a8036a4108100720014200370300200042003703e80341eefbc5004110200041e8036a100820022001290300370300200020002903e8033703880341002101200041003602a80320004188036a4110200041a8036a100621060240024020002802a8032202417f470d000c010b200020023602ec03200020063602e803200041a8036a200041e8036a107720002802a8032201450d0520002902ac0321042002450d002006102a0b200041e8036a41086a22024200370300200042003703e803419efcc500410f200041e8036a100820004188036a41086a22062002290300370300200020002903e80337038803200041a8036a20004188036a10ef0220002d00a8032103200041e8036a41186a220a200041c1036a290000370300200041e8036a41106a220b200041b9036a2900003703002002200041b1036a290000370300200020002900a9033703e8032001410820011b21050240024020034101460d0020004188036a41186a420037030020004188036a41106a42003703002006420037030020004200370388030c010b20004188036a41186a200a29030037030020004188036a41106a200b29030037030020062002290300370300200020002903e803370388030b200041e8026a41086a20004188036a41086a2903002209370300200041e8026a41106a20004188036a41106a290300220c370300200041e8026a41186a20004188036a41186a290300220d3703002000200029038803220e3703e802200041a8036a41086a2004420020011b370300200041a8036a41106a220a200e370300200041a8036a41186a2009370300200041c8036a200c370300200041a8036a41286a200d370300200020053602ac03200041003602a803200041003602f003200042013703e803410110282201450d05200041013602ec03200020002802f003220241016a3602f003200020013602e803200120026a41013a000020002802ac032102200041a8036a410c6a2802002201200041e8036a10b40102402001450d002002200141286c6a210503402002200041e8036a108f01200241206a29030021040240024020002802ec03220620002802f00322016b4108490d0020002802e80321060c010b200141086a22032001490d0a200641017422012003200120034b1b22014100480d0a0240024020060d002001102821060c010b20002802e80320062001102c21060b2006450d09200020013602ec03200020063602e80320002802f00321010b2000200141086a3602f003200620016a20043700002005200241286a2202470d000b0b200a200041e8036a10f10220004193036a200041f0036a280200360000200020002903e80322043703d8032000200437008b03200041e8036a410c6a2000418f036a290000370000200041c28289aa043600e903200041023a00e80320002000290088033700ed03200041e8036a10ce0120002802a8030d0020002802b003450d0020002802ac03102a0b200041d8026a200041d0026a20074101461b2903002104200041e8036a41086a22014200370300200042003703e803418efcc5004110200041e8036a100820004188036a41086a2001290300370300200020002903e80337038803200020043703a80320004188036a4110200041a8036a410810074100210120070d00200041a8036a41086a200041e0016a41086a290300370300200041a8036a41106a200041e0016a41106a2d00003a0000200020002800e3023600eb02200020002802e0023602e802200020002903e0013703a803410121010b200041e0016a41086a2008370300200041e0016a41106a20002903a803370300200041f8016a200041a8036a41086a29030037030020004180026a200041a8036a41106a2d00003a0000200020013a00e001200020002802e8023600e101200020002800eb023600e401200041e8036a41086a22024200370300200042003703e80341e7fcc5004110200041e8036a100820004188036a41086a2002290300370300200020002903e80337038803410110282202450d0620004201370274200020023602700240024020010d0020004101360278200241003a00000c010b20004101360278200241013a0000200041e0016a410172200041f0006a10f1020b2000280274210120004188036a411020002802702202200028027810072001450d002002102a0b20004190046a24000f0b41c4d1c3004133200041e8026a419cd9c3001038000b41c4d1c3004133200041e8026a419cd9c3001038000b410141011037000b200141011037000b1031000b410141011037000bec0501057f23004190016b2202240002400240410f10282203450d00200341002900edae44370000200341076a41002900f4ae443700002002428f808080f001370214200220033602102001200241106a108f012002280218210320022802102101200241e0006a41186a22044200370300200241e0006a41106a22054200370300200241e0006a41086a220642003703002002420037036020012003200241e0006a1000200241306a41186a2004290300370300200241306a41106a2005290300370300200241306a41086a20062903003703002002200229036037033002402002280214450d002002280210102a0b20024100360260200241306a4120200241e0006a100621040240024020022802602201417f470d00410021030c010b2002200136025420022004360250200241e0006a200241d0006a10d4012002280280012203450d02200241106a41186a200241e0006a41186a290300370300200241106a41106a200241e0006a41106a290300370300200241106a41086a200241e0006a41086a290300370300200241086a2002418c016a2802003602002002200229036037031020022002290284013703002001450d002004102a0b200241e0006a41086a2201200241106a41086a290300370300200241e0006a41106a2204200241106a41106a290300370300200241e0006a41186a2205200241106a41186a290300370300200241d0006a41086a2206200241086a2802003602002002200229031037036020022002290300370350024002402003450d002000200229036037030020002003360220200041246a2002290350370200200041186a2005290300370300200041106a2004290300370300200041086a20012903003703002000412c6a20062802003602000c010b2000420037030020004208370320200041186a4200370300200041106a4200370300200041086a4200370300200041286a41003602000b20024190016a24000f0b410f41011037000b41c4d1c3004133200241106a419cd9c3001038000b84fc0111067f017e037f017e027f017e047f017e037f017e017f0a7e017f027e017f0a7e2a7f230041a0196b22022400200241e00e6a41086a22034200370300200242003703e00e41cd9cc6004123200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f41002104200241003602f011200241900f6a4110200241f0116a10062103024002400240024002400240024002400240024020022802f0112205417f460d002003450d0020054104490d01200328000021042003102a0b2001417f6a2106200241e00e6a41086a22034200370300200242003703e00e418e9dc6004110200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a1006210302400240024020022802f0112201417f460d002003450d002001450d0220032d0000220141034f0d022003102a200141014b0d06024020010e020100010b200241e00e6a41086a22034200370300200242003703e00e418e9dc6004110200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241900f6a411010090c010b200620046b220320064b0d0520034106490d050b200241f0116a41086a22034200370300200242003703f01141c785c2004112200241f0116a1008200241e00e6a41086a2003290300370300200220022903f0113703e00e200241003602f011200241e00e6a4110200241f0116a1006210302400240024020022802f0112204417f460d002003450d00200220043602940f200220033602900f200241f0116a200241900f6a106d20022802f0112207450d0220022902f41121082004450d012003102a0c010b41012107420021080b410021090240024002402008422088a7220341057422010d004108210a4100210b0c010b2001410575220bad42d0007e220c422088a70d0c200ca722044100480d0c20041028220a450d010b2008a7210d02402003450d00200141606a210e200241f0116a41206a2103200a2105200721040340200441086a2900002108200441106a290000210c2004290000210f200241e00e6a41186a2210200441186a290000370300200241e00e6a41106a2211200c370300200241e00e6a41086a221220083703002002200f3703e00e200241900f6a200241e00e6a10ec02200241f0116a41186a2010290300370300200241f0116a41106a2011290300370300200241f0116a41086a2012290300370300200320022903900f370300200341086a200241900f6a41086a290300370300200341106a200241900f6a41106a290300370300200341186a200241900f6a41186a290300370300200341206a200241900f6a41206a290300370300200341286a200241900f6a41286a290300370300200220022903e00e3703f0112005200241f0116a41d000109a0541d0006a2105200441206a2104200141606a22010d000b200e41057641016a21090b0240200d450d002007102a0b200241e00e6a41086a22034200370300200242003703e00e41f09cc600411e200241e00e6a1008200241900f6a41086a22042003290300370300200220022903e00e3703900f200241f0116a200241900f6a10de030240024020022802f41122130d004104211342002114410021110c010b200241900f6a4110100920022802f011211120022903f81121140b10a003210820034200370300200242003703e00e41feadc4004117200241e00e6a100820042003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a1006210302400240024020022802f0112204417f470d004200210c0c010b024020030d004200210c0c010b20044108490d012003290000210c2003102a0b200241e00e6a41086a22154200370300200242003703e00e41feadc4004117200241e00e6a1008200241900f6a41086a22162015290300370300200220022903e00e3703900f200220083703f011200241900f6a4110200241f0116a41081007410021172008200c7d2218500d0620154200370300200242003703e00e41a5afc4004116200241e00e6a100820162015290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a1006210302400240024020022802f0112204417f460d002003450d00200220043602e40e200220033602e00e200241f0116a200241e00e6a106d20022802f0112219450d0220022902f411211a02402004450d002003102a0b201a422088a721040c010b410021044200211a410121190b4200210c200241e00e6a41086a22034200370300200242003703e00e4199fec4004111200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a1006210302400240024020022802f0112201417f470d004200210c4200211b0c010b024020030d004200211b0c010b20014110490d01200341086a290000211b2003290000210c2003102a0b200241800c6a10a102200241f00b6a20022903800c220f200241800c6a41086a2903002208428094ebdc03420010a005200241d00b6a200c201b2004ad4200109f05200241e00b6a20022903f00b221b200241f00b6a41086a290300221c4280ec94a37c427f109f052008200241d00b6a41086a290300221d20022903d00b221e200f56201d200856201d2008511b22031b2108200f201e20031b210c2018428086ebc7f5002018428086ebc7f500541b421f8042ffffffff0f83428094ebdc037e429880b5e50380211f200f20022903e00b7c210f410021034184c9c0002104024002400340024041accbc00020046b41184b0d000240200441accbc000460d000340200241c00b6a201b201c200435020022184200109f052003200c20022903c00b22202018200f7e428094ebdc038042ffffffff0f837c22185a2008200241c00b6a41086a2903002018202054ad7c22205a200820205122011b6a2103200c201854200820205420011b0d0441accbc000200441086a2204470d000b0b200241b00b6a201b201c42e8aafa0b4200109f05200241b80b6a29030020022903b00b220c200f42e8aafa0b7e428094ebdc038042ffffffff0f837c2208200c54ad7c210c0c030b200241a00b6a201b201c200435020022184200109f052003200c20022903a00b22202018200f7e428094ebdc038042ffffffff0f837c22185a2008200241a00b6a41086a2903002018202054ad7c22205a200820205122011b6a2103200c201854200820205420011b0d01200241900b6a201b201c200441086a35020022184200109f052003200c20022903900b22202018200f7e428094ebdc038042ffffffff0f837c22185a2008200241900b6a41086a2903002018202054ad7c22205a200820205122011b6a2103200c201854200820205420011b0d01200241800b6a201b201c200441106a35020022184200109f052003200c20022903800b22202018200f7e428094ebdc038042ffffffff0f837c22185a2008200241800b6a41086a2903002018202054ad7c22205a200820205122011b6a2103200c201854200820205420011b0d01200241f00a6a201b201c200441186a35020022184200109f052003200c20022903f00a22202018200f7e428094ebdc038042ffffffff0f837c22185a2008200241f00a6a41086a2903002018202054ad7c22205a200820205122011b6a2103200441206a2104200c201854200820205420011b450d000b0b02402003417f6a220420034d0d00200241f0096a201b201c42c0f0f50b4200109f05200241f8096a29030020022903f009220c200f42288042ffffffff0f837c2208200c54ad7c210c0c010b02400240200441244b0d00200241e00a6a201b201c200441037422014184c9c0006a2802002205ad22184200109f05200241c00a6a200c20022903e00a22202018200f7e428094ebdc038042ffffffff0f837c2218200c2018562008200241e00a6a41086a2903002018202054ad7c22205620082020511b22041b22212018200c20041b220c7d22182008202020041b2020200820041b7d2021200c54ad7d4100200341037422104184c9c0006a280200220320056b2205200520034b1b22034101200341014b1bad2208420010a005200241b00a6a20022903c00a220c200241c00a6a41086a290300222020084200109f05200241d00a6a201b201c20014188c9c0006a2802002203ad22214200109f05200241800a6a2020420020104188c9c0006a28020022012003200120034b22051b2003200120051b6bad221b4200109f05200241a00a6a200c4200201b4200109f05200241900a6a42004200200c4200109f05427f427f200241a00a6a41086a290300220c20022903800a20022903900a7c7c221c20022903880a20022903980a84420052201c200c547222051b221c427f20022903a00a20051b220c201820022903b00a7d201b7e2008807c2208200c542205ad7c221b2005201b201c542008200c5a1b22051b211c427f200820051b211b200241d00a6a41086a29030020022903d00a22082021200f7e428094ebdc038042ffffffff0f837c220c200854ad7c21082004200120034d730d0142002008201c7d200c201b54ad7d220f200c201b7d221b200c56200f200856200f2008511b22031b210c4200201b20031b21080c020b41acd9c300200441251034000b427f2008201c7c200c201b7c220f200c542203ad7c220c2003200c200854200c2008511b22031b210c427f200f20031b21080b42002122200241e0096a2008200c428094ebdc03420010a005200241d0096a20022903e009220c200241e0096a41086a290300220f4280ec94a37c427f109f05200241c0096a200c200f201f4200109f05201f200820022903d0097c7e428094ebdc038021080240201a422088a722030d00420021230c080b20132014422088a74102746a210e201920034105746a2124200241c0096a41086a29030020022903c009220c200842ffffffff0f837c2225200c54ad7c2126200241f0116a41086a2127200241900f6a41086a21122011ad21284200212242002123201321052019211003402005200e460d08024020052802002203450d00024002400240024002402011450d00200241b0096a202520262028420010a005200241a0096a20022903b0092208200241b0096a41086a290300220c20284200109f0520024190096a2008200c20112003200320114b1bad220f4200109f05202520022903a0097d200f7e2028802108200229039009210f20024190096a41086a290300211c411210282203450d01200341002900c1ae44370000200341106a41002f00d1ae443b0000200341086a41002900c9ae4437000020024292808080a0023702f411200220033602f0112010200241f0116a108f0120022802f811210320022802f0112104200241900c6a41186a22014200370300200241900c6a41106a22074200370300200241900c6a41086a220d4200370300200242003703900c20042003200241900c6a1000200241c00d6a41186a2001290300370300200241c00d6a41106a2007290300370300200241c00d6a41086a200d290300370300200220022903900c3703c00d024020022802f411450d0020022802f011102a0b200241003602f011200241c00d6a4120200241f0116a1006210320022802f0112204417f460d032003450d03200220043602f411200220033602f011200241f8086a200241f0116a109f0120022903f808a70d02200241f8086a41106a290300210c200229038009211b2004450d042003102a0c040b41acfec4001032000b411241011037000b41c4d1c300413320024198196a419cd9c3001038000b4200211b4200210c0b0240024002400240024002400240200f200842ffffffff0f837c2208201b2008201b200854200c201c2008200f54ad7c220f54200c200f511b22031b22297d222a200f200c200f20031b222b7d2008202954ad7d222c8450450d004200211f4200211c420021084200210c0c010b200241f0116a201010ec0220272903002208420020022903f011220c42015620084200522008501b22031b2108200c420120031b210f20022802901221070240024020022802981222030d004200211f200241f0076a200f2008428094ebdc03420010a005200241f0076a41086a290300212d20022903f007212e4200211c0c010b2007200341306c6a21014200211f200241e8086a200f2008428094ebdc03420010a005200241c8086a202a202c428094ebdc03420010a005200241d8086a202a202c428094ebdc03420010a105200241e8086a41086a290300222d420020022903e808222e420156202d420052202d501b22031b2118202e420120031b2120200241c8086a41086a290300212f20022903c808213020022903d80821314200211c200721030340200241b8086a200f2003290300220c200c200f56200341086a290300220c200856200c2008511b22041b2008200c20041b2020201810a00520022903b808221b428080808010544100200241b8086a41086a290300501b450d03200241a8086a200f20082020201810a00520022903a808220c428080808010544100200241a8086a41086a290300501b450d04024002400240200ca7450d0020024180086a2030202f201b42ffffffff0f83428094ebdc037e200c42ffffffff0f838042ffffffff0f83220c4200109f0520024190086a200341106a2203200229038008221b200c20317e428094ebdc038042ffffffff0f837c220c20024180086a41086a290300200c201b54ad7c10b404200229039008210c200229039808211b200241900f6a41106a20024190086a41106a29030022213703002002201b3703980f2002200c3703900f0240200ca74101470d00427f201c20217c201f201b7c221b201f542204ad7c220c2004200c201c54200c201c511b22041b211c427f201b20041b211f0c030b200c4201510d010c020b41acaac3001032000b200220123602e00e200241e00e6a109c010b200341206a22032001470d000b0b200241e0076a200f200229038012220c200c200f56200241f0116a41186a290300220c200856200c2008511b22031b2008200c20031b202e4201202e420156202d420052202d501b22031b220c202d420020031b221b10a00520022903e0072218428080808010544100200241e0076a41086a290300501b450d01200241d0076a200f2008200c201b10a00520022903d0072208428080808010544100200241d0076a41086a290300501b450d022008a7450d03200241c0076a202a202c428094ebdc03420010a005200241b0076a20022903c007220c200241c0076a41086a290300220f4280ec94a37c427f109f05200241a0076a200c200f201842ffffffff0f83428094ebdc037e200842ffffffff0f838042ffffffff0f8322084200109f0520022903a007220c2008202a20022903b0077c7e428094ebdc038042ffffffff0f837c2208200c54ad210c200241a0076a41086a290300210f0240200228029412450d002007102a0b200f200c7c210c0b20024188076a2010200820297c220f200c202b7c200f200854ad7c10b4042002290388072108200229039007210c200241f0116a41106a20024188076a41106a290300220f3703002002200c3703f811200220083703f01102402008a74101470d00427f201c200f7c201f200c7c220c201f542203ad7c220820032008201c542008201c511b22031b211c427f200c20031b211f0c050b20084201510d030c040b10d101000b10d201000b41acaac3001032000b200220273602900f200241900f6a109c010b427f2023201c7c2022201f7c220c2022542203ad7c22082003200820235420082023511b22031b2123427f200c20031b21220b200541046a2105201041206a22102024470d000c080b0b41c4d1c300413320024198196a419cd9c3001038000b41c4d1c300413320024198196a419cd9c3001038000b41c4d1c300413320024198196a419cd9c3001038000b200441081037000b41c4d1c300413320024198196a419cd9c3001038000b41c4d1c300413320024198196a419cd9c3001038000b41c4d1c300413320024198196a419cd9c3001038000b02402014a7450d002013102a0b20024188126a202337030020024180126a2022370300200241f8116a41003a0000200241033a00f0114101211741014100200241f0116a10cc01200220233703f811200220223703f0112002200241f0116a3602900f200241900f6a109c0102402022202384500d00201e201d84500d00200241f8066a10a10220022903f8062208201e7d220f200856200241f8066a41086a290300220c201d7d2008201e54ad7d2208200c562008200c511b0d00200241e8066a200f2008201e201d10a005200241b8066a200241e8066a41086a2903002208420020224200109f05200241c8066a2023420020022903e806220c4200109f05200241d8066a200c420020224200109f05200842005220234200527120022903c0064200527220022903d00642005272200241d8066a41086a290300220820022903b80620022903c8067c7c220f200854720d0020022903d806211b200241e00e6a41086a22034200370300200242003703e00e41ace1c0004116200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a100621030240024020022802f0112204417f460d002003450d00024020044110490d00200341086a290000210c200329000021082003102a0c020b41c4d1c300413320024198196a419cd9c3001038000b420021084200210c0b200241e00e6a41086a22034200370300200242003703e00e41ace1c0004116200241e00e6a1008200241900f6a41086a22042003290300370300200220022903e00e3703900f2002427f200c200f7c2008201b7c22182008542203ad7c221c2003201c200c54201c200c511b22031b3703f8112002427f201820031b3703f011200241900f6a4110200241f0116a41101007200241f0116a10d301200241a8066a200241f0116a2008427f85201b20031b2208200c427f85200f20031b220c10d001200241900f6a41106a200c200241a8066a41086a290300221b7d200820022903a806220f54ad7d201b200c7d200f200854ad7d200f200858201b200c58201b200c5122031b22011b37030020022008200f7d200f20087d20011b3703980f2002200f200856201b200c5620031b2203ad3703900f024020030d00200220043602e00e200241e00e6a109d010c010b200220043602e00e200241e00e6a109c010b201aa7450d002019102a0b20154200370300200242003703e00e41bb9cc6004112200241e00e6a100820162015290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a10062103024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022802f0112204417f470d00410021270c010b024020030d00410021270c010b20044104490d01200328000021272003102a0b200241e00e6a41086a22034200370300200242003703e00e41bb9cc6004112200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f2002202741016a22163602f011200241900f6a4110200241f0116a41041007411710282203450d012003410f6a41002900d3fe44370000200341086a41002900ccfe44370000200341002900c4fe4437000020034117412e102c2203450d0220032027360017200241900c6a41186a22044200370300200241900c6a41106a22014200370300200241900c6a41086a22054200370300200242003703900c2003411b200241900c6a1000200241c00d6a41186a2004290300370300200241c00d6a41106a2001290300370300200241c00d6a41086a2005290300370300200220022903900c3703c00d2003102a200241c00d6a41201009200241e00e6a41086a22034200370300200242003703e00e41cd9cc6004123200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a10062103024020022802f0112204417f460d002003450d00200441034d0d042003102a0b200241e00e6a41086a22154200370300200242003703e00e41cd9cc6004123200241e00e6a1008200241900f6a41086a22192015290300370300200220022903e00e3703900f200220063602f011200241900f6a4110200241f0116a41041007201641a105490d0920154200370300200242003703e00e41b99dc6004112200241e00e6a100820192015290300370300200220022903e00e3703900f41002112200241003602f011200241900f6a4110200241f0116a100621320240024020022802f0112233417f470d000c010b024020320d000c010b200220333602f411200220323602f011200241a0066a200241f0116a106c20022802a0060d2e20022802f41122104178712203417f4c0d2020022802a406210e02400240201041037622070d00410421120c010b200310282212450d060b0240200e450d004100211141002105410021010340200241003602e00e02400240024020104104490d0020022010417c6a22103602f411200220022802f011220341046a3602f0112003280000210d200241003602e00e20104104490d00200141016a210420022010417c6a22103602f4112002200341086a3602f0112003280004210320012007470d0220112004201120044b1b220741ffffffff01712007470d342007410374222441004e0d010c340b2007450d322012102a0c320b0240024020010d002024102821120c010b201220052024102c21120b2012450d090b201220056a2201200d360200200141046a2003360200201141026a2111200541086a210520042101200e2004470d000b0b2012450d2e200ead4220862007ad8421082033450d002032102a0b2012410420121b210e02402008420020121b2208422088220ca722032008a7470d00200341016a22042003490d2f200ca722054101742201200420042001491b220441ffffffff01712004470d2f200441037422014100480d2f0240024020030d0020011028210e0c010b200e20054103742001102c210e0b200e450d072008422088a721032004ad21080b202741e17a6a2104200e20034103746a2201200636020420012016360200200e200341016a22114103746a2110410021030240201141044f0d00200e21010c080b200e2105024003402005220128020020044f0d0a0240200141086a2802002004490d00200341016a21030c0b0b0240200141106a2802002004490d00200341026a21030c0b0b200141186a28020020044f0d01200341046a21032010200141206a22056b41184b0d000b200141206a21010c080b200341036a21030c080b41c4d1c300413320024198196a419cd9c3001038000b411741011037000b412e41011037000b41c4d1c300413320024198196a419cd9c3001038000b200341041037000b202441041037000b200141041037000b20012010460d00200e20114103746a21050340200128020020044f0d01200341016a21032005200141086a2201470d000b0b20112003490d01200842ffffffff0f8321080240201120036b2207450d0002402003450d00200e200e20034103746a2007410374109b051a0b200e280204210d200241e00e6a41086a22124200370300200242003703e00e418199c6004113200241e00e6a1008200241900f6a41086a22242012290300370300200220022903e00e3703900f200241f0116a200241900f6a411010c6024101210320022902f411210c0240024020022802f01122044101460d00200441014621030c010b200c422088a72206200d200d20064b1b2211200ca72204490d000240201120044d0d000340411a10282203450d06200341186a41002f00e0bb403b0000200341106a41002900d8bb40370000200341086a41002900d0bb40370000200341002900c8bb403700002003411a4134102c2203450d072003200436001a200241900c6a41186a22014200370300200241900c6a41106a22054200370300200241900c6a41086a22104200370300200242003703900c2003411e200241900c6a1000200241b00c6a41186a2001290300370300200241b00c6a41106a2005290300370300200241b00c6a41086a2010290300370300200220022903900c3703b00c2003102a200241b00c6a41201009200441016a2203210420112003470d000b0b200d2006492103200c428080808070832011ad84210c0b20124200370300200242003703e00e418199c6004113200241e00e6a100820242012290300370300200220022903e00e3703900f0240024020030d00200241900f6a411010090c010b410810282203450d062003200c422088a73600042003200ca7360000200241900f6a41102003410810072003102a0b20082007ad4220868421080b200241e00e6a41086a22034200370300200242003703e00e41b99dc6004112200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f0240200e0d00200241900f6a411010090c010b200241003602f811200242013703f0112008422088a72203200241f0116a10b4010240024020030d0020022802f811210320022802f411210120022802f01121040c010b200e20034103746a2106410020022802f81122116b210520022802f4112101410021030340201120036a2110200e20036a2212280200210702400240200120056a4104490d0020022802f01121040c010b201041046a22042010490d282001410174220d2004200d20044b1b220d4100480d280240024020010d00200d102821040c010b20022802f0112001200d102c21040b2004450d082002200d3602f411200220043602f011200d21010b2002201041046a220d3602f811200420116a20036a2007360000201241046a28020021070240200120056a417c6a41034b0d00200d41046a2224200d490d282001410174220d2024200d20244b1b220d4100480d280240024020010d00200d102821040c010b20042001200d102c21040b2004450d092002200d3602f411200220043602f011200d21010b2002201041086a3602f811200420116a20036a41046a2007360000200541786a2105200341086a2103201241086a2006470d000b201120036a21030b2008a72105200241900f6a411020042003100702402001450d002004102a0b2005450d00200e102a0b20154200370300200242003703e00e41889cc6004116200241e00e6a100820192015290300370300200220022903e00e3703900f41002134200241003602f011200241900f6a4110200241f0116a10062103024020022802f0112204417f460d002003450d0020044104490d07200328000021342003102a0b200241e00e6a41086a22034200370300200242003703e00e419e9cc600411d200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a10062103024002400240024020022802f0112204417f460d0020030d010b410421040c010b20044104490d09200328000021042003102a41012115200441014d0d010b200421150b200241900c6a41186a22034200370300200241900c6a41106a22044200370300200241900c6a41086a22014200370300200242003703900c41d3aec400411a200241900c6a1000200241f0116a41186a2003290300370300200241f0116a41106a2004290300370300200241f0116a41086a2001290300370300200220022903900c3703f011200241900e6a200241f0116a412010fd01200241e00e6a41206a200241900e6a41206a2d00003a0000200241e00e6a41186a200241900e6a41186a290300370300200241e00e6a41106a200241900e6a41106a290300370300200241e00e6a41086a200241900e6a41086a290300370300200220022903900e3703e00e200241f0116a200241e00e6a10ab010240024020022903f0114201510d004101211141002105410021060c010b200220022f01f8113b01e00c2002200229008b123703d00c2002200241fa116a2d00003a00e20c2002200241f0116a41206a2900003700d50c200241fb116a2800002103200241ff116a280000210420024183126a280000210120024187126a2800002105412010282211450d09201120022f01e00c3b00002011200536000f2011200136000b2011200436000720112003360003201120022903d00c370013201141026a20022d00e20c3a0000201141186a20022900d50c370000200241900f6a41206a200241e00e6a41206a2d00003a0000200241900f6a41186a200241e00e6a41186a290300370300200241900f6a41106a200241e00e6a41106a290300370300200241900f6a41086a200241e00e6a41086a290300370300200220022903e00e3703900f200241f0116a200241900f6a10ab0141012105024020022903f0114201510d00410121060c010b200241f0116a41086a2103410221104120210141012105410121060340200241b00c6a41186a200341186a2903002208370300200241b00c6a41106a200341106a290300220c370300200241b00c6a41086a200341086a290300220f37030020022003290300221b3703b00c200241900c6a41186a22122008370300200241900c6a41106a2207200c370300200241900c6a41086a220d200f3703002002201b3703900c024020052006470d00200541016a22042005490d2720102004201020044b1b220641ffffff3f712006470d27200641057422044100480d270240024020050d002004102821110c010b201120012004102c21110b2011450d110b201120016a220420022903900c370000200441186a2012290300370000200441106a2007290300370000200441086a200d290300370000201041026a2110200141206a2101200541016a2105200241f0116a200241900f6a10ab0120022903f0114201510d000b0b200241900c6a41186a22034200370300200241900c6a41106a22044200370300200241900c6a41086a22014200370300200242003703900c41a7aec400411a200241900c6a1000200241f0116a41186a2003290300370300200241f0116a41106a2004290300370300200241f0116a41086a2001290300370300200220022903900c3703f011200241e00d6a200241f0116a412010fd01200241900e6a41206a200241e00d6a41206a2d00003a0000200241900e6a41186a200241e00d6a41186a290300370300200241900e6a41106a200241e00d6a41106a290300370300200241900e6a41086a200241e00d6a41086a290300370300200220022903e00d3703900e200241f0116a200241900e6a10ad01024002402002280290120d004104213541002104410021360c010b412c10282235450d0a203520022903f011370200203541286a200241f0116a41286a2212280200360200203541206a200241f0116a41206a2207290300370200203541186a200241f0116a41186a220d290300370200203541106a200241f0116a41106a220e290300370200203541086a200241f0116a41086a2224290300370200200241e00e6a41206a200241900e6a41206a2d00003a0000200241e00e6a41186a200241900e6a41186a290300370300200241e00e6a41106a200241900e6a41106a290300370300200241e00e6a41086a200241900e6a41086a290300370300200220022903900e3703e00e200241900f6a200241e00e6a10ad01024020022802b00f0d0041012104410121360c010b41022110412c2101410121044101213603402012200241900f6a41286a2802003602002007200241900f6a41206a290300370300200d200241900f6a41186a290300370300200e200241900f6a41106a2903003703002024200241900f6a41086a290300370300200220022903900f3703f011024020042036470d00200441016a22032004490d2720102003201020034b1b2236ad422c7e2208422088a70d272008a722034100480d270240024020040d002003102821350c010b203520012003102c21350b2035450d0d0b203520016a220320022903f011370200200341286a2012280200360200200341206a2007290300370200200341186a200d290300370200200341106a200e290300370200200341086a2024290300370200201041026a21102001412c6a2101200441016a2104200241900f6a200241e00e6a10ad0120022802b00f0d000b0b200242003702ec0c200241f8b9c0003602e80c200420056a2201ad42d0007e2208422088a70d152008a72203417f4c0d150240024020030d00410821100c010b200310282210450d0c0b200241003602c80e200220013602c40e200220103602c00e200241900e6a41206a200241e80c6a360200200241003602a80e200241a40e6a20024198196a36020020022011200541057422016a220d36029c0e200220113602980e200220063602940e200220113602900e2002200241c00e6a3602ac0e200220024198196a3602a00e410221244101210e0240024020050d00201121030c010b4200211b2011210302400340200341086a2900002108200341106a290000210c2003290000210f200241f0116a41186a2205200341186a290000370300200241f0116a41106a2210200c370300200241f0116a41086a221220083703002002200f3703f01120024190066a200241f0116a10b004200241b00c6a41086a22072012290300370300200241b00c6a41106a22122010290300370300200241b00c6a41186a22102005290300370300200220022903f0113703b00c20024190066a41086a290300210c200229039006210f20024180066a10a102200241f0056a20022903800620024180066a41086a290300427f420010a005200241e0056a200f200c20022903f005220842012008420156200241f0056a41086a29030022084200522008501b22051b2008420020051b10a005200241900c6a41086a2007290300370300200241900c6a41106a2012290300370300200241900c6a41186a2010290300370300200220022903b00c3703900c20022903e005220850450d01200341206a2103200141606a22010d000b2002200d3602980e200d21030c010b200220022f01900c3b01e00c200220022d00920c3a00e20c200220022900a30c3703d00c200220022800f80c3602b80d2002200341206a22033602980e2002200241a80c6a2900003700d50c2002200241fb0c6a2800003600bb0d20022800930c210120022800970c2112200228009b0c2110200228009f0c2105200220022d00e20c3a00a20d200220022f01e00c3b01a00d200220022900d50c3700f511200220022903d00c3703f011200220022800bb0d3600c30d200220022802b80d3602c00d200220022d00a20d3a00aa0d200220022f01a00d3b01a80d200220022900f5113700e50e200220022903f0113703e00e200220022800c30d3600b30d200220022802c00d3602b00d4100210e410021240b200220022f01a80d3b01c00d200220022d00aa0d3a00c20d200220022903e00e3703f011200220022900e50e3700f511200220022802b00d3602a00d200220022800b30d3600a30d024002400240200e450d00200241023a00d00f0c010b200220022d00c20d3a009a0d200220022f01c00d3b01980d200220022903f0113703e00d200220022900f5113700e50d200220022802a00d3602880d200220022800a30d36008b0d200241013602a80e200220022d009a0d3a00960d200220022f01980d3b01940d200220022900e50d3700d50e200220022903e00d3703d00e20024190126a201b37030020024188126a200837030020024180126a4200370300200241a7126a2005360000200241a3126a20103600002002419f126a20123600002002419b126a2001360000200242003703f811200242003703f01120024198126a20022f01940d3b01002002419a126a20022d00960d3a0000200241f0116a41c8006a20243a0000200241ab126a20022903d00e370000200241b0126a20022900d50e370000200241bc126a200228008b0d360000200241b9126a20022802880d360000200241900f6a200241ac0e6a200241f0116a10fb0220022d00d00f4102470d010b02402003200d460d002002200d20036b41606a41607120036a41206a3602980e0b410021372006450d142011102a0c140b41c80010282238450d0c2038200241900f6a41c800109a051a200241e00e6a41086a200241900e6a41086a2903002208370300200241e00e6a41206a200241900e6a41206a280200360200200241e00e6a41186a200241900e6a41186a290300370300200241e00e6a41106a200241900e6a41106a290300370300200220022903900e3703e00e410121102008a7220320022802ec0e2201460d10200241b9126a210e200241fc0e6a21274200211b02400340200341086a2900002108200341106a290000210c2003290000210f200241f0116a41186a2205200341186a290000370300200241f0116a41106a2211200c370300200241f0116a41086a221220083703002002200f3703f011200241d0056a200241f0116a10b004200241b00c6a41086a22072012290300370300200241b00c6a41106a22122011290300370300200241b00c6a41186a22112005290300370300200220022903f0113703b00c200241d0056a41086a290300210c20022903d005210f200241c0056a10a102200241b0056a20022903c005200241c0056a41086a290300427f420010a005200241a0056a200f200c20022903b005220842012008420156200241b0056a41086a29030022084200522008501b22051b2008420020051b10a005200241900c6a41086a2007290300370300200241900c6a41106a2012290300370300200241900c6a41186a2011290300370300200220022903b00c3703900c20022903a005220850450d012001200341206a2203470d000b200220013602e80e200121030c110b200220022f01900c3b01e00c200220022d00920c3a00e20c200220022900a30c3703d00c200220022800f80c3602b80d2002200341206a22033602e80e2002200241900c6a41186a220d2900003700d50c2002200241f80c6a41036a22392800003600bb0d20022800930c211120022800970c2112200228009b0c2107200228009f0c2116200220022d00e20c3a008a0d200220022f01e00c3b01880d200220022900d50c3700e50d200220022903d00c3703e00d200220022800bb0d3600b30d200220022802b80d3602b00d20024198126a2124200241a30c6a213a20022802f80e2105200241f0116a410472220641086a2133200641106a213b200241ab126a223c41056a213d41012110410121370340200220022d008a0d22193a00aa0d200220022f01880d22323b01a80d200220022903e00d3703c00d200220022900e50d3700c50d200220022802b00d3602a00d200220022800b30d3600a30d200220193a00960d200220323b01940d2002200541016a22193602f80e200220022900c50d3700d50e200220022903c00d3703d00e200241f0116a41206a201b3703002006420037020020334200370200203b41003602002002200837038812200220053602f011202420022f01940d3b0100202441026a20022d00960d3a0000200220163600a712200220073600a3122002201236009f122002201136009b12203c20022903d00e370000203d20022900d50e370000200241003a00b812200e41036a20022800a30d360000200e20022802a00d360000200241900f6a2027200241f0116a10fb02024020022d00d00f4102470d00203821110c140b200241f0116a200241900f6a41c800109a051a024020372010470d00201041016a22052010490d26201041017422112005201120054b1b2237ad42c8007e2208422088a70d262008a722054100480d260240024020100d002005102821380c010b2038201041c8006c2005102c21380b2038450d0f0b2038201041c8006c6a200241f0116a41c800109a051a201041016a2110024020032001470d00200121030c130b02400340200241f0116a41186a2205200341186a290000370300200241f0116a41106a2211200341106a290000370300200241f0116a41086a2212200341086a290000370300200220032900003703f01120024190056a200241f0116a10b004200241b00c6a41086a22072012290300370300200241b00c6a41106a22122011290300370300200241b00c6a41186a22112005290300370300200220022903f0113703b00c20024190056a41086a290300210c200229039005210f20024180056a10a1024200211b200241f0046a20022903800520024180056a41086a290300427f420010a005200241e0046a200f200c20022903f004220842012008420156200241f0046a41086a29030022084200522008501b22051b2008420020051b10a005200241900c6a41086a2007290300370300200241900c6a41106a2012290300370300200d2011290300370300200220022903b00c3703900c20022903e004220850450d012001200341206a2203460d120c000b0b200220022f01900c3b01e00c200220022d00920c3a00e20c200220022800f80c3602b80d2002200341206a22033602e80e2002203a2900003703d00c2002203a41056a2900003700d50c200220392800003600bb0d20022800930c211120022800970c2112200228009b0c2107200228009f0c2116200220022d00e20c3a008a0d200220022f01e00c3b01880d200220022900d50c3700e50d200220022903d00c3703e00d200220022800bb0d3600b30d200220022802b80d3602b00d201921050c000b0b41e4e8c5001032000b411a41011037000b413441011037000b410841011037000b200d41011037000b200d41011037000b41c4d1c300413320024198196a419cd9c3001038000b41c4d1c300413320024198196a419cd9c3001038000b412041011037000b412c41041037000b200341041037000b200341081037000b41c80041081037000b200541081037000b200441011037000b200220013602e80e200121030c010b410121370b20382111200241023a00d00f0b024020032001460d002002200120036b41606a41607120036a41206a3602e80e0b20022802e40e450d0120022802e00e102a0c010b4108213841082111410021100b0240024002400240024002400240024020102015490d000240024020022802c40e220320022802c80e223d6b2004412c6c2201412c6d2205490d0020022802c00e21030c010b203d20056a2205203d490d18200341017422122005201220054b1b2205ad42d0007e2208422088a70d182008a722124100480d180240024020030d002012102821030c010b20022802c00e200341d0006c2012102c21030b2003450d02200220053602c40e200220033602c00e20022802c80e213d0b203520016a213e024020040d002035213b0c070b2003203d41d0006c6a2133203521030340200241c00d6a41186a2204200341186a290200370300200241c00d6a41106a2201200341106a290200370300200241c00d6a41086a2205200341086a290200370300200220032902003703c00d2003412c6a213b2003280220223c450d07200341286a2802002124200341246a280200213a200241900f6a41186a22392004290300370300200241900f6a41106a223f2001290300370300200241900f6a41086a22402005290300370300200220022903c00d3703900f200241d0046a200241900f6a10b0042024ad42387e2208422088a70d092008a72203417f4c0d09200241d0046a41086a290300211c20022903d00421180240024020030d00410821150c010b200310282215450d040b0240024020240d0041002124410021060c010b203c20244105746a213241002106203c21070340200741086a2900002108200741106a290000210c2007290000210f200241f0116a41186a2227200741186a290000370300200241f0116a41106a2216200c370300200241f0116a41086a221920083703002002200f3703f011200741206a2107200241e80c6a210320022802ec0c210d024003402003280200221241086a210420122f0106220e4105742103410021010240024003402003450d01200241f0116a20044120109c052205450d02200341606a2103200141016a2101200441206a21042005417f4a0d000b2001417f6a210e0b200d450d02200d417f6a210d2012200e4102746a4194036a21030c010b0b2010201220014102746a41e8026a220328020022044d0d072011200441c8006c6a22042903102108200441186a290300210c200241c0046a10a102200241b0046a20022903c004200241c0046a41086a290300427f420010a0052010200328020022044d0d08200241a0046a2018201c20022903b004220f4201200f420156200241b0046a41086a290300220f420052200f501b22011b200f420020011b10a0052011200441c8006c6a220441186a427f200c200820022903a0047c220f2008542201ad7c221b2001201b200c54200f20085a1b22011b3703002004427f200f20011b370310200241900c6a41186a22042027290300370300200241900c6a41106a22012016290300370300200241900c6a41086a22052019290300370300200220022903f0113703900c200328020021120240024020062024460d00200621030c010b202441016a22032024490d1c2024410174220d2003200d20034b1b220dad42387e2208422088a70d1c2008a722034100480d1c0240024020240d002003102821150c010b2015202441386c2003102c21150b2015450d0a20242103200d21240b2015200341386c6a220342003703082003420037030020032012360210200320022903900c3702142003411c6a2005290300370200200341246a20012903003702002003412c6a2004290300370200200641016a21060b20072032470d000b0b0240203a450d00203c102a0b200241b00c6a41186a22032039290300370300200241b00c6a41106a2204203f290300370300200241b00c6a41086a22012040290300370300200220022903900f3703b00c20024190046a10a10220024180046a20022903900420024190046a41086a290300427f420010a005200241f0036a2018201c20022903800422084201200842015620024180046a41086a29030022084200522008501b22051b2008420020051b10a00520334200370308203320022903f00337030020334200370310203341186a4200370300203320063602282033202436022420332015360220203320022903b00c37022c203341346a20012903003702002033413c6a2004290300370200203341c4006a2003290300370200203d41016a213d203341d0006a2133203b2103203b203e470d000b2002203d3602c80e0c070b02402037450d002038102a0b024020022802c80e2203450d00200341d0006c210120022802c00e41206a210303400240200341046a280200450d002003280200102a0b200341d0006a2103200141b07f6a22010d000b0b024020022802c40e450d0020022802c00e102a0b20022802e80c20022802ec0c20022802f00c10bc0202402004450d002004412c6c2104203541206a210303400240200341046a280200450d002003280200102a0b2003412c6a2103200441546a22040d000b0b2036450d0f2035102a0c0f0b201241081037000b200341081037000b41a09ec400200420101034000b41b09ec400200420101034000b200341081037000b2002203d3602c80e203b203e460d000340203b41206a2802002204450d01203b412c6a21030240203b41246a280200450d002004102a0b2003213b203e2003470d000b0b02402036450d002035102a0b2034ad42307e2208422088a70d002008a72203417f4c0d00024002400240024020030d00410821060c010b200310282206450d010b2034412c6c2203417f4c0d0202400240024020030d004104213f0c010b20031028223f450d010b4100213602402010203420102034491b223b0d0020342141410021390c030b2011201041c8006c22356a2127200241f0116a41106a2132200241f0116a41086a213320112103203421164100213941002119034002402010450d002035210403400240200341c0006a2d00000d00200241e0036a427f427f200341106a290300220842012008420156200341186a29030022084200522008501b22011b2008420020011b10a0052003200241e0036a41086a290300370308200320022903e0033703000b200341c8006a2103200441b87f6a22040d000b0b20022802c00e220520022802c80e220e41d0006c6a211502400240024002400240200e450d00200521120340024020122802282203450d00200341386c2101201228022041106a210303402010200328020022044d0d0402402011200441c8006c6a22042d00400d002004290310220c200441186a290300220f84500d00200241d0036a2012290300220842004280808080104200109f05200241a0036a4200420020084200109f05200241c0036a427f20022903d003201241086a290300220842ffffffff0f8320085220022903a80342005272200241d0036a41086a290300221b200842208620022903a0037c7c2208201b547222071b427f200820071b200c200f10a005200241b0036a201241146a350200201241186a290300220842208684200842208820022903c003200241c0036a41086a290300109f052004427f2004290300220820022903b0037c220c200c2008542207200441086a220d2903002208200241b0036a41086a2903007c2007ad7c220c200854200c2008511b22071b370300200d427f200c20071b3703000b200341386a2103200141486a22010d000b0b201241d0006a22122015470d000b0b201941016a21192011201041c8006c6a21122035210420112103024003402003210102400240201220036b41d8014d0d00200141c0006a2d00000d01200141c8006a21030c070b0340024020040d00201621410c0c0b200441b87f6a2104200141c0006a2107200141c8006a2203210120072d00000d000b200341b87f6a21010c060b20014188016a2d0000450d01200141d0016a2d0000450d03200441e07d6a2104200141a0026a210320014198026a2d00000d000b410321040c030b20014190016a2103410121040c020b41bcc0c200200420101034000b200141d8016a2103410221040b2001200441c8006c6a21010b024020032012460d00200141086a29030021082001290300210c0340200341c8006a21040240200341c0006a2d00000d00200341086a290300220f2008200c2003290300221b562008200f562008200f511b22121b2108201b200c20121b210c2003200120121b21010b2004210320272004470d000b0b200141013a00400240200e450d002001410c6a210d200141206a210e0340200541d0006a2124024020052802282204450d0020052802202103200441386c2104034002400240200d2003460d00200341146a200e4120109c050d010b200541186a22122903002108200141086a2207290300210c20032001290300220f2005290310221b7d3703002003200c20087d200f201b54ad7d3703082001290300210820122007290300370300200520083703100b200341386a2103200441486a22040d000b0b2024210520242015470d000b0b200129031021082032200141306a2900003703002033200141286a290000370300200141186a290300210c200241f0116a41186a2203200141386a290000370300200220012900203703f01102400240024020392016460d00201621410c010b201641016a22042016490d15201641017422012004200120044b1b2241ad42307e220f422088a70d15200fa722044100480d150240024020160d002004102821060c010b2006201641306c2004102c21060b2006450d0120162139204121160b2033290300210f2032290300211b2003290300211c20022903f01121182006203941306c6a2203200837032020032018370300200341286a200c370300200341186a201c370300200341106a201b370300200341086a200f370300203941016a2139201121032019203b4f0d040c010b0b200441081037000b200341041037000b200341081037000b024020022802c80e2203450d0020022802c00e2235200341d0006c6a2140200641e0006a213b2006203941306c22036a210d200241900e6a41186a213c200241900e6a41106a213d200241900e6a41086a213a20034191014921334100213602400340203c203541c4006a290000370300203d2035413c6a290000370300203a203541346a2900003703002002203529002c3703900e024020352802282203450d0020352802202204200341386c6a21322035412c6a211641002127410821194100211503402006210302400240024020330d00203b2103024002400240200441146a2201200241f0116a46220e450d0020062903202108200641086a290300210c200641106a290300210f200641186a290300211b2006290300211c200241f0116a41286a200641286a290300370300200241f0116a41186a201b370300200241f0116a41106a200f370300200241f0116a41086a200c37030020022008370390122002201c3703f0110c010b024002400340200341406a22102903002108200341a07f6a2205290300210c200541086a290300210f200541106a290300211b200541186a290300211c200241f0116a41286a2205201041086a290300370300200241f0116a41186a2210201c370300200241f0116a41106a2211201b370300200241f0116a41086a2212200f37030020022008370390122002200c3703f011200241f0116a20014120109c05450d03200341706a22242903002108200341506a2207290300210c200741086a290300210f200741106a290300211b200741186a290300211c2005202441086a2903003703002010201c3703002011201b3703002012200f37030020022008370390122002200c3703f0110240200e0d00200241f0116a20014120109c05450d00200341206a2903002108200341086a290300210c200341106a290300210f200341186a290300211b2003290300211c2005200341286a2903003703002010201b3703002011200f3703002012200c37030020022008370390122002201c3703f011200e0d03200241f0116a20014120109c05450d03200341d0006a2903002108200341306a290300210c200341386a290300210f200341c0006a290300211b200341c8006a290300211c2005200341d8006a2903003703002010201c3703002011201b3703002012200f37030020022008370390122002200c3703f011200e0d02200241f0116a20014120109c05450d02200341e0006a2105200341c0016a2103200d20056b4190014d0d050c010b0b200241900f6a41286a2005290300370300200241900f6a41206a200241f0116a41206a290300370300200241900f6a41186a2010290300370300200241900f6a41106a2011290300370300200241900f6a41086a2012290300370300200220022903f0113703900f0c050b200241900f6a41286a2005290300370300200241900f6a41206a200241f0116a41206a290300370300200241900f6a41186a2010290300370300200241900f6a41106a2011290300370300200241900f6a41086a2012290300370300200220022903f0113703900f0c040b200241900f6a41286a2005290300370300200241900f6a41206a200241f0116a41206a290300370300200241900f6a41186a2010290300370300200241900f6a41106a2011290300370300200241900f6a41086a2012290300370300200220022903f0113703900f0c030b200241900f6a41286a200241f0116a41286a290300370300200241900f6a41206a200241f0116a41206a290300370300200241900f6a41186a200241f0116a41186a290300370300200241900f6a41106a200241f0116a41106a290300370300200241900f6a41086a200241f0116a41086a290300370300200220022903f0113703900f0c020b200341a07f6a21030b2003200d460d0102400240200441146a2201200241f0116a470d0020032903202108200341086a290300210c200341106a290300210f200341186a290300211b2003290300211c200241f0116a41286a200341286a290300370300200241f0116a41186a201b370300200241f0116a41106a200f370300200241f0116a41086a200c37030020022008370390122002201c3703f0110c010b0340200341206a2903002108200341086a290300210c200341106a290300210f200341186a290300211b2003290300211c200241f0116a41286a200341286a290300370300200241f0116a41186a201b370300200241f0116a41106a200f370300200241f0116a41086a200c37030020022008370390122002201c3703f011200241f0116a20014120109c05450d01200d200341306a2203470d000c030b0b200241900f6a41286a200241f0116a41286a290300370300200241900f6a41206a200241f0116a41206a290300370300200241900f6a41186a200241f0116a41186a290300370300200241900f6a41106a200241f0116a41106a290300370300200241900f6a41086a200241f0116a41086a290300370300200220022903f0113703900f0b200241e00e6a41286a200241900f6a41286a2903002208370300200241e00e6a41206a200241900f6a41206a290300220c370300200241e00e6a41186a200241900f6a41186a290300220f370300200241e00e6a41106a200241900f6a41106a290300221b370300200241e00e6a41086a200241900f6a41086a290300221c370300200220022903900f22183703e00e200241f0116a41286a2008370300200241f0116a41206a200c370300200241f0116a41186a200f370300200241f0116a41106a201b370300200241f0116a41086a201c370300200220183703f011200241f0116a2016460d00200241f0116a20164120109c05450d00024002402035290310221b2004290300220c85203541186a290300220f200441086a2903002208858450450d0042002108428080808010210c0c010b20024190036a200c42004280808080104200109f0520024180036a42004200200c4200109f050240200842ffffffff0f832008522002290388034200527220024190036a41086a290300221c20084220862002290380037c7c2218201c54724101470d000240201b422088200f42208684221b200f422088220f84500d00200241e0026a200c2008201b200f10a005200241e0026a41086a290300210820022903e002210c0c020b41dcc0c2001032000b200241f0026a2002290390032018201b4201201b420156200f420052200f501b22031b200f420020031b10a005200241f0026a41086a290300210820022903f002210c0b200220042f00143b01a00d2002200441166a2d00003a00a20d2002200441276a2900003703f80c20022004412c6a2900003700fd0c200441236a28000021012004411f6a28000021052004411b6a2800002110200441176a280000211102400240024020152027460d00201521030c010b202741016a22032027490d17202741017422122003201220034b1b2212ad42307e220f422088a70d17200fa722034100480d170240024020270d002003102821190c010b2019202741306c2003102c21190b2019450d0120272103201221270b20022d00a20d211220022f01a00d21072019200341306c6a2203200136000f2003200536000b2003201036000720032011360003200320073b0100200341026a20123a00002003200c370320200341286a2008370300200320022903f80c370013200341186a20022900fd0c370000201541016a21150c010b200341081037000b200441386a22042032470d000b024020150d002027450d012019102a0c010b02400240201541306c22040d00420021084200210c0c010b201941206a2103420021084200210c0340200341086a290300200c7c2003290300220c20087c2208200c54ad7c210c200341306a2103200441506a22040d000b0b200241d0026a420042808080801020087d220f200f428080808010564200200c200842808080801056ad7c7d22084200522008501b22031b221c4200200820031b22082015ad2218420010a00520022903d002210f0240201c20185441002008501b0d00200241d0026a41086a290300211b2015417f6a2110201941206a21034100210403402003427f20032903002208200f7c220c200c2008542201200341086a22052903002208201b7c2001ad7c220c200854200c2008511b22011b3703002005427f200c20011b37030020102004460d01200341306a21032015200441016a22044b0d000b41ccc0c200200420151034000b200241c0026a200f200820182008109f050240201c20022903c0027da72205450d004100210303402019200320157041306c6a2204427f2004290320220842017c220c200c2008542201200441286a2204290300220f2001ad7c221b200f54200c20085a1b22011b3703202004427f201b20011b370300200341016a22032005490d000b0b200241f0116a41186a2204203c290300370300200241f0116a41106a2201203d290300370300200241f0116a41086a2205203a290300370300200220022903900e3703f011024020362034470d00203441016a22032034490d14203441017422102003201020034b1b2210ad422c7e2208422088a70d142008a722034100480d140240024020340d0020031028213f0c010b203f2034412c6c2003102c213f0b203f450d0320342136201021340b203f2036412c6c6a220320022903f011370200200529030021082001290300210c2004290300210f200320153602282003202736022420032019360220200341186a200f370200200341106a200c370200200341086a2008370200203641016a21360b203541d0006a22352040470d000c020b0b200341041037000b02402037450d002038102a0b024020022802c80e2203450d00200341d0006c210420022802c00e41206a210303400240200341046a280200450d002003280200102a0b200341d0006a2103200441b07f6a22040d000b0b024020022802c40e450d0020022802c00e102a0b20022802e80c20022802ec0c20022802f00c10bc022006450d08203941306c220341306e21040240024020030d0041012142420021300c010b200441057422014100480d10200110282242450d072004ad21300b024002402006200620036a470d00410021190c010b203941306c2101410021192042210320062104034020032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a290000370000201941016a2119200341206a2103200441306a2104200141506a22010d000b0b200242003702ec0c200241f8b9c0003602e80c024020194105742203450d00204220036a213b200241f0116a4102722143200241900c6a41136a213c200241b00c6a41136a2144204221070340200241b0026a200710b004200241b0026a41086a290300210c20022903b002210f200241a0026a10a10220024190026a20022903a002200241a0026a41086a290300427f420010a00520024180026a200f200c20022903900222084201200842015620024190026a41086a29030022084200522008501b22031b2008420020031b10a005200741086a2900002108200741106a290000210c2007290000210f200241e00e6a41186a220e200741186a290000370300200241e00e6a41106a2224200c370300200241e00e6a41086a221520083703002002200f3703e00e20022903800221080240024002400240024002400240024020022802e80c221041f8b9c000460d0020022802ec0c21110c010b200241900f6a410041e0021099051a200241f0116a41004190041099051a41f80610282210450d0141002111201041003b010620104100360200201041086a200241900f6a41e002109a051a201041e8026a200241f0116a419004109a051a200241003602ec0c200220103602e80c0b200741206a210702400340201041086a2104201041066a210d20102f01062212410574210341002101024003402003450d01200241e00e6a20044120109c052205450d03200341606a2103200141016a2101200441206a21042005417f4a0d000b2001417f6a21120b02402011450d002011417f6a2111201020124102746a41f8066a28020021100c010b0b200241c00d6a41186a2203200e290300370300200241c00d6a41106a2024290300220c370300200241c00d6a41086a2015290300220f370300200220022903e00e221b3703c00d200220022802f00c41016a3602f00c200241900e6a41106a2239200c370300200241900e6a41086a2240200f370300200241900e6a41186a223e20032903003703002002201b3703900e200d2f01002204410b490d04200241900f6a410041e0021099051a200241f0116a41004190041099051a41f80610282203450d02200341003b010620034100360200200341086a200241900f6a41e002109a052101200341e8026a200241f0116a419004109a052105200241b00c6a41086a2245201041d0016a290000370300200241b00c6a41106a2246201041d8016a290000370300200241b00c6a41186a2247201041e0016a290000370300200241f0116a41086a222720104190056a290300370300200241f0116a41106a221620104198056a290300370300200241f0116a41186a2232201041a0056a290300370300200241f0116a41206a2233201041a8056a290300370300200241f0116a41286a2235201041b0056a290300370300200220102900c8013703b00c20022010290388053703f0112001201041e8016a20102f010641796a2204410574109a0521012005201041b8056a200441306c109a052105201041063b0106200320043b0106200220022f01b00c3b01e00c200220022d00b20c3a00e20c200220442900003703d00c2002204441056a22482900003700d50c20022800b30c214920022800b70c214a20022800bb0c214b20022800bf0c214c200241900f6a41286a224d2035290300370300200241900f6a41206a224e2033290300370300200241900f6a41186a224f2032290300370300200241900f6a41106a22502016290300370300200241900f6a41086a22512027290300370300200220022903f0113703900f0240024020124107490d00201241057420016a41c07e6a2001201241796a22114105746a2201200441ffff037120116b410574109b051a200141186a203e290300370000200141106a2039290300370000200141086a2040290300370000200120022903900e370000201241306c20056a220441e07d6a200441b07d6a2204200341066a220d2f010020116b41306c109b051a200441186a4200370300200420083703102004420037030820042008370300200441286a4100360200200442083703200c010b201041086a20124105746a220441206a2004200d2f010020126b410574109b051a200441186a203e290300370000200441106a2039290300370000200441086a2040290300370000200420022903900e370000201041e8026a201241306c6a220441306a2004200d2f010020126b41306c109b051a200441186a4200370300200420083703102004420037030820042008370300200441286a4100360200200442083703200b200d200d2f010041016a3b0100200241d00e6a41026a220420022d00e20c3a00002015205129030037030020242050290300370300200e204f290300370300200241e00e6a41206a2238204e290300370300200241e00e6a41286a2237204d290300370300200220022f01e00c3b01d00e200220022903d00c3703900c200220022900d50c3700950c200220022903900f3703e00e200241e00d6a41286a22522037290300370300200241e00d6a41206a22532038290300370300200241e00d6a41186a2254200e290300370300200241e00d6a41106a22552024290300370300200241e00d6a41086a22562015290300370300200220022903e00e3703e00d200220022f01d00e3b01a00d200220042d00003a00a20d200220022903900c3703f80c200220022900950c3700fd0c0240201028020022110d00200241e80c6a2104200321010c060b20102f0104213d41002157200321580340200241b80d6a41026a225920022d00a20d3a0000200220022f01a00d3b01b80d200220022903f80c3703d00e200220022900fd0c3700d50e2037205229030037030020382053290300370300200e20542903003703002024205529030037030020152056290300370300200220022903e00d3703e00e203d41ffff0371211202400240024020112f01062203410b490d002043410041a2071099051a41a80710282205450d0720054100360200200541046a200241f0116a41a407109a051a2047201141e0016a2900003703002046201141d8016a2900003703002045201141d0016a290000370300200220112900c8013703b00c2035201141b0056a2903003703002033201141a8056a2903003703002032201141a0056a290300370300201620114198056a290300370300202720114190056a29030037030020022011290388053703f011200541086a201141e8016a20112f0106220441796a2203410574109a05215a200541e8026a201141b8056a200341306c109a05215b200541f8066a20114194076a2004417a6a220d410274109a05213a201141063b0106200520033b01060240200d450d0041002103203a210403402004280200220120033b010420012005360200200441046a2104200d200341016a2203470d000b0b204d2035290300370300204e2033290300370300204f20322903003703002050201629030037030020512027290300370300200220022903f0113703900f200220022f01b00c3b01e00c200220022d00b20c3a00e20c20022900b30c210820022900bb0c210c200220482900003700d50c200220442900003703d00c203c20022903d00c370000203c41056a220d20022900d50c370000200220022d00e20c3a00920c200220022f01e00c3b01900c2002200c37009b0c200220083700930c2035204d2903003703002033204e2903003703002032204f2903003703002016205029030037030020272051290300370300200220022903900f3703f011203d41ffff037122044107490d01205a2012417a6a22014105746a205a201241796a22034105746a220420052f010620036b410574109b051a200441186a20022900d50e3700002004204c36000f2004204b36000b2004204a36000720042049360003200441026a20592d00003a0000200420022f01b80d3b0000200420022903d00e370013201241306c205b6a220441e07d6a200441b07d6a220420052f0106223d20036b41306c109b051a200441286a2037290300370300200441206a2038290300370300200441186a200e290300370300200441106a2024290300370300200441086a2015290300370300200420022903e00e3703002005203d41016a22043b01062012410274223d203a6a416c6a203a20014102746a2212200441ffff037120016b410274109b051a20122058360200200120052f010622124b0d022005203d6a41e0066a2104034020042802002201200341016a22033b010420012005360200200441046a210420032012490d000c030b0b201141086a2204201241016a22014105746a200420124105746a2204200320126b2205410574109b051a2004204c36000f2004204b36000b2004204a36000720042049360003200441026a20592d00003a0000200420022f01b80d3b0000200420022903d00e370013200441186a20022900d50e3700002011201241306c6a22044198036a200441e8026a220d200541306c109b051a20044190036a203729030037030020044188036a203829030037030020044180036a200e290300370300200441f8026a2024290300370300200441f0026a2015290300370300200d20022903e00e3703002011200341016a22033b01062012410274201141f8066a22046a41086a200420014102746a2204200341ffff037120016b410274109b051a200420583602000240201220112f010622034f0d00205820013b010420582011360200200120034f0d002003417f6a210520112001417f6a22034102746a4180076a2104034020042802002201200341026a3b010420012011360200200441046a21042005200341016a2203470d000b0b41001a200241e80c6a1a20101a0c090b201141086a2203201241016a22014105746a200320124105746a220320112f0106223d20126b223a410574109b051a2003204c36000f2003204b36000b2003204a36000720032049360003200341026a20592d00003a0000200320022f01b80d3b0000200320022903d00e370013200341186a20022900d50e370000201141e8026a201241306c6a220341306a2003203a41306c109b051a200341286a2037290300370300200341206a2038290300370300200341186a200e290300370300200341106a2024290300370300200341086a2015290300370300200320022903e00e3703002011203d41016a22033b01062012410274223a201141f8066a223d6a41086a203d20014102746a223d200341ffff037120016b410274109b051a203d2058360200200420112f010622014f0d002011203a6a41fc066a2103034020032802002204201241016a22123b010420042011360200200341046a210320012012470d000b0b205741016a2112200241b00d6a41026a220320022d00920c3a00002040202729030037030020392016290300370300203e2032290300370300200241900e6a41206a22042033290300370300200241900e6a41286a22012035290300370300200220022f01900c3b01b00d200220022903f0113703900e2002203c2900003703c00e2002200d2900003700c50e20022800930c214920022800970c214a200228009b0c214b200228009f0c214c20522001290300370300205320042903003703002054203e2903003703002055203929030037030020562040290300370300200220022903900e3703e00d200220022f01b00d3b01a00d200220032d00003a00a20d200220022903c00e3703f80c200220022900c50e3700fd0c0240201128020022030d0020111a200241e80c6a22041a200521010c070b20112f0104213d200241e80c6a1a20111a2003211120052158201221570c000b0b2010200141306c6a22034180036a4200370300200341f8026a2008370300200341f0026a4200370300200341e8026a200837030020034190036a410036020020034188036a220128020021042003418c036a2802002103200142083703002004450d052003450d052004102a0c050b41f80641081037000b41f80641081037000b41a80741081037000b201020124105746a220341286a200341086a2201200420126b410574109b051a200341206a203e290300370000200341186a2039290300370000200341106a2040290300370000200120022903900e3700002010201241306c6a22034198036a200341e8026a220420102f010620126b41306c109b051a20034190036a410036020020034188036a420837030020034180036a4200370300200341f8026a2008370300200341f0026a420037030020042008370300201020102f010641016a3b01060c010b2043410041a2071099051a41a80710282203450d0820034100360200200341046a200241f0116a41a407109a051a2003200428020022053602f806200420033602002004200428020441016a360204200541003b010420052003360200200320032f010622054105746a220441086a20022f01a00d3b00002004410a6a20022d00a20d3a0000200441176a204c360000200441136a204b3600002004410f6a204a3600002004410b6a20493600002004411b6a20022903f80c370000200441206a20022900fd0c3700002003200541306c6a220441e8026a20022903e00d370300200441f0026a2056290300370300200441f8026a205529030037030020044180036a205429030037030020044188036a205329030037030020044190036a2052290300370300200341f8066a200541016a22044102746a2001360200200320043b0106200120043b01042001200336020020101a0b2007203b470d000b0b02402036412c6c2203450d00203f20036a2132203f210d03400240200d28022841306c2203450d00200d280220220e20036a21150340200241f0016a200d10b004200e221041286a2224290300210f20102903202108200241f0016a41086a290300211b20022903f001211c200241e0016a10a102200241d0016a20022903e001200241e0016a41086a290300427f420010a005200241c0016a201c201b20022903d001220c4201200c420156200241d0016a41086a290300220c420052200c501b22031b200c420020031b10a005200241a0016a200f420020022903c001220c4200109f05200241b0016a20084200200c4200109f0520024190016a4200420020084200109f0542ffffffff0f200241b0016a41086a290300220820022903a0012002290390017c7c220c42208820022903a80120022903980184420052200c2008547222031b2108427f20023502b401200c4220868420031b210c201041306a210e200241e80c6a210320022802ec0c21120240024003402003280200221141086a210420112f010622074105742103410021010240024003402003450d01201020044120109c052205450d02200341606a2103200141016a2101200441206a21042005417f4a0d000b2001417f6a21070b2012450d022012417f6a2112201120074102746a41f8066a21030c010b0b2011200141306c6a220341f8026a2204427f2004290300220f200c7c221b201b200f54220420034180036a2201290300220f20087c2004ad7c221b200f54201b200f511b22041b3703002001427f201b20041b370300200241f0116a41186a2211200d41186a290000370300200241f0116a41106a2212200d41106a290000370300200241f0116a41086a2207200d41086a2900003703002002200d2900003703f01120034188036a2105024020034190036a220128020022042003418c036a280200470d00200441016a22032004490d16200441017422272003202720034b1b2227ad42307e220f422088a70d16200fa722164100480d160240024020040d002016102821030c010b2005280200200441306c2016102c21030b2003450d0220052003360200200541046a2027360200200128020021040b2005280200200441306c6a220320022903f0113703002003200c370320200341186a2011290300370300200341106a2012290300370300200341086a2007290300370300200341286a20083703002001200128020041016a3602000b2010200c37032020242008370300200e2015460d020c010b0b201641081037000b200d412c6a220d2032470d000b0b200241e00e6a41086a22034200370300200242003703e00e41a5afc4004116200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a100621030240024020022802f0112204417f460d002003450d00200220043602e40e200220033602e00e200241f0116a200241e00e6a106d20022802f0112207450d0320022902f41121082004450d012003102a0c010b42002108410121070b02402007450d002008422088a72203450d0020034105742101200721040340410f10282203450d04200341002900edae44370000200341076a41002900f4ae443700002002428f808080f0013702f411200220033602f0112004200241f0116a108f0120022802f811210320022802f0112105200241900c6a41186a22104200370300200241900c6a41106a22114200370300200241900c6a41086a22124200370300200242003703900c20052003200241900c6a1000200241c00d6a41186a2010290300370300200241c00d6a41106a2011290300370300200241c00d6a41086a2012290300370300200220022903900c3703c00d024020022802f411450d0020022802f011102a0b200441206a2104200241c00d6a41201009200141606a22010d000b0b02402008a7450d002007102a0b20022802f00c211020022802e80c21030240024020022802ec0c22010d00200321040c010b2001210520032104034020042802f80621042005417f6a22050d000b0340200320032f01064102746a41f8066a28020021032001417f6a22010d000b0b200241ac0f6a20032f0106360200200241900f6a41186a4100360200200241a40f6a2003360200200220103602b00f200241003602a00f200242003703980f200220043602940f200241003602900f200241f0116a200241900f6a10b1020240200241b0126a223b280200220d0d00427f2120427f211c0c080b200241f0116a41106a2101200241a8126a2133200241f0116a41286a2135427f2120427f211c0340200241e00d6a41086a200241f0116a41086a22112903002208370300200241e00d6a41106a2001290300220c370300200241e00d6a41186a200241f0116a41186a2205290300220f370300200220022903f011221b3703e00d203329030021182035290300211f20022802b412212420022802b812210320022903a0122121200229039012212f200241900e6a41186a2215200f370300200241900e6a41106a2227200c370300200241900e6a41086a221620083703002002201b3703900e20024180016a10a102200241e0006a20022903800120024180016a41086a290300427f420010a005200241f0006a10a102200241c0006a2002290370200241f0006a41086a290300427f420010a005200241d0006a2002290360220842012008420156200241e0006a41086a29030022084200522008501b22041b2008420020041b202f201f109f05200241306a2002290340220842012008420156200241c0006a41086a29030022084200522008501b22041b2008420020041b20212018109f05200241d0006a41086a290300211f200241306a41086a290300211b4100211220022903502121200229033021184100210e410821070240200341306c2210450d00201041306d220ead42307e2208422088a70d112008a722044100480d11200410282207450d050b02402003450d00200341047441706a213220072103200d21040340200441286a290300210c200441206a290300210f2005200441186a2903003703002001200441106a2903003703002011200441086a290300370300200220042903003703f011200241206a10a102200241106a2002290320200241206a41086a290300427f420010a00520022002290310220842012008420156200241106a41086a29030022084200522008501b22121b2008420020121b200f200c109f052003200241086a29030037030820032002290300370300200341106a20022903f011370300200341186a2011290300370300200341206a2001290300370300200341286a2005290300370300200341306a2103200441306a2104201041506a22100d000b203241047641016a21120b02402024450d00200d102a0b2012ad42307e2208422088a70d012008a72203417f4c0d010240024020030d004108210d0c010b20031028220d450d060b0240024020120d00410021100c010b2007201241306c6a211141002110200d2103200721040340200320042903003703002003200441086a290300370308200341106a200441106a290300370300200341186a200441186a290300370300200341206a200441206a290300370300200341286a200441286a290300370300200341306a2103201041016a2110200441306a22042011470d000b0b2005201f3703002002202137038012200220183703f011200220103602981220022012360294122002200d360290122002201b3703f811200241e00e6a41186a2015290300370300200241e00e6a41106a2027290300370300200241e00e6a41086a2016290300370300200220022903900e3703e00e0240410f10282203450d00200341002900edae44370000200341076a41002900f4ae443700002002428f808080f0013702b40c200220033602b00c200241e00e6a200241b00c6a108f0120022802b80c210320022802b00c2104200241900c6a41186a22054200370300200241900c6a41106a22104200370300200241900c6a41086a22114200370300200242003703900c20042003200241900c6a1000200241c00d6a41186a2005290300370300200241c00d6a41106a2010290300370300200241c00d6a41086a2011290300370300200220022903900c3703c00d024020022802b40c450d0020022802b00c102a0b200241003602e80e200242013703e00e2002200241f0116a3602b00c200241b00c6a200241e00e6a10a301200220013602b00c200241b00c6a200241e00e6a10a30120022802901221032002280298122204200241e00e6a10b40102402004450d00200441306c21040340200341106a200241e00e6a108f01200220033602b00c200341306a2103200241b00c6a200241e00e6a10a301200441506a22040d000b0b20022802e40e2103200241c00d6a412020022802e00e220420022802e80e100702402003450d002004102a0b20182020542103201b201c512104201b201c5421050240200228029412450d00200228029012102a0b2003200520041b21030240200e450d002007102a0b201b201c20031b211c2018202020031b2120200241f0116a200241900f6a10b10220022802b012220d450d090c010b0b410f41011037000b1036000b41c4d1c300413320024198196a419cd9c3001038000b410f41011037000b200441081037000b200341081037000b41a80741081037000b200141011037000b200241f0116a200241900f6a10b1020240203b2802002203450d000340024020022802b412450d002003102a0b200241f0116a200241900f6a10b10220022802b01222030d000b0b024020022802940f220341f8b9c000460d00200328020021012003102a2001450d00200128020021042001102a2004450d00024020042802002203450d0003402004102a2003210420032802002201210320010d000b0b2004102a0b200241e00e6a41086a22034200370300200242003703e00e4199fec4004111200241e00e6a1008200241900f6a41086a22042003290300370300200220022903e00e3703900f2002201c3703f811200220203703f011200241900f6a4110200241f0116a4110100720034200370300200242003703e00e41a5afc4004116200241e00e6a100820042003290300370300200220022903e00e3703900f200241003602f811200242013703f0112019200241f0116a10b40102402019450d00201941057421042042210303402003200241f0116a108f01200341206a2103200441606a22040d000b0b20022802f4112103200241900f6a411020022802f011220420022802f811100702402003450d002004102a0b2019ad210802402036450d002036412c6c2104203f41206a210303400240200341046a280200450d002003280200102a0b2003412c6a2103200441546a22040d000b0b2008422086210802402034450d00203f102a0b203020088421082041450d012006102a0c010b200241e00e6a41086a22034200370300200242003703e00e4199fec4004111200241e00e6a1008200241900f6a41086a2003290300370300200220022903e00e3703900f200241003602f011200241900f6a4110200241f0116a10062103024020022802f0112204417f460d002004410f4d0d052003102a0b410021420b024020172014a745720d002013102a0b20420d0102402009450d00200941d0006c2104200a41c0006a210303400240200341046a280200450d002003280200102a0b200341d0006a2103200441b07f6a22040d000b0b200b450d00200a102a0b200041003602000c010b200020083702042000204236020002402009450d00200941d0006c2104200a41c0006a210303400240200341046a280200450d002003280200102a0b200341d0006a2103200441b07f6a22040d000b0b200b450d00200a102a0b200241a0196a24000f0b41c4d1c300413320024198196a419cd9c3001038000b41c4d1c300413320024198196a419cd9c3001038000b1031000baa0b02067f017e230041206b22042400200441106a41086a220542003703002004420037031041f9b5c200411d200441106a1008200441086a2005290300370300200420042903103703000240024002400240024002400240024002400240200441104101410041001003417f470d001098012106024002400240024020024101470d00200441106a41086a220542003703002004420037031041b8bfc200411a200441106a1008200441086a2005290300370300200420042903103703002004410036021020044110200441106a10062105024020042802102207417f460d002005450d0020074104490d06200528000021072005102a200720064b0d020b200441106a41086a220542003703002004420037031041b8bfc200411a200441106a1008200441086a2005290300370300200420042903103703002004200620014101746a36021020044110200441106a410410070b200028020821052000280204210820002802002109200441106a41086a220042003703002004420037031041f9b5c200411d200441106a1008200441086a2000290300370300200420042903103703002004410036021820044201370310410410282200450d052004410436021420042004280218220741046a36021820042000360210200020076a200636000020042802142206200428021822006b4104490d01200428021021060c020b200041046a280200450d0b2000280200102a0c0b0b200041046a22072000490d09200641017422002007200020074b1b22004100480d090240024020060d002000102821060c010b200428021020062000102c21060b2006450d042004200036021420042006360210200428021821000b2004200041046a360218200620006a20013600002005200441106a10b40102402005450d002009200541286c6a21072009210503402005200441106a108f01200541206a290300210a0240024020042802142201200428021822006b4108490d00200428021021010c010b200041086a22062000490d0b200141017422002006200020064b1b22004100480d0b0240024020010d002000102821010c010b200428021020012000102c21010b2001450d072004200036021420042001360210200428021821000b2004200041086a360218200120006a200a3700002007200541286a2205470d000b0b20042802142105200428021821000240024020024101460d000240024020052000460d00200428021021050c010b200041016a22052000490d0b200041017422012005200120054b1b22014100480d0b0240024020000d002001102821050c010b200428021020002001102c21050b2005450d082004200136021420042005360210200428021821000b2004200041016a360218200520006a41003a00000c010b0240024020052000460d00200428021021050c010b200041016a22052000490d0a200041017422012005200120054b1b22014100480d0a0240024020000d002001102821050c010b200428021020002001102c21050b2005450d082004200136021420042005360210200428021821000b2004200041016a360218200520006a41013a00000240024020042802142205200428021822006b4104490d00200428021021050c010b200041046a22012000490d0a200541017422002001200020014b1b22004100480d0a0240024020050d002000102821050c010b200428021020052000102c21050b2005450d092004200036021420042005360210200428021821000b2004200041046a360218200520006a20033600000b2004280214210020044110200428021022052004280218100702402000450d002005102a0b2008450d092009102a0c090b200041046a280200450d082000280200102a0c080b41c4d1c3004133200441106a419cd9c3001038000b410441011037000b200041011037000b200041011037000b200141011037000b200141011037000b200041011037000b1031000b200441206a24000bcb0201057f230041d0006b220224002002410036022820014110200241286a1006210302400240024020022802282204417f460d0020030d010b200041003a00000c010b41002101200241003a00480340024020042001470d000240200141ff0171450d00200241003a00480b41c4d1c3004133200241286a419cd9c3001038000b200241286a20016a200320016a2d00003a00002002200141016a22053a00482005210120054120470d000b200241086a41186a2201200241286a41186a290300370300200241086a41106a2205200241286a41106a290300370300200241086a41086a2206200241286a41086a2903003703002002200229032837030802402004450d002003102a0b20002002290308370001200041013a0000200041196a2001290300370000200041116a2005290300370000200041096a20062903003700000b200241d0006a24000bdf0301017f024002400240024002400240410110282202450d00200220002d00003a0000200241014102102c2202450d01200220002d00013a0001200241024104102c2202450d02200220002d00023a0002200220002d00033a0003200241044108102c2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102c2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102c2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f200128020020012802042002412010072002102a0f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000b952801057f02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2202280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00003a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00013a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00023a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00033a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00043a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00053a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00063a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00073a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00083a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00093a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d0f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000e3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1020012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000f3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00103a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00113a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00123a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00133a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00143a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00153a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00163a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00173a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00183a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00193a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d002006102821050c010b200128020020042006102c21050b2005450d1f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001e3a000002400240200228020020032802002202460d00200128020021040c010b200241016a22042002490d21200241017422052004200520044b1b22054100480d210240024020020d002005102821040c010b200128020020022005102c21040b2004450d2020012004360200200141046a2005360200200141086a28020021020b2003200241016a360200200420026a20002d001f3a00000f0b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200541011037000b1031000b02000ba50201057f230041d0006b21020240200128020022032001280204470d00200041003602000f0b200120034180016a3602002002200329006237012a2002200329006a370132200241086a41086a220120022903303703002002200329007237013a200241086a41106a220420022903383703002002200328007a360142200220032f007e3b0146200241086a41186a22052002290340370300200220032f00603b012820022002290328370308200241286a41186a22062005290300370300200241286a41106a22052004290300370300200241286a41086a220420012903003703002002200229030837032820002003360200200020022903283702042000410c6a2004290300370200200041146a20052903003702002000411c6a20062903003702000b280020004101360204200041086a200128020420012802006b4107762201360200200020013602000bb905020b7f047e23004190016b22032400024002402001280200220420012802042205460d00200120044180016a22063602002003200441e2006a29000037016a2003200441ea006a290000370172200341c8006a41086a220720032903703703002003200441f2006a29000037017a200341c8006a41106a220820032903783703002003200441fa006a280000360182012003200441fe006a2f00003b018601200341c8006a41186a22092003290380013703002003200441e0006a2f00003b016820032003290368370348200341286a41186a220a2009290300370300200341286a41106a220b2008290300370300200341286a41086a220c200729030037030020032003290348370328200541807f6a210d02400340200341086a41186a200a290300220e370300200341086a41106a200b290300220f370300200341086a41086a200c2903002210370300200320032903282211370308200341e8006a41186a200e370300200341e8006a41106a200f370300200341e8006a41086a2010370300200320113703682002450d01200d2004460d02200120064180016a22053602002003200641e2006a29000037016a2003200641ea006a290000370172200720032903703703002003200641f2006a29000037017a200820032903783703002003200641fa006a280000360182012003200641fe006a2f00003b01860120092003290380013703002003200641e0006a2f00003b016820032003290368370348200a2009290300370300200b2008290300370300200c20072903003703002003200329034837032820044180016a21042002417f6a2102200521060c000b0b20002004360200200020032903683702042000410c6a200341f0006a290300370200200041146a200341f8006a2903003702002000411c6a20034180016a2903003702000c010b200041003602000b20034190016a24000ba50201057f230041d0006b21020240200128020022032001280204470d00200041003602000f0b200120034180016a3602002002200329004237012a2002200329004a370132200241086a41086a220120022903303703002002200329005237013a200241086a41106a220420022903383703002002200328005a360142200220032f005e3b0146200241086a41186a22052002290340370300200220032f00403b012820022002290328370308200241286a41186a22062005290300370300200241286a41106a22052004290300370300200241286a41086a220420012903003703002002200229030837032820002003360200200020022903283702042000410c6a2004290300370200200041146a20052903003702002000411c6a20062903003702000bb905020b7f047e23004190016b22032400024002402001280200220420012802042205460d00200120044180016a22063602002003200441c2006a29000037016a2003200441ca006a290000370172200341c8006a41086a220720032903703703002003200441d2006a29000037017a200341c8006a41106a220820032903783703002003200441da006a280000360182012003200441de006a2f00003b018601200341c8006a41186a22092003290380013703002003200441c0006a2f00003b016820032003290368370348200341286a41186a220a2009290300370300200341286a41106a220b2008290300370300200341286a41086a220c200729030037030020032003290348370328200541807f6a210d02400340200341086a41186a200a290300220e370300200341086a41106a200b290300220f370300200341086a41086a200c2903002210370300200320032903282211370308200341e8006a41186a200e370300200341e8006a41106a200f370300200341e8006a41086a2010370300200320113703682002450d01200d2004460d02200120064180016a22053602002003200641c2006a29000037016a2003200641ca006a290000370172200720032903703703002003200641d2006a29000037017a200820032903783703002003200641da006a280000360182012003200641de006a2f00003b01860120092003290380013703002003200641c0006a2f00003b016820032003290368370348200a2009290300370300200b2008290300370300200c20072903003703002003200329034837032820044180016a21042002417f6a2102200521060c000b0b20002004360200200020032903683702042000410c6a200341f0006a290300370200200041146a200341f8006a2903003702002000411c6a20034180016a2903003702000c010b200041003602000b20034190016a24000be6880106147f027e077f017e027f017e230041d0046b22042400200441c0036a20012002200310f903200441c0036a41086a280200210520042802c40321060240024020042802c0034101470d002000200636020420004101360200200041086a20053602000c010b200441d4036a280200220741306c2108200441d8036a2802002109200441d0036a280200210a200441cc036a280200210b4100210c4100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004102470d000b200441d0006a200b200d6a41546a10fa032004280250210c200428025421010b4100210e20014100200c1b210f200741306c2108200c4104200c1b21104100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004108470d000b200441c8006a200b200d6a41546a10fa032004280248210e200428024c21010b4100211120014100200e1b2112200741306c2108200e4104200e1b210d4100210102400340024020082001470d000c020b200b20016a2102200141306a220c210120022d00004104470d000b200441c0006a200b200c6a41546a10fa0320042802402111200428024421010b4100210e2001410020111b2113200741306c21082011410420111b21114100210102400340024020082001470d000c020b200b20016a2102200141306a220c210120022d00004103470d000b200441386a200b200c6a41546a10fa032004280238210e200428023c21010b41002102024020014100200e1b2201450d00200141286c2108200e4104200e1b41186a2101410021020340200220012d0000456a2102200141286a2101200841586a22080d000b0b0240024020120d00411e2101200041b98dc6003602040c010b200d201241146c6a211241002114410021150240024002400340200d450d0141d78dc600210841382101200d41086a280200417c6a220e41024b0d02200d280200210c024002400240200e0e03000501000b41012115200c41af8dc600460d01200c28000041e3c2b1e306460d010c040b41012114200c41b38dc600460d00200c41b38dc6004106109c050d030b0240200d410c6a280200450d0041132101200041d58ec6003602040c050b0240200d41106a280200220120026b220c20014d0d00412a2101200041e88ec6003602040c050b41af8ec6002108412621012013200c4d0d022011200c4102746a220c450d02418f8ec600210841202101200f200c280200220c4d0d022010200c4104746a220c450d0241928fc6002108411f2101200c2802080d02200c2d000d220c41077141044b0d020240200c0e050003030300000b200d41146a220d2012470d000b0b41b18fc60041b98dc600201441017122021b2108411c411e20021b21012002450d002015410171450d00200741306c2108410021010c010b200020083602040c010b0240034020082001460d01200b20016a2102200141306a220d210120022d00004106470d000b200441306a200b200d6a41546a10fa032004280234450d00200041fd8ac600360204411f21010c010b200741306c21082003280268210c410021010240034020082001460d01200b20016a2102200141306a220d210120022d00004105470d000b200441286a200b200d6a41546a220110fa030240200428022c41014d0d00411821012000419c8bc6003602040c020b200441206a200110fa032004280224450d0020042802202201450d002001280200200c4d0d0041222101200041b48bc6003602040c010b200741306c2108410021010240034020082001460d01200b20016a2102200141306a220d210120022d00004107470d000b200441186a200b200d6a41546a10fa0320042802182201200428021c4104746a2108034020012008460d012001450d012001410c6a2102200141106a210120022d0000410271450d000b41322101200041c08cc6003602040c010b200741306c2108410021010240034020082001460d01200b20016a2102200141306a220d210120022d0000410c470d000b200b200d6a2201415c6a2802002202450d00200141546a280200220d200241186c6a210c0340200d220241186a210d2002280208410374210120022802002102024003402001450d01200141786a210120022d00042108200241086a21022008410271450d000b413121012000418f8cc6003602040c030b200d200c470d000b0b200741306c2108410021010240034020082001460d01200b20016a2102200141306a220d210120022d00004102470d000b200441106a200b200d6a41546a10fa0320042802142201450d002004280210220220014104746a211103402002450d01200241106a210e200420022d000d22083a00c0032002280200220120022802086a210c410021024100200441c0036a20084104461b210d024003400240024002400240200241ff01710e03000102000b2001200c460d014100210220012108200141016a21010c020b2001200c460d034101210220012108200141016a21010c010b200d450d0241022102200d21084100210d0b20082d0000410271450d000b41392101200041d68bc6003602040c030b200e2102200e2011470d000b0b200741306c21084100210c4100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004102470d000b200441086a200b200d6a41546a10fa032004280208210c200428020c21010b4100210e20014100200c1b2110200741306c2108200c4104200c1b21124100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004103470d000b2004200b200d6a41546a10fa032004280200210e200428020421010b200e4104200e1b220220014100200e1b41286c6a210d41002113024002400340024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402002200d460d00412d2101418e91c400210820022802084103470d2102402002280200220c41f8e2c500460d00200c41f8e2c5004103109c050d220b200241286a21114115210c418790c400210e4114210141fa90c400210802400240024020022d00180e0400240123000b4136210c41d18fc400210e2010200228021c22014d0d22201220014104746a220f450d222002280214210c200228020c210220092d00700d01200c410b470d014138210141c290c4002108200241ac81c600460d23200241ac81c600410b109c05450d230c210b412f210141bb91c400210820022802144106470d220240200228020c220c41cb8fc400460d00200c41cb8fc4004106109c050d230b02402013450d00411f2101200041ea91c4003602040c280b2002411c6a2113201121020c240b41262101419c90c4002108200c417d6a220c41134b0d2102400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200c0e14003e3e3e0e043e073c0b0a120114111b103e0c19000b200241effec500460d3d200241effec5004103109c05450d3d41effec50020024103109c050d3d41011028220e450d1d200e41003a0000200f2d000c41e000460d010c3a0b200241f2fec500460d0141f2fec5002002410f109c05450d0120024181ffc500460d034181ffc5002002410f109c05450d03024020024198ffc500460d004198ffc5002002410f109c050d3d0b41071028220e450d20200e4100360003200e41013a0002200e41003b0000200f2d000c41e000460d060c380b200f2802084101470d380240200f2802002214200e460d0041002102034020024101460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d3a0c000b0b200f2d000d4104470d38200e102a201121020c3d0b41041028220e450d1b200e4100360000200f2d000c41e000470d35200f2802084104470d350240200f2802002214200e460d0041002102034020024104460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d370c000b0b200f2d000d4104470d35200e102a201121020c3c0b024020024190ffc500460d00200229000042e5f0d1fbb5ac98b6ec00520d3a0b41071028220e450d1c200e4100360003200e41013a0002200e41003b0000200f2d000c41e000460d010c330b41011028220e450d1a200e41003a0000200f2d000c41e000470d31200f2802084101470d31200f2802002214200e460d3041002102034020024101460d31200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d320c000b0b200f2802084107470d31200f2802002214200e460d2e41002102034020024107460d2f200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d320c000b0b200241a7ffc500460d0141a7ffc5002002410a109c05450d010240200241b1ffc500460d0041b1ffc5002002410a109c050d060b4126210c419c90c400210e200f2d000c41e000470d35200f2802080d3520112102200f2d000d4104460d380c350b200f2802084107470d31200f2802002214200e460d2b41002102034020024107460d2c200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d320c000b0b41021028220e450d19200e41003b0000200f2d000c41e000470d29200f2802084102470d290240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d2b0c000b0b200f2d000d4104470d29200e102a201121020c360b0240200241c6ffc500460d0041c6ffc5002002410d109c050d340b4126210c419c90c400210e200f2d000c41e000470d32200f2802080d3220112102200f2d000d4104460d350c320b0240200241d3ffc500460d0041d3ffc5002002410c109c050d330b4126210c419c90c400210e200f2d000c41e000470d31200f2802080d3120112102200f2d000d4104460d340c310b0240200241eaffc500460d0041eaffc50020024115109c050d320b4126210c419c90c400210e200f2d000c41e000470d30200f2802080d3020112102200f2d000d4104460d330c300b0240200241ffffc500460d0041ffffc5002002410a109c050d310b41021028220e450d16200e41003b0000200f2d000c41e000460d010c240b02402002418980c600460d00418980c60020024107109c050d300b4126210c419c90c400210e200f2d000c41e000470d2e200f2802080d2e20112102200f2d000d4104460d310c2e0b200f2802084102470d220240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d240c000b0b200f2d000d4104470d22200e102a201121020c300b02402002419080c600460d00419080c60020024113109c050d2e0b4126210c419c90c400210e200f2d000c41e000470d2c200f2802080d2c20112102200f2d000d4104460d2f0c2c0b200241a380c600460d0141a380c60020024111109c05450d01200241e280c600460d0641e280c60020024111109c05450d060240200241f380c600460d0041f380c60020024111109c050d2d0b41041028220e450d17200e4100360000200f2d000c41e000460d080c1f0b0240200241b480c600460d0041b480c6002002410e109c050d2c0b41081028220e450d13200e4200370000200f2d000c41e000460d020c1d0b41021028220e450d11200e41003b0000200f2d000c41e000470d1b200f2802084102470d1b0240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d1d0c000b0b200f2d000d4104470d1b200e102a201121020c2c0b200241c280c600460d0141c280c60020024110109c05450d01200241d280c600460d0241d280c60020024110109c05450d020240200241b781c600460d0041b781c60020024110109c050d2a0b4126210c419c90c400210e200f2d000c41e000470d28200f2802080d2820112102200f2d000d4104460d2b0c280b200f2802084108470d1a0240200f2802002214200e460d0041002102034020024108460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d1c0c000b0b200f2d000d4104470d1a200e102a201121020c2a0b4126210c419c90c400210e200f2d000c41e000470d26200f2802080d26200f2d000d22014104460d2620112102200141fb0171450d290c260b41031028220e450d0f200e41003a0002200e41003b0000200f2d000c41e000470d16200f2802084103470d160240200f2802002214200e460d0041002102034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d180c000b0b200f2d000d4104470d16200e102a201121020c280b41021028220e450d0f200e41003b0000200f2d000c41e000470d14200f2802084102470d140240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d160c000b0b200f2d000d4104470d14200e102a201121020c270b02402002418481c600460d00418481c60020024116109c050d250b41021028220e450d10200e41003b0000200f2d000c41e000460d020c120b200f2802084104470d160240200f2802002214200e460d0041002102034020024104460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d180c000b0b200f2d000d4104470d16200e102a201121020c250b02402002419a81c600460d00419a81c60020024112109c050d230b4126210c419c90c400210e200f2d000c41e000470d21200f2802080d2120112102200f2d000d4104460d240c210b200f2802084102470d0f0240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d110c000b0b200f2d000d4104470d0f200e102a201121020c230b024020130d0041002116410021170c0e0b024020132802040d002000418992c400360204413221010c260b024020132802002216201341086a28020022174d0d00200041bb92c40036020441c90021010c260b201720032802644d0d0d2000418493c40036020441c10021010c250b410141011037000b410441011037000b410141011037000b410741011037000b410741011037000b410241011037000b410241011037000b410241011037000b410841011037000b410341011037000b410241011037000b410441011037000b410241011037000b20092903082118200441c0036a41086a22024200370300200441f8b9c0003602c4032009290310211920042018a7417f2018428080808010541b3602d00320042019a7417f2019428080808010541b3602c003200441c0036a4104722201410d10fb032001410c10fb032001410710fb032001410f10fb03200441d8006a41106a20042802d003360200200441d8006a41086a2002290300370300200420042903c003370358200441c0036a41106a22082007360200200441c0036a410c6a200a3602002004200b3602c803200420053602c403200420063602c003200441f0006a200441c0036a10fc03024002400240410110282201450d00200141003a0000200420042f01c003220d3b01b002200841e0083b01002002428180808010370300200420013602c403200441013602c0032004200d3b01d203200441f0006a200441c0036a10fd03210c0240410310282202450d00200241026a41002d00fae2453a0000200241002f00f8e2453b00000240410310282208450d00200841026a41002d00f1fe453a0000200841002f00effe453b0000200441b0026a41026a200441c0036a41026a220b2d000022073a0000200420042f00c003220e3b01b00220044184016a280200210d200441f0006a41106a2802002101200b20073a00002004200e3b01c00302400240024002400240024002400240200d2001470d00200141016a220d2001490d012001410174220b200d200b200d4b1b220dad42287e2218422088a70d012018a7220b4100480d010240024020010d00200b102821010c010b200428027c200141286c200b102c21010b2001450d072004200d360280012004200136027c200428028401210d0b200428027c200d41286c6a220141003a00182001200836020c200142838080803037020420012002360200200141106a428380808030370200200141196a20042f01c0033b00002001411b6a200441c2036a2d00003a00002001411c6a200c360200200420042802840141016a36028401200441c0036a200441f0006a418c01109a051a20044180026a200441c0036a10fe0320044180026a41106a280200220e41306c2101200428028802220741546a210202400340410021082001450d01200141506a21012002412c6a210d200241306a220c2102200d2d00004103470d000b200c41086a2802002201450d00200141286c2102200c28020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b200e41306c2101200741546a21022008417f6a210d02400340410021082001450d01200141506a21012002412c6a210c200241306a220b2102200c2d00004103470d000b200b41086a2802002201450d00200141286c2102200b28020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b200e41306c21012007415c6a21020240034041002111024020010d00410021010c020b200141506a2101200241246a210c200241306a220b2102200c2d00004104470d000b200b28020021010b0240024002400240200e450d00200120086a211a2007200e41306c6a2112200441d8006a410472211b4100211c4100211d0340024020072d000041786a220141044b0d00024002400240024020010e050301020400030b200728020c2201450d032007280204220c200141186c6a211e201d210103402001211d0240200c22082802144104742202450d00200828020c21010340024020012d0000410b470d00200141046a220c280200220b200d490d00200c200b41016a3602000b200141106a2101200241706a22020d000b0b200442003703d00320044280808080c0003703c803200442043703c003024002400240411010282201450d0020042802c8032102200420013602c003200441013602c403200120024104746a22014200370200200141056a4200370000200420042802c80341016a3602c80302402008280214221f450d0041002106201f210103400240024002400240024002400240024002400240024002400240200620014f0d004110210c0240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200828020c222020064104746a2d000022140eac010001020202020202020202020202020303030404050506060707080809090a0a0b0b0c0d0d0e0e0f0f1010111213131414151516161717181819191a1a1b1b1c1c1d1d1e1e1f1f2020212122222323242425252627272828292a2a2b2b2c2d2d2e2e2f2f303031313232333434353536363737383839393a3a3b3b3c3c3d3d3e3e3f3f40404141424243434444454546464747484a4a4a4a49494a4a4a4a4a4a4a4a4a4a4a4a4a4a4b4b4b4b000b4111210c0c4a0b4112210c0c490b410a210c0c480b4108210c0c470b4108210c0c460b4104210c0c450b4104210c0c440b4104210c0c430b4104210c0c420b4104210c0c410b4104210c0c400b4104210c0c3f0b4105210c0c3e0b4105210c0c3d0b4105210c0c3c0b4105210c0c3b0b4105210c0c3a0b4113210c0c390b4114210c0c380b4106210c0c370b4107210c0c360b410b210c0c350b410b210c0c340b410b210c0c330b410b210c0c320b410b210c0c310b410b210c0c300b410b210c0c2f0b410b210c0c2e0b410b210c0c2d0b410b210c0c2c0b410b210c0c2b0b410c210c0c2a0b410c210c0c290b410c210c0c280b410c210c0c270b410c210c0c260b410c210c0c250b4100210c0c240b4100210c0c230b4101210c0c220b4102210c0c210b4103210c0c200b4103210c0c1f0b4100210c0c1e0b4100210c0c1d0b4100210c0c1c0b4100210c0c1b0b4100210c0c1a0b4100210c0c190b4101210c0c180b4102210c0c170b4103210c0c160b4103210c0c150b4100210c0c140b4100210c0c130b4100210c0c120b4100210c0c110b410d210c0c100b410d210c0c0f0b410d210c0c0e0b410d210c0c0d0b410d210c0c0c0b410d210c0c0b0b410d210c0c0a0b410d210c0c090b410d210c0c080b410d210c0c070b410d210c0c060b410d210c0c050b410d210c0c040b410d210c0c030b410e210c0c020b410e210c0c010b410f210c0b200641016a210a2004280260210f201b2101024003402001280200221141086a210520112f0106210b41002102024002400340200b20022201460d01200141016a210202404100417f4101200520016a2d00002213200c4b1b2013200c461b41016a0e03000301000b0b2002417f6a210b0b0240200f0d00200441d8006a21020c030b200f417f6a210f2011200b4102746a41ec006a21010c010b0b200441d8006a21020240201120014103746a41146a22012802000e04010d0001010b200141046a21020b20022802002102024002400240024002400240024002402014417e6a220141084b0d0020010e09010302120405050607010b20042802c8032201417f6a220c20014f0d12200c20014b0d1220042802c003200c4104746a220c280208220120026a22022001490d12200c41086a20023602000c130b20042802c8032201417f6a220c20014f0d11200c20014b0d1120042802c003200c4104746a220c280208220120026a22022001490d11200c41086a200236020020042802c8032201417f6a220c20014f0d11200c20014b0d1120042802c0032202200c4104746a280204210c02400240200120042802c403460d002001210b0c010b200141016a220b2001490d2320014101742211200b2011200b4b1b220b41ffffffff0071200b470d23200b41047422114100480d23200220014104742011102c2202450d082004200b3602c403200420023602c00320042802c803210b0b2002200b4104746a2202200e3b000d200241003a000c2002200c360204200220013602002002410f6a200e4110763a0000200241086a4100360200200420042802c80341016a3602c8030c120b20042802c8032201417f6a220c20014f0d10200c20014b0d1020042802c003200c4104746a220c280208220120026a22022001490d10200c41086a200236020020042802c803220221010240200220042802c403470d00200241016a22012002490d222002410174220c2001200c20014b1b220141ffffffff00712001470d222001410474220b4100480d220240024020020d00200b1028210c0c010b20042802c0032002410474200b102c210c0b200c450d08200420013602c4032004200c3602c00320042802c80321010b20042802c00320014104746a2201200e3b000d200141003a000c2001200a360204200120023602002001410f6a200e4110763a0000200141086a4100360200200420042802c80341016a3602c8030c110b20042802c8032201417f6a220c20014f0d0f200c20014b0d0f20042802c003200c4104746a220c280208220120026a22022001490d0f200c41086a200236020020042802c803220221010240200220042802c403470d00200241016a22012002490d212002410174220c2001200c20014b1b220141ffffffff00712001470d212001410474220b4100480d210240024020020d00200b1028210c0c010b20042802c0032002410474200b102c210c0b200c450d08200420013602c4032004200c3602c00320042802c80321010b20042802c00320014104746a2201200e3b000d200141013a000c2001200a360204200120023602002001410f6a200e4110763a0000200141086a4100360200200420042802c80341016a3602c8030c100b200441c0036a200610ff030d0e20042802c8032202450d0e20042002417f6a22013602c80320042802c003220c20014104746a220b2d000c4102460d0e2001450d0f2002417e6a220220014f0d0e200c20024104746a220c200b2802002202200c280200220c200c20024b1b360200200220014f0d0f200441c0036a200610ff030d0e0c0f0b20042802c8032201417f6a220c20014f0d0d200c20014b0d0d20042802c003200c4104746a220c280208220120026a22022001490d0d202020064104746a41046a280200210b200c41086a200236020020042802c8032201417f6a220220014b0d0d2002200b6b220120024b0d0d200441c0036a200610ff030d0d20042802c803220220014d0d0d20042802c003220c20014104746a2d000c0d0e2002410474200c6a41706a2202200120022802002202200220014b1b3602000c0e0b20042802c8032201417f6a220c20014f0d0c200c20014b0d0c20042802c003200c4104746a220c280208220120026a22022001490d0c200c41086a200236020020042802c8032201417f6a220520014b0d0c202020064104746a41046a280200220128020021022001280204210c2004200520012802086b220b20054b22013a00b00220010d0c410410282213450d052013200b36020002400240200c4104490d00200520022802006b220f20054b0d08200241046a21010c010b0240200c0d0041012102410121110c0b0b200520022802006b220f20054b0d07200241046a21010b2002200c4102746a2120410121114104210c4102210b41022102034002402002417f6a22142011470d00201441016a22112014490d1f200b2011200b20114b1b221141ffffffff03712011470d1f201141027422144100480d1f0240024020024101470d002014102821130c010b2013200c2014102c21130b2013450d090b2013200c6a200f36020002400240202020016b410d490d000240200520012802006b220f20054b0d00200141046a21010c020b200441013a00b0020c0d0b20202001460d0b200520012802006b220f20054b0d0a200141046a21010b200b41026a210b200241016a2102200c41046a210c0c000b0b20042802c8032201417f6a220c20014f0d0b200c20014b0d0b20042802c003200c4104746a220c280208220120026a22022001490d0b200c41086a2002360200200441c0036a200610ff030d0b20042802c8032201450d0b20042802c00322022d000c0d0c200141047420026a41706a41003602000c0c0b41fce2c500200620011034000b201141041037000b200b41041037000b200b41041037000b410441041037000b41012111200441013a00b0020c030b201441041037000b200441013a00b0020c010b20042d00b0020d002013450d022002ad4220862011ad842118410121050240200441c0036a200610ff030d0002402018422088a72201450d002001410274210c20132101034020042802c803220b200128020022024d0d02024020042802c003221120024104746a2d000c0d00200b41047420116a41706a220b2002200b280200220b200b20024b1b3602000b200141046a2101200c417c6a220c0d000b0b410021050b02402018a7450d002013102a0b20050d020c030b2011450d012013102a0c010b200441c0036a200610ff03450d010b024020042802c403450d0020042802c003102a0b024020042802d003450d0020042802cc03102a0b4101211c0c0a0b200a201f460d0120082802142101200a21060c000b0b20042802cc0320042802d4032201410041202001676b10800420042903d003212120042802cc03211f024020042802c403450d0020042802c003102a0b0240201f0d004101211c0c080b0240200828021422022021422088a722114101746a220141ffffffff00712001470d002001410474220c417f4c0d00024002400240200c0d004108210b0c010b200c1028220b450d01200828021421020b20084100360214200828020c21222008200b36020c200841106a220b2802002123200b2001360200202220024104746a210f201f20114103746a212041022111024020020d00201f210a202221010c040b41002101201f210a4100210c20222102024002400340200241016a2f0000200241036a2d000041107472210e024020022d0000221341ac01470d00200241106a21010c070b200241086a2900002118200241046a280000210502400240024020114102470d000240200a2020470d00410021112020210a0c020b200a2902002219422088a721152019a7211041012111200a41086a210a0b20114101470d00200c2010470d0002402001200b280200470d00200141016a22112001490d15200141017422062011200620114b1b221141ffffffff00712011470d15201141047422064100480d150240024020010d002006102821010c010b200828020c20014104742006102c21010b2001450d022008200136020c200b2011360200200828021421010b200828020c20014104746a220120042f00c0033b00012001412d3a000020012015360204200141036a200441c0036a41026a2d00003a00002008200828021441016a220136021402402001200b280200470d00200141016a22112001490d15200141017422062011200620114b1b221141ffffffff00712011470d15201141047422064100480d150240024020010d002006102821010c010b200828020c20014104742006102c21010b2001450d042008200136020c200b2011360200200828021421010b200828020c20014104746a220120042f00c0033b00012001410b3a00002001200d36020441022111200141036a200441c0036a41026a2d00003a00002008200828021441016a2201360214200c21100b02402001200b280200470d00200141016a22062001490d14200141017422142006201420064b1b220641ffffffff00712006470d14200641047422144100480d140240024020010d002014102821010c010b200828020c20014104742014102c21010b2001450d042008200136020c200b2006360200200828021421010b200c41016a210c200828020c20014104746a22012018370308200120053602042001200e3b0001200120133a0000200141036a200e4110763a00002008200828021441016a2201360214200241106a2202200f470d010c080b0b200641081037000b200641081037000b201441081037000b200c41081037000b1036000b411041041037000b2001200f460d0003400240024020012d000022024109460d00200241ac01470d010c030b0240200141046a280200220228020441ffffffff0371450d002002280200102a0b2002102a0b200141106a2201200f470d000b0b2021a7210102402023450d002022102a0b200a202047201120114102461b210202402001450d00201f102a0b024020024101470d004101211c0c050b200841186a210c024002402004280268450d0020082802142202450d00200828020c210120024104742102410021080340024020012d0000412c470d002001410b3a0000200141046a201a360200200841016a21080b200141106a2101200241706a22020d000b4101210120080d010b201d21010b200c201e470d000b2001211d0c030b20072802042201200d490d022007200141016a3602040c020b200728020c2201450d012007280204220c2001411c6c6a210b0340200c2201411c6a210c024020012802182202450d0020012802102101200241027421020340024020012802002208200d490d002001200841016a3602000b200141046a21012002417c6a22020d000b0b200c200b460d020c000b0b200728020c2201450d00200141146c2102200728020441106a2101034002402001417c6a2802000d0020012802002208200d490d002001200841016a3602000b200141146a21012002416c6a22020d000b0b200741306a22072012470d000b201c4101710d02201d4101710d01200428029002211120042802880221070b2004418c026a280200210f20042802840221132004280280022105410021060c020b200441c0036a41106a20044180026a41106a280200360200200441c0036a41086a20044180026a41086a29030037030020042004290380023703c003200441b0026a200441c0036a10fc03411010282202450d07200241063a0000410110282201450d06200141003a000041011028220c450d05200c20012d00003a00002001102a411010282208450d04200841063a000041f00010282201450d03200141063a00602001412c3b01502001200d3602442001410b3a0040200141d8003a0030200120042802683602242001412d3a0020200141003602142001410f3a0010200141003602042001410f3a0000024020082d00004109470d0002402008280204220d28020441ffffffff0371450d00200d280200102a2008280204210d0b200d102a0b2008102a024020022d00004109470d0002402002280204220828020441ffffffff0371450d002008280200102a200228020421080b2008102a0b2002102a200441e4036a4287808080f000370200200441e0036a2001360200200441dc036a4100360200200441c0036a410c6a4281808080800c370200200441c8036a4101360200200441003602ec03200442043702d4032004200c3602c403200441013602c003200441b0026a200441c0036a108104200441c0036a200441b0026a418c01109a051a20044198026a200441c0036a10fe0320044198026a410c6a280200210f200441a8026a28020021112004280298022105200428029c02211320042802a0022107410021060c010b2004418c026a280200210f200428028802210702402004280290022211450d00201141306c21022007210103402001108204200141306a2101200241506a22020d000b0b41012106411a211341f28cc60021050240200f450d002007102a0b0b200441e4006a280200210e200428025c21080240200441e0006a2802002201450d000340200828026c21082001417f6a22010d000b0b4100210d4100210102400340200e450d0102400240200120082f01064f0d00200820014103746a41146a2902002118200141016a21010c010b02400240200828020022010d00200dad21184100210c410021010c010b2008330104422086200dad8421184101210c0b2008102a2018a7210d024002402018422088a7220b20012f01064f0d00200121020c010b034002400240200128020022020d00200dad2118410021020c010b200c41016a210c2001330104422086200dad8421180b2001102a2018a7210d200221012018422088a7220b20022f01064f0d000b0b200b41027420026a41f0006a28020021082002200b4103746a41146a29020021180240200c417f6a2201450d000340200828026c21082001417f6a22010d000b0b410021010b200e417f6a210e2018a74103470d000b0b0240200841f8b9c000460d00200828020021012008102a2001450d00200128020021022001102a2002450d00024020022802002201450d0003402002102a2001210220012802002208210120080d000b0b2002102a0b02402006450d002000200536020420004101360200200041086a20133602000c250b200441b0026a41106a2011360200200441b0026a410c6a200f360200200420073602b802200420133602b402200420053602b002200441c0036a200441b0026a2009280260108304024020042802c0034101470d000240200441c0036a41086a280200450d0020042802c403102a0b2000418c8dc60036020420004101360200200041086a41233602000c250b200441d4036a2802002102200441c0036a41106a280200210f200441c0036a410c6a2802002106200441c8036a280200210d20042802c403210820032802582110200441003602a002200442013703980202400240410410282201450d002004410436029c02200420042802a002220c41046a3602a00220042001360298022001200c6a200836000002400240200428029c02220820042802a00222016b4104490d0020042802980221080c010b200141046a220c2001490d0320084101742201200c2001200c4b1b22014100480d030240024020080d002001102821080c010b20042802980220082001102c21080b2008450d022004200136029c02200420083602980220042802a00221010b2004200141046a3602a002200820016a200d3600002006200241306c22016a210d024020020d00200621010c0e0b200141506a2111200441c0036a4101722102200441c0036a41276a210c200441c0036a41206a210b200441c0036a41186a2107200441c0036a41086a210e20062101034020012d00002108200c200141286a290000370000200b200141216a2900003703002007200141196a290000370300200441c0036a41106a2203200141116a290000370300200e200141096a2900003703002004200141016a2900003703c003024020084110470d00200141306a21010c0f0b200441b0026a41276a2213200c290000370000200441b0026a41206a2205200b290300370300200441b0026a41186a20072903002218370300200441b0026a41106a20032903002219370300200441b0026a41086a200e2903002221370300200420042903c00322243703b00220022024370000200241086a2021370000200241106a2019370000200241186a2018370000200241206a2005290300370000200241276a2013290000370000200420083a00c003200441f0006a200441c0036a20044198026a10840420042d00702208411f470d0d201141506a2111200141306a2201200d470d000b200d21010c0d0b410441011037000b200141011037000b1031000b41f00041081037000b411041081037000b410141011037000b410141011037000b411041081037000b200b41041037000b410341011037000b410341011037000b410141011037000b200428027421122004280278211002402011450d00200141306a2101200441c0036a4101722102200441c0036a41276a210b200441c0036a41206a2107200441c0036a41186a210e200441c0036a41086a2111034020012d0000210c200b200141286a2900003700002007200141216a290000370300200e200141196a290000370300200441c0036a41106a2203200141116a2900003703002011200141096a2900003703002004200141016a2900003703c003200c4110460d01200441b0026a41276a2213200b290000370000200441b0026a41206a22052007290300370300200441b0026a41186a200e2903002218370300200441b0026a41106a20032903002219370300200441b0026a41086a20112903002221370300200420042903c00322243703b00220022024370000200241086a2021370000200241106a2019370000200241186a2018370000200241206a2005290300370000200241276a20132900003700002004200c3a00c003200441c0036a108204200141306a2201200d470d000b0b0240200f450d002006102a0b0240200428029c02450d00200428029802102a0b024020084105470d002010450d002012102a0b200041cd8fc60036020420004101360200200041086a41253602000c190b02402001200d460d00200441c0036a4101722102200441c0036a41276a210c200441c0036a41206a210b200441c0036a41186a2107200441c0036a41086a210e034020012d00002108200c200141286a290000370000200b200141216a2900003703002007200141196a290000370300200441c0036a41106a2211200141116a290000370300200e200141096a2900003703002004200141016a2900003703c00320084110460d01200441b0026a41276a2203200c290000370000200441b0026a41206a2213200b290300370300200441b0026a41186a20072903002218370300200441b0026a41106a20112903002219370300200441b0026a41086a200e2903002221370300200420042903c00322243703b00220022024370000200241086a2021370000200241106a2019370000200241186a2018370000200241206a2013290300370000200241276a2003290000370000200420083a00c003200441c0036a108204200141306a2201200d470d000b0b0240200f450d002006102a0b2004280298022101200429029c0221182000411c6a41003a0000200041146a2018370200200041106a20013602002000410c6a2017360200200041086a2016360200200020103602042000411d6a20042f0080023b0000200041003602002000411f6a20044182026a2d00003a00000c180b200e102a2000419c90c4003602040c160b200e102a2000419c90c4003602040c150b200e102a2000419c90c4003602040c140b200e102a2000419c90c4003602040c130b200e102a2000419c90c4003602040c120b200e102a2000419c90c4003602040c110b200e102a2000419c90c4003602040c100b200e102a2000419c90c4003602040c0f0b200f2d000d22024104460d05200241fb01710d05200e102a201121020c0b0b200f2d000d22024104460d02200241fb01710d02200e102a201121020c0a0b200f2d000d22024104460d00200241fb01710d00200e102a201121020c090b200e102a2000419c90c4003602040c0b0b200e102a2000419c90c4003602040c0a0b200e102a2000419c90c4003602040c090b200e102a2000419c90c4003602040c080b200e102a2000419c90c4003602040c070b02400240200241bbffc500460d0041bbffc5002002410b109c050d010b4126210c419c90c400210e200f2d000c41e000470d01200f2802080d0120112102200f2d000d4104460d040c010b0240200241dfffc500460d0041dfffc5002002410b109c050d030b4126210c419c90c400210e200f2d000c41e000470d00200f2802080d0020112102200f2d000d4104460d030b200e2108200c21010b200020083602040c040b0240200241ac81c600460d0041ac81c6002002410b109c050d030b024041021028220c450d00200c41003b0000200f2d000c41e000470d02200f2802084102470d020240200f280200220e200c460d0041002101034020014102460d01200c20016a2102200e20016a2108200141016a210120082d000020022d0000470d040c000b0b200f2d000d4104470d02200c102a201121020c010b0b410241011037000b200c102a0b412621012000419c90c4003602040b20004101360200200041086a200136020002402007450d00200b200741306c6a2111200b210703402007220041306a21070240024020002d00002201410e4b0d00024002400240024002400240024002400240024002400240024020010e0f0001020304050607080e090e0a0b0c000b200041086a280200450d0d200041046a280200102a0c0d0b0240200041086a280200450d00200041046a280200102a0b200041146a280200450d0c200041106a280200102a0c0c0b02402000410c6a2802002202450d00200041046a28020021012002410474210203400240200141046a280200450d002001280200102a0b200141106a2101200241706a22020d000b0b200041086a280200450d0b2000280204102a0c0b0b02402000410c6a2802002202450d00200041046a2802002101200241286c210203400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101200241586a22020d000b0b200041086a280200450d0a2000280204102a0c0a0b200041086a280200450d09200041046a280200102a0c090b200041086a280200450d08200041046a280200102a0c080b200041086a280200450d07200041046a280200102a0c070b02402000410c6a2802002201450d00200041046a280200220c20014104746a210e03400240200c2802082202450d00200c2802002101200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d002008280200102a200d28020021080b2008102a0b200141106a2101200241706a22020d000b0b200c41106a21010240200c41046a280200450d00200c280200102a0b2001210c2001200e470d000b0b200041086a280200450d062000280204102a0c060b02402000410c6a2802002202450d00200041046a2802002101200241146c210203400240200141046a280200450d002001280200102a0b200141146a21012002416c6a22020d000b0b200041086a280200450d052000280204102a0c050b02402000410c6a2802002201450d00200041046a280200220c2001411c6c6a210e03400240200c2802042201450d000240200c410c6a2802002202450d00200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d002008280200102a200d28020021080b2008102a0b200141106a2101200241706a22020d000b0b200c41086a280200450d00200c280204102a0b200c411c6a21010240200c41146a280200450d00200c280210102a0b2001210c2001200e470d000b0b200041086a280200450d042000280204102a0c040b02402000410c6a2802002201450d00200041046a280200220c200141186c6a210e03400240200c41046a280200450d00200c280200102a0b0240200c41146a2802002202450d00200c28020c2101200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d002008280200102a200d28020021080b2008102a0b200141106a2101200241706a22020d000b0b200c41186a21010240200c41106a280200450d00200c28020c102a0b2001210c2001200e470d000b0b200041086a280200450d032000280204102a0c030b02402000410c6a2802002201450d00200041046a280200220c2001411c6c6a210e03400240200c2802042201450d000240200c410c6a2802002202450d00200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d002008280200102a200d28020021080b2008102a0b200141106a2101200241706a22020d000b0b200c41086a280200450d00200c280204102a0b200c411c6a21010240200c41146a280200450d00200c280210102a0b2001210c2001200e470d000b0b200041086a280200450d022000280204102a0c020b0240200041046a2802002201450d00200041086a280200450d002001102a0b0240200041146a2802002201450d0002402000411c6a2802002202450d002002410c6c21020340024020012802002208450d00200141046a280200450d002008102a0b2001410c6a2101200241746a22020d000b0b200041186a280200450d002000280214102a0b200041246a280200220c450d0102402000412c6a2802002201450d00200c20014104746a210e0340200c220d41106a210c0240200d2802042201450d000240200d410c6a2802002202450d002002410c6c21020340024020012802002208450d00200141046a280200450d002008102a0b2001410c6a2101200241746a22020d000b0b200d41086a280200450d00200d280204102a0b200c200e470d000b0b200041286a280200450d012000280224102a0c010b0240200041086a280200450d00200041046a280200102a0b0240200041146a2802002201450d00200041186a280200450d002001102a0b200041246a280200450d00200041206a280200102a0b20072011470d000b0b200a450d00200b102a0b200441d0046a24000ba20301067f230041106b2202240020024100360208200242013703002000200210a001200041046a200210a001200041086a200210a00120002d0018210302400240024002400240200228020420022802082204460d00200228020021050c010b200441016a22052004490d03200441017422062005200620054b1b22064100480d030240024020040d002006102821050c010b200228020020042006102c21050b2005450d0120022006360204200220053602000b2002200441016a360208200520046a20033a0000200028020c2106200041146a2802002204200210b4010240024020022802042203200228020822056b2004490d00200228020021000c010b200520046a22002005490d03200341017422072000200720004b1b22074100480d030240024020030d002007102821000c010b200228020020032007102c21000b2000450d022002200736020420022000360200200721030b200020056a20062004109a051a200128020020012802042000200520046a100702402003450d002000102a0b200241106a24000f0b200641011037000b200741011037000b1031000bd60801037f024002400240024002400240024002400240410110282202450d00200220002d00003a0000200241014102102c2202450d01200220002d00013a0001200241024104102c2202450d02200220002d00023a0002200220002d00033a0003200241044108102c2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102c2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102c2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f2002412041c000102c2202450d06200220002d00203a0020200220002d00213a0021200220002d00223a0022200220002d00233a0023200220002d00243a0024200220002d00253a0025200220002d00263a0026200220002d00273a0027200220002d00283a0028200220002d00293a0029200220002d002a3a002a200220002d002b3a002b200220002d002c3a002c200220002d002d3a002d200220002d002e3a002e200220002d002f3a002f200220002d00303a0030200220002d00313a0031200220002d00323a0032200220002d00333a0033200220002d00343a0034200220002d00353a0035200220002d00363a0036200220002d00373a0037200220002d00383a0038200220002d00393a0039200220002d003a3a003a200220002d003b3a003b200220002d003c3a003c200220002d003d3a003d200220002d003e3a003e200220002d003f3a003f024002402001280200220041046a2802002203200041086a28020022016b41c000490d00200028020021030c010b200141c0006a22042001490d09200341017422012004200120044b1b22014100480d090240024020030d002001102821030c010b200028020020032001102c21030b2003450d0820002003360200200041046a2001360200200041086a28020021010b200041086a200141c0006a360200200320016a220041386a200241386a290000370000200041306a200241306a290000370000200041286a200241286a290000370000200041206a200241206a290000370000200041186a200241186a290000370000200041106a200241106a290000370000200041086a200241086a290000370000200020022900003700002002102a0f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000b41c00041011037000b200141011037000b1031000bc32205017f057e097f047e0f7f230041c0056b22032400200241206a2903002104200241186a2903002105200241106a2903002106200241c8006a29030021072002290308210820022802002109200341086a41186a220a200241c0006a220b290300370300200341086a41106a220c200241386a220d290300370300200341086a41086a220e200241306a220f2903003703002003200241286a2202290300370308200341286a41186a2210200b290300370300200341286a41106a2211200d290300370300200341286a41086a220d200f290300370300200320022903003703282001280200210b20034180026a41186a2202200a29030037030020034180026a41106a220f200c29030037030020034180026a41086a220c200e2903003703002003200329030837038002024002400240024041381028220a450d00200a4200370308200a4200370300200a2009360210200a2003290328370214200a411c6a200d290300370200200a41246a2011290300370200200a412c6a2010290300370200200341d0016a41086a200c290300370300200341d0016a41106a200f290300370300200341d0016a41186a200229030037030020032003290380023703d001024002400240200b2802082202200b41046a280200470d00200241016a220c2002490d012002410174220d200c200d200c4b1b220cad42d0007e2212422088a70d012012a7220d4100480d010240024020020d00200d102821020c010b200b280200200241d0006c200d102c21020b2002450d02200b2002360200200b41046a200c360200200b28020821020b200b280200200241d0006c6a2202420037031020022004370308200220053703002002200a360220200220032903d00137022c200241186a4200370300200241246a428180808010370200200241346a200341d0016a41086a220a2903003702002002413c6a200341d0016a41106a220e290300370200200241c4006a200341d0016a41186a2202290300370200200b200b28020841016a3602082001280204210f20034190016a41186a200341286a41186a29030037030020034190016a41106a200341286a41106a29030037030020034190016a41086a200341286a41086a2903003703002003200329032837039001024002400240200f280200220c41f8b9c000460d00200f280204210d0c010b4100210d20034180026a410041e0021099051a200341f8016a220b4100360200200341f0016a2201420037030020024200370300200e4200370300200a4200370300200342003703d0014194031028220c450d01200c41003b0106200c4100360200200c41086a20034180026a41e002109a051a200c4190036a200b280200360200200c4188036a2001290300370200200c4180036a200341e8016a290300370200200c41f8026a200341e0016a290300370200200c41f0026a200341d0016a41086a290300370200200c20032903d0013702e802200f4100360204200f200c3602000b02400340200c41086a210a200c41066a2110200c2f0106220e41057421024100210b0240024003402002450d0120034190016a200a4120109c052201450d02200241606a2102200b41016a210b200a41206a210a2001417f4a0d000b200b417f6a210e0b200d450d02200d417f6a210d200c200e4102746a4194036a280200210c0c010b0b200c200b4102746a41e8026a20093602000c060b200341c8006a41186a20034190016a41186a22022903002212370300200341c8006a41106a20034190016a41106a220a2903002213370300200341c8006a41086a20034190016a41086a220b290300221437030020032003290390012215370348200f200f28020841016a36020820022012370300200a2013370300200b20143703002003201537039001024002400240024020102f0100220d410b490d0020034180026a410041e0021099051a200341f8016a22024100360200200341f0016a220a4200370300200341d0016a41186a4200370300200341d0016a41106a4200370300200341d0016a41086a4200370300200342003703d00141940310282211450d03201141003b010620114100360200201141086a20034180026a41e002109a05210b20114190036a200228020036020020114188036a200a29030037020020114180036a200341d0016a41186a290300370200201141f8026a200341d0016a41106a290300370200201141f0026a200341d0016a41086a290300370200201120032903d0013702e8022003200c2f00c8013b01cc012003200c41ca016a2d00003a00ce01200c41cb016a2800002116200c41cf016a2800002117200c41d3016a2800002118200c41d7016a28000021192003200c41e0016a2900003700bd012003200c2900db013703b801200c28028003211a200b200c41e8016a200c2f010641796a2202410574109a05210b201141e8026a200c4184036a2002410274109a052101200c41063b0106201120023b0106200320032f01cc013b01b401200320032d00ce013a00b601200320032903b8013703d001200320032900bd013700d501200e4107490d01201141066a2110200b200e417a6a220d4105746a200b200e41796a220a4105746a220b200241ffff0371200a6b410574109b051a200b41186a20034190016a41186a290300370000200b41106a20034190016a41106a290300370000200b41086a20034190016a41086a290300370000200b2003290390013700002001200d4102746a210b2001200a4102746a21020c020b200c41086a2201200e41016a220f4105746a2001200e4105746a2201200d200e6b410574109b051a200141186a2002290300370000200141106a200a290300370000200141086a200b2903003700002001200329039001370000200c41e8026a2202200f4102746a2002200e4102746a2202200c2f0106200e6b410274109b051a20022009360200200c200c2f010641016a3b01060c080b200c41086a2202200e41016a220a4105746a2002200e4105746a220220102f0100200e6b410574109b051a200241186a20034190016a41186a290300370000200241106a20034190016a41106a290300370000200241086a20034190016a41086a2903003700002002200329039001370000200c41e8026a220b200e4102746a2102200b200a4102746a210b200e210a0b200b200220102f0100200a6b410274109b051a20022009360200201020102f010041016a3b0100200341b0016a41026a221b20032d00b60122023a0000200341fc006a41026a221c20023a0000200320032900d50137008501200320032903d00137038001200320032f01b40122023b01b001200320032900850137006d2003200329038001370368200320023b017c200c280200220d450d05200c2f0104211020034180026a410272211d0340201b201c2d00003a0000200320032f017c3b01b00120032003290368370390012003200329006d37009501201041ffff0371210c02400240024002400240200d2f01062202410b490d00201d410041be031099051a41c40310282201450d0320014100360200200141046a20034180026a41c003109a051a2003200d2f00c8013b01cc012003200d41ca016a2d00003a00ce012003200d41db016a2900003703b8012003200d41e0016a2900003700bd01200d41cb016a280000211e200d41cf016a280000211f200d41d3016a2800002120200d41d7016a2800002121200d4180036a2802002122200141086a200d41e8016a200d2f0106220a41796a2202410574109a052123200141e8026a200d4184036a2002410274109a05212420014194036a200d41b0036a200a417a6a220e410274109a052109200d41063b0106200120023b01060240200e450d00410021022009210a0340200a280200220b20023b0104200b2001360200200a41046a210a200e200241016a2202470d000b0b200320032d00ce0122023a00b601200320032f01cc01220a3b01b401200320032903b8013703d001200320032900bd013700d50120034180016a41026a220e20023a00002003200a3b018001200320032903d00137038002200320032900d50137008502201041ffff0371220a4107490d012023200c417a6a220b4105746a2023200c41796a22024105746a220a20012f010620026b410574109b051a200a41186a200329009501370000200a201936000f200a201836000b200a2017360007200a2016360003200a41026a201b2d00003a0000200a20032f01b0013b0000200a2003290390013700132024200b410274220a6a202420024102746a221020012f0106221620026b410274109b051a2010201a3602002001201641016a22103b0106200c410274221620096a416c6a2009200a6a220a201041ffff0371220c200b6b410274109b051a200a2011360200200c200b490d02200120166a41fc026a210a0340200a280200220b200241016a22023b0104200b2001360200200a41046a210a2002200c490d000c030b0b200d41086a220a200c41016a220b4105746a200a200c4105746a220a2002200c6b410574109b051a200a41186a200329009501370000200a201936000f200a201836000b200a2017360007200a2016360003200a41026a200341b0016a41026a2d00003a0000200a20032f01b0013b0000200a200329039001370013200d41e8026a2202200b410274220a6a2002200c41027422016a2202200d2f0106220e200c6b410274109b051a2002201a360200200d200e41016a22023b01062001200d4194036a220c6a41086a200c200a6a220a200241ffff03712201200b6b410274109b051a200a2011360200201041ffff037120014f0d0b200d200b417f6a22024102746a4198036a210a0340200a280200220b200241016a22023b0104200b200d360200200a41046a210a20022001490d000c0c0b0b200d41086a2202200c41016a22104105746a2002200c4105746a2202200d2f0106200c6b410574109b051a200241186a2003290095013700002002201936000f2002201836000b2002201736000720022016360003200241026a201b2d00003a0000200220032f01b0013b00002002200329039001370013200d41e8026a220b201041027422096a200b200c41027422026a220b200d2f01062216200c6b410274109b051a200b201a360200200d201641016a220b3b01062002200d4194036a22166a41086a201620096a2209200b41ffff0371220b20106b410274109b051a20092011360200200a200b4f0d00200d20026a4198036a210203402002280200220a200c41016a220c3b0104200a200d360200200241046a2102200b200c470d000b0b201c200e2d00003a0000200320032f0180013b017c2003200329038002370368200320032900850237006d200d28020022020d01201e21162021211920202118201f2117200121112022211a0c080b41c40341041037000b200d2f01042110201e21162021211920202118201f21172002210d2022211a200121110c000b0b41940341041037000b41940341041037000b1031000b200d41081037000b413841081037000b20034180026a410272410041be031099051a41c40310282202450d0120024100360200200241046a20034180026a41c003109a051a2002200f280200220a36029403200f2002360200200f200f28020441016a360204200a41003b0104200a2002360200200220022f0106220b4105746a220a41086a20032f017c3b0000200a410a6a200341fc006a41026a2d00003a0000200a41176a2019360000200a41136a2018360000200a410f6a2017360000200a410b6a2016360000200a411b6a2003290368370000200a41206a200329006d37000020024194036a200b41016a220a4102746a20113602002002200b4102746a41e8026a201a3602002002200a3b01062011200a3b0104201120023602000b20002005370310200020083703002000200329032837032020002007370340200041186a200437030020002006370308200041286a200341306a290300370300200041306a200341386a290300370300200041386a200341286a41186a290300370300200341c0056a24000f0b41c40341041037000b0a0041c8c2c2001032000b5101027e024002402003450d002002280200450d010b41b698c40041f4031050000b2001280218220342002003290308220420023502047d2205200520045622021b37030820004105410420021b3602000bee0201047f024002400240024002402002417f4c0d000240024020020d00410121060c010b200210282206450d020b200620012002109a0521062004417f4c0d000240024020040d0041012101410021070c010b20042107200410282201450d030b200120032004109a052103024020002802082201200041046a280200470d00200141016a22082001490d05200141017422092008200920084b1b220841ffffff3f712008470d05200841057422094100480d050240024020010d002009102821010c010b200028020020014105742009102c21010b2001450d0420002001360200200041046a2008360200200028020821010b200028020020014105746a220141003602182001200336020c2001200236020820012002360204200120063602002001411c6a2005360200200141146a2004360200200141106a20073602002000200028020841016a3602080f0b1036000b200241011037000b200441011037000b200941041037000b1031000bf90e05047f027e027f017e027f230041c00c6b2204240002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320022802042105200241246a2802002106200241346a280200210302400240200241146a2802002207450d004105210220012802002802182802402802bc012003490d010b200441286a4200370300200441206a4200370300200441186a420037030020012802182202420020022903082208427f20012802102903482209420586200942ffffffffffffffff07832009521b7d22092009200856220a1b3703082004420037031041052102200a0d000240024020012802142802082005200441106a4120101741026a220a41024b0d00200a0e03020001020b41a0fac5001032000b0240024020070d00410121034100210b0c010b2004200128021029034842002003ad220c4200109f052001280218220a4200200a2903082209427f200429030020042903084200521b7d22082008200956220a1b370308200a0d012003417f4c0d060240024020030d004101210b02402001280214280208200641014100101741026a220341024b0d0020030e03040002040b41a0fac5001032000b024002402003102e220b450d00024020012802142802082006200b2003101741026a220341024b0d0020030e03020003020b41a0fac5001032000b200341011037000b200b102a0c020b200c422086200c842109200b4521030b20012802002101200441306a41186a220a200441106a41186a290300370300200441306a41106a2205200441106a41106a290300370300200441306a41086a2206200441106a41086a2903003703002004200429031037033020012802182107024020030d0020072802402802bc012009422088a74f0d002009a7450d01200b102a0c010b200441d0006a41186a200a290300370300200441d0006a41106a2005290300370300200441d0006a41086a20062903003703002004200429033037035020072802180d062007417f360218200441a8016a200741e8006a290000370300200441a0016a200741e0006a29000037030020044198016a200741d8006a2900003703002004200729005037039001024002402007411c6a220d280200220a41f8b9c000460d00200741206a28020021060c010b41002106200441e0096a410041e0021099051a200441c0016a410041a0081099051a41880b1028220a450d08200a41003b0106200a4100360200200a41086a200441e0096a41e002109a051a200a41e8026a200441c0016a41a008109a051a200741206a41003602002007200a36021c0b024002400340200a2f0106220e4105742105410021024100210302400240034020052002460d0120044190016a200a20026a41086a4120109c052201450d02200241206a2102200341016a21032001417f4a0d000b2003417f6a210e0b2006450d022006417f6a2106200a200e4102746a41880b6a280200210a0c010b0b200741246a2101410121020c010b200441f0006a41186a20044190016a41186a290300370300200441f0006a41106a20044190016a41106a290300370300200441f0006a41086a20044190016a41086a2903003703002004200429039001370370200741246a210141002106200e2103410021020b0240024020020d00200441fc096a200441f0006a41086a290300370200200441840a6a200441f0006a41106a2903003702002004418c0a6a200441f0006a41186a290300370200200420013602f009200420033602ec092004200d3602e8092004200a3602e409200420063602e009200420042903703702f409200441e0016a20042903b001370300200441e8016a200441b0016a41086a290300370300200441f4016a4200370200200442003703d801200442003703c001200441f8b9c0003602f001200441003a00fc01200441fd016a20042900900137000020044185026a20044190016a41086a2900003700002004418d026a20044190016a41106a29000037000020044195026a20044190016a41186a290000370000200441003a009d02200441e0096a200441c0016a10b70121020c010b200441d8016a4200370300200441d4016a41f8b9c000360200200441003602e001200441003602d001200442003703c801200441f8b9c0003602c401200441003602c001200a200341e0006c6a41e8026a2102200441c0016a1095010b200441c0016a41186a200441d0006a41186a290300370300200441c0016a41106a200441d0006a41106a290300370300200441c0016a41086a200441d0006a41086a290300370300200420042903503703c00120042009370294012004200b36029001200441e0096a200241306a200441c0016a20044190016a10bd01024020042802e009450d0020042802e4092202450d00200441e8096a280200450d002002102a0b2007200728021841016a360218410421020b20002002360200200441c00c6a24000f0b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b1036000b41a8b8c0004110200441c0016a41d0b8c0001038000b41880b41081037000b900302017f027e230041c0006b22042400024002402003450d0020022802000d0020022802042103200441186a4200370300200441106a4200370300200441086a420037030020012802182202420020022903082205427f20012802102903482206420586200642ffffffffffffffff07832006521b7d2206200620055622021b3703082004420037030002400240024020020d00024002402001280214280208200320044120101741026a220241024b0d0020020e03020001020b41a0fac5001032000b200441206a2001280200280218220241186a200241d0006a2002410c6a4100200228020c1b200410a7012004280220450d01200441306a41086a2203200441206a41086a28020036020020042004290320370330200141046a21020240200141086a280200450d002002280200102a0b20022004290330370200200241086a2003280200360200410021010c020b200041053602000c030b2001410c6a4100360200410121010b20004100360200200020013602040c010b41b698c40041f4031050000b200441c0006a24000bae0f06017f017e057f027e037f027e230041d0016b220424000240024002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042103200241286a2903002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200441286a20012802102903484200200241146a280200220aad4200109f052001280218220242002002290308220b427f200429032820042903304200521b7d220c200c200b5622021b370308024020020d00200a417f4c0d0802400240024002400240200a0d004101210d02402001280214280208200341014100101741026a220241024b0d00200141146a210e20020e03060002060b41a0fac5001032000b0240200a102e220d450d00024020012802142802082003200d200a101741026a220241024b0d00200141146a210e20020e03030002030b41a0fac5001032000b200a41011037000b41002102200441003a00980102400340200a2002460d01200441f8006a20026a200d20026a2d00003a00002004200241016a22033a0098012003210220034120470d000b200441a0016a41186a2202200441f8006a41186a290300370300200441a0016a41106a2203200441f8006a41106a290300370300200441a0016a41086a220f200441f8006a41086a290300370300200420042903783703a0010240200a450d00200d102a0b200441386a41086a200f290300370300200441386a41106a2003290300370300200441386a41186a2002290300370300200420042903a001370338200441186a200128021029034842002007ad4200109f052001280218220242002002290308220b427f200429031820042903204200521b7d220c200c200b5622021b37030820020d042007417f4c0d0c20070d03200e280200280208200641014100101741026a220241024b0d0220020e03040204040b0240200241ff0171450d00200441003a0098010b200a450d030b200d102a0c020b41a0fac5001032000b0240024002402007102e2202450d000240200e280200280208200620022007101741026a220341024b0d0020030e03030002030b41a0fac5001032000b200741011037000b2007410f4d0d00200241086a2900002110200229000021112002102a200441086a200128021029034842002009ad4200109f052001280218220242002002290308220b427f200429030820042903104200521b7d220c200c200b5622021b37030820020d01200141046a210a0240024020092001410c6a220d28020022034b0d00200921020c010b02400240200141086a280200220220036b200920036b2206490d00200a2802002107200321020c010b200320066a22072003490d0d2002410174220e2007200e20074b1b220e4100480d0d0240024020020d00200e102821070c010b200a2802002002200e102c21070b2007450d0c20012007360204200141086a200e3602002001410c6a28020021020b200720026a210e0240024020064102490d00200e410020092003417f7322036a22061099051a2007200920026a20036a6a210e200620026a21020c010b2006450d010b200e41003a0000200241016a21020b200d2002360200024002402001280214280208200820012802042002101741026a220241024b0d0020020e03030001030b41a0fac5001032000b2001410c6a2202280200210720024100360200200141086a28020021032001280204210d2001420137020420012802182202290308220c210b024002402005500d002005210b200c2005540d010b2002200c200b7d3703082002290310210c200441a0016a41186a200241186a2903003703002004200b3703a8012004200b3703a0012004200c3703b001200128020041186a2802002106200441f8006a41186a200441386a41186a290300370300200441f8006a41106a200441386a41106a290300370300200441f8006a41086a200441386a41086a29030037030020042004290338370378200420073602c801200420033602c4012004200d3602c001200441d8006a2006200441f8006a20112010200441a0016a200441c0016a10c101410121090240024020042802584101460d00200441d8006a410472210d200441d8006a41106a2d00002107200441e4006a2802002106200441e0006a2802002103410021090c010b200441e4006a210d200441ec006a2802002106200441d8006a41106a2802002103410021070b200d280200210d200220042903a80120022903087c370308200141086a2802002102024020090d0002402002450d00200a280200102a0b200a200d3602000c0e0b2002450d00200a280200102a0b200a200d3602004180022107410021060c0c0b2002102a0b200041053602000c0b0b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b1036000b200e41011037000b1031000b2001410c6a2006360200200141086a200336020020004100360200200020073602040b200441d0016a24000bc71006017f017e057f027e037f027e230041e0016b2204240002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042103200241286a2903002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200441206a20012802102903484200200241146a280200220aad4200109f052001280218220242002002290308220b427f200429032020042903284200521b7d220c200c200b5622021b3703080240024020020d00200a417f4c0d0902400240024002400240200a0d004101210d02402001280214280208200341014100101741026a220241024b0d00200141146a210e20020e03060002060b41a0fac5001032000b0240200a102e220d450d00024020012802142802082003200d200a101741026a220241024b0d00200141146a210e20020e03030002030b41a0fac5001032000b200a41011037000b41002102200441003a00c80102400340200a2002460d01200441a8016a20026a200d20026a2d00003a00002004200241016a22033a00c8012003210220034120470d000b20044188016a41186a2202200441a8016a41186a29030037030020044188016a41106a2203200441a8016a41106a29030037030020044188016a41086a220f200441a8016a41086a290300370300200420042903a801370388010240200a450d00200d102a0b200441306a41086a200f290300370300200441306a41106a2003290300370300200441306a41186a20022903003703002004200429038801370330200441106a200128021029034842002007ad4200109f052001280218220242002002290308220b427f200429031020042903184200521b7d220c200c200b5622021b37030820020d042007417f4c0d0d20070d03200e280200280208200641014100101741026a220241024b0d0220020e03040204040b0240200241ff0171450d00200441003a00c8010b200a450d030b200d102a0c020b41a0fac5001032000b0240024002402007102e2202450d000240200e280200280208200620022007101741026a220341024b0d0020030e03030002030b41a0fac5001032000b200741011037000b2007410f4d0d00200241086a2900002110200229000021112002102a2004200128021029034842002009ad4200109f052001280218220242002002290308220b427f200429030020042903084200521b7d220c200c200b5622021b37030820020d01200141046a21070240024020092001410c6a220a28020022034b0d00200921020c010b02400240200141086a280200220220036b200920036b2206490d002007280200210d200321020c010b200320066a220d2003490d0e2002410174220e200d200e200d4b1b220e4100480d0e0240024020020d00200e1028210d0c010b20072802002002200e102c210d0b200d450d0d2001200d360204200141086a200e3602002001410c6a28020021020b200d20026a210e0240024020064102490d00200e410020092003417f7322036a22061099051a200d200920026a20036a6a210e200620026a21020c010b2006450d010b200e41003a0000200241016a21020b200a2002360200024002402001280214280208200820012802042002101741026a220241024b0d0020020e03030001030b41a0fac5001032000b2001410c6a2202280200210d20024100360200200141086a28020021032001280204210a2001420137020420012802182202290308220c210b0240024002402005500d002005210b200c2005540d010b2002200c200b7d3703082002290310210c20044188016a41186a200241186a2903003703002004200b370390012004200b370388012004200c37039801200128020041186a28020021062004200d360258200420033602542004200a360250200441a8016a20062011201020044188016a200441306a200441d0006a10b5014101210d0240024020042802a8014101460d00200441d0006a41086a200441a8016a41186a290300370300200441d0006a41106a200441c8016a2802003602002004200441a8016a41106a290300370350200441d8016a2d00002106200441d0016a2802002109200441cc016a2802002108200441b4016a280200210e200441a8016a41086a28020021034100210d20042802ac01210a0c010b200441bc016a280200210e200441b8016a2802002103200441b4016a280200210a410021060b200220042903900120022903087c370308200441f0006a41086a2202200441d0006a41086a290300370300200441f0006a41106a220f200441d0006a41106a280200360200200420042903503703700240200d0d00200441bc016a2002290300370200200441c4016a200f2802003602002004200e3602b001200420033602ac012004200a3602a801200420042903703702b4010240200141086a280200450d002007280200102a0b200120083602042001410c6a4100360200200141086a2009360200200641ff017122020d02200441a8016a2007108f010c020b200141086a280200450d002007280200102a0b2001200a3602042001410c6a4100360200200141086a200336020041800221020b20004100360200200020023602040c020b2002102a0b200041053602000b200441e0016a24000f0b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b1036000b200e41011037000b1031000b9d0503027f037e057f230041206b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200441106a20012802102903184200200241146a2802002203ad22064200109f0520012802182202420020022903082207427f200429031020042903184200521b7d2208200820075622021b370308024020020d0020042001280210290348420020064200109f0520012802182202420020022903082207427f200429030020042903084200521b7d2208200820075622021b37030820020d000240024020032001410c6a2209280200220a4b0d00200321020c010b02400240200141086a2802002202200a6b2003200a6b220b490d002001280204210c200a21020c010b200a200b6a220c200a490d062002410174220d200c200d200c4b1b220d4100480d060240024020020d00200d1028210c0c010b20012802042002200d102c210c0b200c450d052001200c360204200141086a200d3602002001410c6a28020021020b200c20026a210d02400240200b4102490d00200d41002003200a417f73220a6a220b1099051a200c200320026a200a6a6a210d200b20026a21020c010b200b450d010b200d41003a0000200241016a21020b20092002360200024002402001280214280208200520012802042002101741026a220241024b0d0020020e03020001020b41a0fac5001032000b2001410c6a2202280200210320024100360200200141086a280200210220012802042105200142013702040240200128021c220a450d00200141206a280200450d00200a102a0b2001200536021c200141246a2003360200200141206a20023602000b20004105360200200441206a24000f0b41b698c40041f4031050000b41b698c40041f4031050000b200d41011037000b1031000b23002001410c6a4100360200200128020041206a200141046a108f01200041043602000b27002001410c6a4100360200200128020028021841d0006a200141046a108f01200041043602000bd50102027f027e410021042001410c6a41003602002001280218220541186a2903002106200529031021070240024002400240200141086a28020022054110490d00200128020421050c010b200541017422044110200441104b1b22044100480d020240024020050d002004102821050c010b200128020420052004102c21050b2005450d0120012005360204200141086a20043602002001410c6a28020021040b2001410c6a200441106a360200200520046a2201200637000820012007370000200041043602000f0b200441011037000b1031000bc20103017f017e017f410021042001410c6a4100360200200128021829030821050240024002400240200141086a28020022064108490d00200128020421060c010b200641017422044108200441084b1b22044100480d020240024020060d002004102821060c010b200128020420062004102c21060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441086a360200200620046a2005370000200041043602000f0b200441011037000b1031000bb804020b7f027e230041206b220424002001410c6a41003602000240024002402001280200280218220528021841016a220641004c0d00200541d0006a2107200520063602182005411c6a2108200541206a28020021090240024003402008280200220a41086a210b200a2f0106220c41057421084100210d0240024003402008450d012007200b4120109c05220e450d02200841606a2108200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a210c0b2009450d022009417f6a2109200a200c4102746a41880b6a21080c010b0b200a200d41e0006c6a220841c5036a310000200841e8026a290300220f200f50220b1ba7450d004200200841f8026a290300200b1b210f4200200841f0026a290300200b1b21100c010b200441086a200541286a28020020072005412c6a28020028021c110500200441106a290300210f20052802182106200429030821100b20052006417f6a36021802400240200141086a280200220b2001410c6a28020022086b4110490d002001280204210b0c010b200841106a220d2008490d03200b4101742208200d2008200d4b1b22084100480d0302400240200b0d0020081028210b0c010b2001280204200b2008102c210b0b200b450d022001200b360204200141086a20083602002001410c6a28020021080b2001410c6a200841106a360200200b20086a2208200f3700082008201037000020004104360200200441206a24000f0b41b8b8c0004118200441186a41e0b8c0001038000b200841011037000b1031000bd50102027f027e410021042001410c6a41003602002001280200220541086a2903002106200529030021070240024002400240200141086a28020022054110490d00200128020421050c010b200541017422044110200441104b1b22044100480d020240024020050d002004102821050c010b200128020420052004102c21050b2005450d0120012005360204200141086a20043602002001410c6a28020021040b2001410c6a200441106a360200200520046a2201200637000820012007370000200041043602000f0b200441011037000b1031000b860302047f027e230041c0006b220424000240024002402003450d0020022802000d0020034101460d0120022802100d01410521050240200241146a28020022032001280210220628026c4b0d0020022802042107200441086a200629034842002003ad4200109f0520012802182202420020022903082208427f200429030820042903104200521b7d2209200920085622021b37030820020d002003417f4c0d0302400240024020030d004101210202402001280214280208200741014100101741026a220641024b0d0020060e03040002040b41a0fac5001032000b02402003102e2202450d0002402001280214280208200720022003101741026a220641024b0d0020060e03030002030b41a0fac5001032000b200341011037000b2001410c6a4100360200200441186a2002200310a803410421052004200141046a36023c200441186a2004413c6a10c8012003450d010b2002102a0b20002005360200200441c0006a24000f0b41b698c40041f4031050000b41b698c40041f4031050000b1036000bc20103017f017e017f410021042001410c6a4100360200200128020029031021050240024002400240200141086a28020022064108490d00200128020421060c010b200641017422044108200441084b1b22044100480d020240024020060d002004102821060c010b200128020420062004102c21060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441086a360200200620046a2005370000200041043602000f0b200441011037000b1031000bdc0102027f027e410021042001410c6a4100360200200128020028021828024022054180016a2903002106200529037821070240024002400240200141086a28020022054110490d00200128020421050c010b200541017422044110200441104b1b22044100480d020240024020050d002004102821050c010b200128020420052004102c21050b2005450d0120012005360204200141086a20043602002001410c6a28020021040b2001410c6a200441106a360200200520046a2201200637000820012007370000200041043602000f0b200441011037000b1031000bb20803027f047e027f230041e0046b2204240002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200441286a20012802102903484200200241146a2802002202ad4200109f0520012802182203420020032903082206427f200429032820042903304200521b7d2207200720065622031b3703080240024020030d002002417f4c0d0402400240024020020d004101210302402001280214280208200541014100101741026a220541024b0d0020050e03040002040b41a0fac5001032000b02402002102e2203450d0002402001280214280208200520032002101741026a220541024b0d0020050e03030002030b41a0fac5001032000b200241011037000b2004200236023c20042003360238200441d0036a200441386a108101024020042802d00322054113460d00200441c8026a200441d0036a410472418401109a051a02402002450d002003102a0b200441c0016a200441c8026a418401109a051a20042005360238200441386a410472200441c0016a418401109a051a200441003602d803200442013703d003200441386a200441d0036a10eb0120042802d8032103024020042802d403450d0020042802d003102a0b200128021822022903102206200241186a2903002207844200510d07200441186a2003ad42004280c8afa0254200109f05200441086a200429031822084280a094a58d1d7c2209200441186a41086a2903002009200854ad7c2006200710a00520024200200229030822062004290308427f200441086a41086a290300501b7d220720072006561b37030820072006580d03200441386a106a0c020b2002450d010b2003102a0b410521020c070b20012802002102200441c8026a200441386a418801109a051a200441c0016a41086a2002280218220241d8006a290000370300200441d0016a2203200241e0006a290000370300200441d8016a2205200241e8006a290000370300200420022900503703c001200441d7036a200441c8026a418801109a051a02402002413c6a2802002201200241386a280200470d00200141016a220a2001490d062001410174220b200a200b200a4b1b220aad42b0017e2206422088a70d062006a7220b4100480d060240024020010d00200b102821010c010b2002280234200141b0016c200b102c21010b2001450d0520022001360234200241386a200a360200200228023c21010b2002280234200141b0016c6a220141013a0000200120042903c001370001200141096a200441c8016a290300370000200141116a2003290300370000200141196a2005290300370000200141216a200441d0036a418f01109a051a2002200228023c41016a36023c410421020c060b41b698c40041f4031050000b41b698c40041f4031050000b1036000b419cb7c0001032000b200b41081037000b1031000b20002002360200200441e0046a24000b8c1705087f027e037f027e047f230041a0026b22042400024002400240024002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620034107460d0720022802700d0720022802042103200241246a2802002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200241f4006a280200210a200441206a20012802102903484200200241146a280200220bad4200109f052001280218220242002002290308220c427f200429032020042903284200521b7d220d200d200c5622021b3703080240024020020d00200b417f4c0d0a024002400240200b0d004101210e02402001280214280208200341014100101741026a220241024b0d00200141146a210f20020e03040002040b41a0fac5001032000b0240200b102e220e450d00024020012802142802082003200e200b101741026a220241024b0d00200141146a210f20020e03030002030b41a0fac5001032000b200b41011037000b41002102200441003a00f00102400340200b2002460d01200441d0016a20026a200e20026a2d00003a00002004200241016a22033a00f0012003210220034120470d000b20044180026a41086a2202200441d0016a41086a29030037030020044180026a41106a2203200441d0016a41106a29030037030020044180026a41186a2210200441d0016a41186a290300370300200420042903d001370380020240200b450d00200e102a0b200441306a41086a2002290300370300200441306a41106a2003290300370300200441306a41186a20102903003703002004200429038002370330200441106a200128021029034842002006ad4200109f052001280218220242002002290308220c427f200429031020042903184200521b7d220d200d200c5622021b3703082002450d030c100b0240200241ff0171450d00200441003a00f0010b200b450d010b200e102a0b200441f0006a41186a20044180026a41186a290300370300200441f0006a41106a20044180026a41106a290300370300200441f0006a41086a20044180026a41086a2903003703002004200429038002370370410521020c0e0b2006417f4c0d080240024002400240024020060d004101210b0240200f280200280208200541014100101741026a220241024b0d0020020e03120002120b41a0fac5001032000b02402006102e220b450d000240200f2802002802082005200b2006101741026a220241024b0d0020020e03030002030b41a0fac5001032000b200641011037000b41002102200441003a00f0010240034020062002460d01200441d0016a20026a200b20026a2d00003a00002004200241016a22033a00f0012003210220034120470d000b20044180026a41086a2202200441d0016a41086a29030037030020044180026a41106a2203200441d0016a41106a29030037030020044180026a41186a220e200441d0016a41186a290300370300200420042903d0013703800202402006450d00200b102a0b200441d0006a41086a2002290300370300200441d0006a41106a2003290300370300200441d0006a41186a200e29030037030020042004290380023703502004200128021029034842002008ad4200109f052001280218220242002002290308220c427f200429030020042903084200521b7d220d200d200c5622031b3703084105210220030d112008417f4c0d0c20080d03200f280200280208200741014100101741026a220341024b0d0220030e03110211110b0240200241ff0171450d00200441003a00f0010b2006450d0f0b200b102a410521020c0f0b41a0fac5001032000b024002400240024002402008102e2203450d000240200f280200280208200720032008101741026a220b41024b0d00200b0e03030002030b41a0fac5001032000b200841011037000b2008410f4d0d00200341086a2900002111200329000021122003102a024002400240200a0d00410121064100210b4100210e0c010b20044180026a41186a210320044180026a41106a210520044180026a41086a210841002110410021024100210b4100210e4101210603402003420037030020054200370300200842003703002001280218220742002007290308220d427f2001280210290348220c420586200c42ffffffffffffffff0783200c521b7d220c200c200d5622071b370308200442003703800220070d1102400240200f280200280208200920026a221320044180026a4120101741026a220741024b0d0020070e03130001130b41a0fac5001032000b200441d0016a41186a22142003290300370300200441d0016a41106a22152005290300370300200441d0016a41086a2216200829030037030020042004290380023703d0010240200b200e470d002010200b41016a220e2010200e4b1b220e41ffffff3f71200e470d03200e41057422074100480d0302400240200b0d002007102821060c010b200620022007102c21060b2006450d100b200620026a220720042903d001370000200741186a2014290300370000200741106a2015290300370000200741086a2016290300370000201341206a2013490d11201041026a2110200241206a2102200a200b41016a220b470d000b0b2001280200280218210320044190016a41086a200441306a41086a29030037030020044190016a41106a2201200441306a41106a29030037030020044190016a41186a2205200441306a41186a290300370300200441b0016a41086a200341d8006a290000370300200441b0016a41106a2208200341e0006a290000370300200441b0016a41186a2207200341e8006a2900003703002004200429033037039001200420032900503703b00120044180026a41186a220a200441d0006a41186a29030037030020044180026a41106a2209200441d0006a41106a29030037030020044180026a41086a200441d0006a41086a29030037030020042004290350370380022003413c6a2802002202200341386a280200470d03200241016a220f2002490d0020024101742210200f2010200f4b1b220fad42b0017e220c422088a70d00200ca7221041004e0d020b1031000b2003102a0c0f0b0240024020020d002010102821020c010b2003280234200241b0016c2010102c21020b2002450d0b20032002360234200341386a200f360200200328023c21020b2003280234200241b0016c6a220241023a0000200220042903b0013700012002200429039001370021200241096a200441b0016a41086a290300370000200241116a2008290300370000200241196a2007290300370000200241296a20044190016a41086a290300370000200241316a2001290300370000200241396a2005290300370000200220063600642002200e3600682002200b36006c20022012370370200241f8006a20113703002002200429038002370041200241c9006a20044180026a41086a290300370000200241d1006a2009290300370000200241d9006a200a290300370000200220042f00703b0061200241e3006a200441f0006a41026a2d00003a0000200220042903d0013703800120024188016a200441d0016a41086a29030037030020024190016a200441d0016a41106a29030037030020024198016a200441d0016a41186a290300370300200241a0016a200441f0016a290300370300200241a8016a200441f8016a2903003703002003200328023c41016a36023c410421020c0d0b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b1036000b200741011037000b201041081037000b41052102200e450d012006102a0c010b410521020b20002002360200200441a0026a24000b16002000410036020020002001410c6a2802003602040bab0202057f027e230041106b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d024105210302402001410c6a2802002205200241146a2802002206490d00200520066b200241246a2802002205470d0020022802042107200128020421082004200128021029035042002005ad4200109f0520012802182202420020022903082209427f200429030020042903084200521b7d220a200a20095622021b37030820020d000240024020012802142802082007200820066a2005101841026a220241024b0d0020020e03020001020b41b0fbc5001032000b410421030b20002003360200200441106a24000f0b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000bf90303027f027e067f230041106b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200420012802102903484200200241146a2802002203ad4200109f0520012802182202420020022903082206427f200429030020042903084200521b7d2207200720065622021b37030841052108024020020d000240024020032001410c6a2209280200220a4b0d00200321020c010b02400240200141086a2802002202200a6b2003200a6b220b490d002001280204210c200a21020c010b200a200b6a220c200a490d062002410174220d200c200d200c4b1b220d4100480d060240024020020d00200d1028210c0c010b20012802042002200d102c210c0b200c450d052001200c360204200141086a200d3602002001410c6a28020021020b200c20026a210d02400240200b4102490d00200d41002003200a417f73220a6a220b1099051a200c200320026a200a6a6a210d200b20026a21020c010b200b450d010b200d41003a0000200241016a21020b20092002360200024002402001280214280208200520012802042002101741026a220141024b0d0020010e03020001020b41a0fac5001032000b410421080b20002008360200200441106a24000f0b41b698c40041f4031050000b41b698c40041f4031050000b200d41011037000b1031000bbb0b05047f027e037f017e037f230041e0016b2204240002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d03200241246a2802002105200241346a280200210602400240024002400240200241146a2802002203450d0020022802042107200441306a200128021029034842002003ad4200109f0520012802182202420020022903082208427f200429033020042903384200521b7d22092009200856220a1b37030841052102200a0d0e2003417f4c0d092003102e220a450d0a024020012802142802082007200a2003101741026a220741024b0d0020070e03040002040b41a0fac5001032000b4101210b410021074100210c0c010b2004200336028c012004200a36028801200441c0006a20044188016a106d200429024421082004280240210b200a102a200b450d0c2008a7210c200128021028025c2008422088a72207490d0b0b200b2007410041202007676b10c402024020074102490d00200b21022007210303402002200241206a220a4120109c05450d0c200a21022003417f6a220341024f0d000b0b200441206a200128021029034842002006ad220d4200109f0520012802182202420020022903082208427f200429032020042903284200521b7d2209200920085622021b37030820020d0a2006417f4c0d060240024020060d004101210a02402001280214280208200541014100101741026a220241024b0d0020020e030d00020d0b41a0fac5001032000b024002402006102e220a450d00024020012802142802082005200a2006101741026a220241024b0d0020020e03020003020b41a0fac5001032000b200641011037000b200a102a0c0b0b20042001280210220329032842002007ad4200109f05200441106a20032903204200200d4200109f0520012802182102427f2109024020042903184200520d0020042903084200520d002004290310220820042903007c220d2008540d00427f200d20032903307c22082008200d541b21090b200242002002290308220820097d220920092008561b37030820092008580d012006450d0a200a102a0c0a0b200a102a0c0a0b200441b8016a41086a22052001280200280218220341d8006a290000370300200441b8016a41106a2201200341e0006a290000370300200441b8016a41186a220e200341e8006a290000370300200420032900503703b80102402003413c6a2802002202200341386a280200470d00200241016a220f2002490d0820024101742210200f2010200f4b1b2210ad42b0017e2208422088a70d082008a7220f4100480d080240024020020d00200f102821020c010b2003280234200241b0016c200f102c21020b2002450d0720032002360234200341386a2010360200200328023c21020b2003280234200241b0016c6a220241003a0000200220042f00dd013b0001200241053a00102002200736000c2002200c3600082002200b360004200220042903b801370011200241036a200441dd016a41026a2d00003a0000200241196a2005290300370000200241216a2001290300370000200241296a200e2903003700002002200a360034200220063600382002200636003c200220042f00b5013b0031200241336a200441b5016a41026a2d00003a00002002200429038801370340200241c8006a20044188016a41086a290300370300200241d0006a20044188016a41106a290300370300200241d8006a20044188016a41186a290300370300200241e0006a200441a8016a290300370300200241e8006a200441c0006a41c800109a051a2003200328023c41016a36023c410421020c090b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b41b698c40041f4031050000b1036000b200341011037000b200f41081037000b1031000b41052102200c450d00200b102a0b20002002360200200441e0016a24000b8e0a03027f027e057f230041e00b6b220424000240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200420012802102903484200200241146a2802002202ad4200109f0520012802182203420020032903082206427f200429030020042903084200521b7d2207200720065622081b3703084105210320080d052002417f4c0d02024020020d0002402001280214280208200541014100101741026a220241024b0d0020020e03070007070b41a0fac5001032000b02400240024002402002102e2208450d0002402001280214280208200520082002101741026a220541024b0d0020050e03030002030b41a0fac5001032000b200241011037000b2002410f4b0d010b2008102a0c060b200841086a2900002106200829000021072008102a200128020028021822092802180d032009417f360218200441c8006a200941e8006a290000370300200441c0006a200941e0006a290000370300200441306a41086a200941d8006a29000037030020042009290050370330024002402009411c6a220a280200220841f8b9c000460d00200941206a280200210b0c010b4100210b20044180096a410041e0021099051a200441e0006a410041a0081099051a41880b10282208450d05200841003b010620084100360200200841086a20044180096a41e002109a051a200841e8026a200441e0006a41a008109a051a200941206a41003602002009200836021c0b02400240034020082f0106220c4105742105410021024100210102400240034020052002460d01200441306a200820026a41086a4120109c052203450d02200241206a2102200141016a21012003417f4a0d000b2001417f6a210c0b200b450d02200b417f6a210b2008200c4102746a41880b6a28020021080c010b0b200941246a2103410121020c010b200441106a41186a200441306a41186a290300370300200441106a41106a200441306a41106a290300370300200441106a41086a200441306a41086a29030037030020042004290330370310200941246a21034100210b200c2101410021020b0240024020020d002004419c096a200441106a41086a290300370200200441a4096a200441106a41106a290300370200200441ac096a200441106a41186a29030037020020042003360290092004200136028c092004200a3602880920042008360284092004200b36028009200420042903103702940920044180016a200429035037030020044188016a200441d0006a41086a29030037030020044194016a42003702002004420037037820044200370360200441f8b9c00036029001200441003a009c012004419d016a2004290030370000200441a5016a200441306a41086a290000370000200441ad016a200441306a41106a290000370000200441b5016a200441306a41186a290000370000200441003a00bd0120044180096a200441e0006a10b70121020c010b200441f8006a4200370300200441f4006a41f8b9c00036020020044100360280012004410036027020044200370368200441f8b9c000360264200441003602602008200141e0006c6a41e8026a2102200441e0006a1095010b200241286a2006370300200241206a2007370300200242013703182009200928021841016a360218410421030c050b41b698c40041f4031050000b41b698c40041f4031050000b1036000b41a8b8c0004110200441e0006a41d0b8c0001038000b41880b41081037000b20002003360200200441e00b6a24000ba30203037f027e027f230041206b220424002001410c6a22054100360200200441086a2001280200280218220641186a200641d0006a10a801200441086a41106a290300210720042802082106200429031021080240024002400240200141086a2802002209200528020022056b4110490d00200128020421090c010b200541106a220a2005490d0220094101742205200a2005200a4b1b22054100480d020240024020090d002005102821090c010b200128020420092005102c21090b2009450d0120012009360204200141086a20053602002001410c6a28020021050b2001410c6a200541106a360200200920056a22012007427f20061b37000820012008427f20061b37000020004104360200200441206a24000f0b200541011037000b1031000bee0203027f027e017f230041206b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200420012802102903484200200241146a2802002202ad4200109f0520012802182203420020032903082206427f200429030020042903084200521b7d2207200720065622081b37030841052103024020080d002002417f4c0d0302400240024020020d004101210802402001280214280208200541014100101741026a220141024b0d0020010e03040002040b41a0fac5001032000b02402002102e2208450d0002402001280214280208200520082002101741026a220141024b0d0020010e03030002030b41a0fac5001032000b200241011037000b200441106a200820021054024020042802100d002004280214200441186a280200100b0b410421032002450d010b2008102a0b20002003360200200441206a24000f0b41b698c40041f4031050000b41b698c40041f4031050000b1036000bbe0101037f410021042001410c6a4100360200200128020028021c21050240024002400240200141086a28020022064104490d00200128020421060c010b200641017422044104200441044b1b22044100480d020240024020060d002004102821060c010b200128020420062004102c21060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441046a360200200620046a2005360000200041043602000f0b200441011037000b1031000bc205020a7f017e230041c0006b220424002004200136020c20042000410120011b3602082004200441086a106c024020042802000d000240024002400240024002400240200428020c22014170712200417f4c0d002004280204210502400240200141047622060d00410821070c010b200010282207450d020b02402005450d00200441206a4104722108410021094100210a410021000340200441206a200441086a109803200441306a41086a220b200841086a2802003602002004200829020037033002402004280220220c4104470d002006450d0a2007102a0c0a0b200041016a2101200441106a41086a220d200b28020036020020042004290330370310024020002006470d0020092001200920014b1b220641ffffffff00712006470d062006410474220b4100480d060240024020000d00200b102821070c010b2007200a200b102c21070b2007450d050b2007200a6a2200200c360200200041046a20042903103702002000410c6a200d280200360200200941026a2109200a41106a210a2001210020052001470d000b0b2007450d07200441206a200220072005200311060020042802202100410110282201450d042004428180808010370234200420013602300240024020004105460d00200141003a0000200141014102102c2101024020004104470d002001450d08200141003a00012004428280808020370234200420013602304202210e0c020b2001450d08200141013a0001200442828080802037023420042001360230200441206a200441306a1099032004350238210e200428023021010c010b200141013a00004201210e0b2001ad422086200e84210e02402006450d002007102a0b200441c0006a2400200e0f0b1036000b200041081037000b200b41081037000b1031000b410141011037000b410241011037000b410241011037000b41b8c6c20041f000200441206a41c0c5c2001038000bde0202047f017e02400240024002400240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a3602002004417f6a220441034b0d0520040e0401020304010b200041043602000f0b0240200541034b0d00200041043602000f0b200041003602002003280001210420012002417b6a3602042001200341056a360200200020043602040f0b024020054108490d0020004101360200200329000121062001200241776a3602042001200341096a360200200041086a20063703000f0b200041043602000f0b0240200541034b0d00200041043602000f0b200041023602002003280001210420012002417b6a3602042001200341056a360200200020043602040f0b024020054108490d0020004103360200200329000121062001200241776a3602042001200341096a360200200041086a20063703000f0b200041043602000f0b200041043602000b840b02037f017e024002400240024002400240024002400240024002400240024020002802000e0400010203000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0c200241017422042003200420034b1b22044100480d0c0240024020020d002004102821030c010b200128020020022004102c21030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a00002000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0c200241017422002004200020044b1b22004100480d0c0240024020020d002000102821020c010b200128020020022000102c21020b2002450d0520012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0b200241017422042003200420034b1b22044100480d0b0240024020020d002004102821030c010b200128020020022004102c21030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a00002000290308210502400240200141046a2802002202200428020022006b4108490d00200128020021020c010b200041086a22032000490d0b200241017422002003200020034b1b22004100480d0b0240024020020d002000102821020c010b200128020020022000102c21020b2002450d0620012002360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200220006a20053700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0a200241017422042003200420034b1b22044100480d0a0240024020020d002004102821030c010b200128020020022004102c21030b2003450d0620012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a00002000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0a200241017422002004200020044b1b22004100480d0a0240024020020d002000102821020c010b200128020020022000102c21020b2002450d0720012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d09200241017422042003200420034b1b22044100480d090240024020020d002004102821030c010b200128020020022004102c21030b2003450d0720012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a00002000290308210502400240200141046a2802002202200428020022006b4108490d00200128020021020c010b200041086a22032000490d09200241017422002003200020034b1b22004100480d090240024020020d002000102821020c010b200128020020022000102c21020b2002450d0820012002360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200220006a20053700000f0b200441011037000b200041011037000b200441011037000b200041011037000b200441011037000b200041011037000b200441011037000b200041011037000b1031000bfd0201057f230041d0006b220224002002410036022820014110200241286a10062103024002400240024020022802282204417f460d0020030d010b200041023a00000c010b2004450d0120032d0000220541014b0d01410021010240024020050e020100010b41002101200241003a00482004417f6a2105200341016a21060340024020052001470d00200141ff0171450d04200241003a00480c040b200241286a20016a200620016a2d00003a00002002200141016a22043a00482004210120044120470d000b200241086a41186a200241286a41186a290300370300200241086a41106a200241286a41106a290300370300200241086a41086a200241286a41086a29030037030020022002290328370308410121010b200020013a000020002002290308370001200041096a200241106a290300370000200041116a200241186a290300370000200041196a200241206a2903003700002003102a0b200241d0006a24000f0b41c4d1c3004133200241286a419cd9c3001038000b1300200041013602042000418cc8c2003602000b340020004195c9c20036020420004100360200200041146a4103360200200041106a41a0c9c200360200200041086a420a3702000b2f01017f02404101102822020d00410141011037000b200042818080801037020420002002360200200241003a00000b8b5606077f017e067f027e037f037e230041e0036b22012400200141d8006a41086a220242003703002001420037035841e7fcc5004110200141d8006a100820014190016a41086a20022903003703002001200129035837039001200141e8026a20014190016a109a0302400240024002400240024002400240024002400240024020012d00e80222024102470d00200141d8006a21030c010b20014190016a4110100920014188026a41086a200141f1026a29000037030020014188026a41106a200141e8026a41116a29000037030020014188026a41186a220420014181036a290000370300200120012900e90237038802200141d8006a21030240200241037122024103460d0020020e03010001010b200141a0016a41186a2004290300370300200141a0016a41106a20014188026a41106a290300370300200141a0016a41086a20014188026a41086a29030037030020012001290388023703a001200141d8006a41086a220242003703002001420037035841c0fcc5004111200141d8006a100820014190016a41086a2002290300370300200120012903583703900141002105200141003602e80220014190016a4110200141e8026a10062102024020012802e8022204417f460d002002450d0020044104490d02200228000021052002102a0b411610282202450d022002410e6a41002900dffc45370000200241086a41002900d9fc45370000200241002900d1fc4537000020024116412c102c2202450d0320022005360016200141d8006a41186a22044200370300200141d8006a41106a22064200370300200141d8006a41086a22074200370300200142003703582002411a200141d8006a1000200141e8026a41186a2004290300370300200141e8026a41106a2006290300370300200141e8026a41086a2007290300370300200120012903583703e8022002102a20014100360258200141e8026a4120200141d8006a1006210202400240024020012802582206417f460d002002450d0020012006360294012001200236029001200141d8006a20014190016a107320012802582204450d07200129025c210802402006450d002002102a0b200120043602782001200837027c2008a721022008422088a72206418002490d01412010282206450d08200620012903a001370000200641186a200141a0016a41186a290300370000200641106a200141a0016a41106a290300370000200641086a200141a0016a41086a29030037000020014281808080103702ec02200120063602e802200541016a2205200141e8026a109f032006102a200141d8006a41086a220642003703002001420037035841c0fcc5004111200141d8006a100820014190016a41086a20062903003703002001200129035837039001200120053602e80220014190016a4110200141e8026a410410070c020b4100210620014100360280012001420137037841012104410021020b200141e8026a41186a2209200141a0016a41186a290300370300200141e8026a41106a220a200141a0016a41106a290300370300200141e8026a41086a220b200141a0016a41086a290300370300200120012903a0013703e802024020062002470d00200241016a22072002490d0c2002410174220c2007200c20074b1b220741ffffff3f712007470d0c2007410574220c4100480d0c0240024020020d00200c102821040c010b20042002410574200c102c21040b2004450d082001200736027c20012004360278200721020b200420064105746a220720012903e802370000200741186a2009290300370000200741106a200a290300370000200741086a200b2903003700002001200641016a360280012005200141f8006a109f030b2002450d002004102a0b200141d8006a41086a220242003703002001420037035841d8a1c6004113200141d8006a1008200141e8026a41086a2002290300370300200120012903583703e802200141003602a001200141e8026a4110200141a0016a1006210202400240024020012802a0012204417f460d002002450d002004450d0120022d000021042002102a200141e8026a4110100920044102460d0020044101710d020b41c0acc3001032000b41c4d1c3004133200141d8036a419cd9c3001038000b200141d8006a41086a220242003703002001420037035841afc5c2004111200141d8006a100820014190016a41086a22042002290300370300200120012903583703900120014190016a41101009200242003703002001420037035841c8fbc5004117200141d8006a100820042002290300370300200120012903583703900120014190016a41101009200242003703002001420037035841feadc4004117200141d8006a1008200141e8026a41086a22042002290300370300200120012903583703e8020240200141e8026a41104101410041001003417f470d0010a0032108200242003703002001420037035841feadc4004117200141d8006a100820042002290300370300200120012903583703e802200120083703a001200141e8026a4110200141a0016a410810070b2002420037030020014200370358418194c1004110200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200141003602e802200141a0016a4110200141e8026a1006210220012802e8022204417f460d072002450d0720044104490d062002280000210d2002102a200141a0016a41101009410121090c080b41c4d1c3004133200141d8036a419cd9c3001038000b411641011037000b412c41011037000b41c4d1c3004133200141d8036a419cd9c3001038000b412041011037000b200c41011037000b41c4d1c3004133200141d8036a419cd9c3001038000b410021090b200141d8006a41086a220242003703002001420037035841d591c6004115200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200141003602e802200141a0016a4110200141e8026a10062102024002400240024002400240024002400240024002400240024020012802e8022204417f460d002002450d002004450d0b20022d000021042002102a20044102460d0020044101710d010b410410282204450d0120044100360200200141d8006a41086a2202420037030020014200370358419194c1004115200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200141003602f002200142013703e8024101200141e8026a10b401200428020021070240024020012802ec02220520012802f00222066b4104490d0020012802e80221020c010b200641046a22022006490d0d2005410174220a2002200a20024b1b220a4100480d0d0240024020050d00200a102821020c010b20012802e8022005200a102c21020b2002450d032001200a3602ec02200120023602e802200a21050b2001200641046a220a3602f002200220066a2007360000200141a0016a41102002200a100702402005450d002002102a0b2004102a410410282204450d0320044100360200200141d8006a41086a2202420037030020014200370358418898c1004116200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200141003602f002200142013703e8024101200141e8026a10b401200428020021070240024020012802ec02220520012802f00222066b4104490d0020012802e80221020c010b200641046a22022006490d0d2005410174220a2002200a20024b1b220a4100480d0d0240024020050d00200a102821020c010b20012802e8022005200a102c21020b2002450d052001200a3602ec02200120023602e802200a21050b2001200641046a220a3602f002200220066a2007360000200141a0016a41102002200a100702402005450d002002102a0b2004102a200141d8006a41086a2202420037030020014200370358419e98c1004110200141d8006a1008200141a0016a41086a22042002290300370300200120012903583703a001200141003602e802200141a0016a4110200141e8026a41041007200141013a00e802200242003703002001420037035841d591c6004115200141d8006a100820042002290300370300200120012903583703a001200141a0016a4110200141e8026a410110070b200141d8006a41086a2202420037030020014200370358419194c1004115200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200141003602e802200141a0016a4110200141e8026a100621020240024020012802e8022204417f460d002002450d002001200436028c022001200236028802200141e8026a20014188026a10820120012802e802220e450d0620012902ec02210f2004450d012002102a0c010b4104210e4200210f0b200141d8006a41086a2202420037030020014200370358418898c1004116200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200141003602e802200141a0016a4110200141e8026a100621020240024020012802e8022204417f460d002002450d002001200436028c022001200236028802200141e8026a20014188026a10820120012802e8022207450d0720012902ec02211002402004450d002002102a0b20012007360288022010422088a7210c0c010b4104210720014104360288024100210c420021100b200f422088a72111024020090d002011417f6a220220114f0d07200220114b0d07200e20024102746a280200210d0b41002011419c7f6a22022002201141016a4b1b221220114b0d07200e20124102746a21132012450d0a200cad2108200e210b0340200b2802002109024002400240024002402008a7220a41014b0d0041002102200a0e020201020b41002102200a2104034020022004410176220620026a22052009200720054102746a280200491b2102200420066b220441014b0d000b0b20092007200241027422046a2802002206460d022002200920064b6a21020c010b410021020b200120023602e80241d498c100412e200141e8026a418499c1001038000b20082002ad580d09200720046a2204200441046a2002417f73200a6a410274109b051a201042ffffffff0f83200a417f6a220cad422086842110200b41046a220b2013460d0b2008427f7c210820012802880221070c000b0b410441041037000b200a41011037000b410441041037000b200a41011037000b41c4d1c3004133200141d8036a419cd9c3001038000b41c4d1c3004133200141d8036a419cd9c3001038000b41ae98c10041261050000b41e4e8c5001032000b41b0b1c0001032000b41c4d1c3004133200141d8036a419cd9c3001038000b200f42ffffffff0f8321080240201120126b2202450d0002402012450d00200e20132002410274109b051a2010422088a7210c0b20082002ad4220868421080b2001280288022107410021020240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200c41014b0d00200c0e020201020b200c2104034020022004410176220620026a2205200d200720054102746a280200491b2102200420066b220441014b0d000b0b0240200d200720024102746a2802002204460d002002200d20044b6a21020b200c2002490d010b200c2010a7470d02200c41016a2204200c490d13200c41017422062004200620044b1b220441ffffffff03712004470d132004410274220641004e0d010c130b41f8b0c0001032000b02400240200c0d002006102821070c010b2007200c4102742006102c21070b2007450d0120012007360288022004ad21100b200720024102746a220441046a2004200c20026b410274109b051a2004200d36020002402008422088220fa722042008a7470d00200441016a22022004490d11200fa722054101742206200220022006491b220241ffffffff03712002470d11200241027422064100480d110240024020040d0020061028210e0c010b200e20054102742006102c210e0b200e450d022008422088a721042002ad21080b200e20044102746a200d3602000240200c41016a22130d00419499c1001032000b2013201341017622024d0d02200128028802220620024102746a280200210d024020134101710d0020132002417f6a22024d0d04200620024102746a280200200d6a410176210d0b200141d8006a41086a2202420037030020014200370358419194c1004115200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200141003602f002200142013703e802200441016a2211200141e8026a10b4010240024020110d0020012802f002210920012802ec02210720012802e80221040c010b410020012802f00222026b2106200441027441046a210a20012802ec022107200e210503402005280200210b02400240200720066a4104490d0020012802e80221040c010b200241046a22042002490d13200741017422092004200920044b1b22094100480d130240024020070d002009102821040c010b20012802e80220072009102c21040b2004450d07200120093602ec02200120043602e802200921070b200541046a21052001200241046a22093602f002200420026a200b3600002006417c6a210620092102200a417c6a220a0d000b0b2008a72102200141a0016a411020042009100702402007450d002004102a0b02402002450d00200e102a0b200128028802210e200141d8006a41086a2202420037030020014200370358418898c1004116200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a001200142013703e802200141003602f0022013200141e8026a10b401200c41027441046a2109410020012802f00222026b21062010a7210c20012802ec022107200e210503402005280200210b02400240200720066a4104490d0020012802e80221040c010b200241046a22042002490d122007410174220a2004200a20044b1b220a4100480d120240024020070d00200a102821040c010b20012802e8022007200a102c21040b2004450d072001200a3602ec02200120043602e802200a21070b200541046a21052001200241046a220a3602f002200420026a200b3600002006417c6a2106200a21022009417c6a22090d000b200141a0016a41102004200a100702402007450d002004102a0b0240200c450d00200e102a0b200141d8006a41086a2202420037030020014200370358419e98c1004110200141d8006a1008200141a0016a41086a2002290300370300200120012903583703a0012001200d3602e802200141a0016a4110200141e8026a410410070240201141e500470d00200d419a086a1098014b0d00200141d8006a41086a220442003703002001420037035841d985c2004117200141d8006a1008200141e8026a41086a2004290300370300200120012903583703e802410810282204450d072004200d360004200441e400360000200141e8026a41102004410810072004102a0b200242003703002001420037035841f9b5c200411d200141d8006a1008200141e8026a41086a2002290300370300200120012903583703e802200141003602a001200141e8026a4110200141a0016a10062102024020012802a0012204417f460d002002450d0020012002360288022001200436028c0220044104490d0c2001200241046a3602880220012004417c6a220636028c0220064104490d0c200228000021072001200441786a36028c022001200241086a360288022002280004210b200141a0016a20014188026a107720012802a001220a450d0c20012902a40121144100210502400240200128028c0222040d000c010b20012004417f6a220936028c022001200128028802220641016a36028802024020062d00004101460d000c010b20094104490d0020012004417b6a36028c022001200641056a360288022006280001210c410121050b2002102a2014422088a72109024020072000470d00024020050d002009ad42287e2208422088a70d0a2008a72202417f4c0d0a0240024020020d004108210c0c010b20021028220c450d0c0b4100210602402009450d00200941286c210541002106200c2102200a21040340200441086a2903002108200441106a2903002110200441186a290300210f20042903002115200241206a200441206a290300370300200241186a200f370300200241106a2010370300200241086a200837030020022015370300200241286a2102200641016a2106200441286a2104200541586a22050d000b0b200141b0016a200b360200200141a0016a410c6a2006360200200141a0016a41086a20093602002001200c3602a401200141003602a001200141e8026a200141a0016a10c30120014193026a200141e8026a41086a280200360000200120012903e80237008b02200141e8026a410c6a2001418f026a290000370000200141c6a4b9da043600e902200141023a00e80220012001290088023700ed02200141e8026a10ce012009450d01200c102a0c010b2009ad42287e2208422088a70d092008a72202417f4c0d090240024020020d00410821130c010b200210282213450d0c0b0240024020090d00410021060c010b200941286c21054100210620132102200a21040340200441086a2903002108200441106a2903002110200441186a290300210f20042903002115200241206a200441206a290300370300200241186a200f370300200241106a2010370300200241086a200837030020022015370300200241286a2102200641016a2106200441286a2104200541586a22050d000b0b200141b4016a200b360200200141b0016a2006360200200141a0016a410c6a2009360200200141a0016a41086a20133602002001200c3602a401200141013602a001200141e8026a200141a0016a10c30120014193026a200141e8026a41086a280200360000200120012903e80237008b02200141e8026a410c6a2001418f026a290000370000200141c6a4b9da043600e902200141023a00e80220012001290088023700ed02200141e8026a10ce012009450d002013102a0b2014a7210c0240200b20076a2000470d00200141d8006a41086a220242003703002001420037035841c694c600411b200141d8006a1008200141e8026a41086a2002290300370300200120012903583703e802200141003602a801200142013703a0012009200141a0016a10b40102402009450d00200a200941286c6a2107200a210403402004200141a0016a108f01200441206a29030021080240024020012802a401220620012802a80122026b4108490d0020012802a00121060c010b200241086a22052002490d15200641017422022005200220054b1b22024100480d150240024020060d002002102821060c010b20012802a00120062002102c21060b2006450d0f200120023602a401200120063602a00120012802a80121020b2001200241086a3602a801200620026a20083700002007200441286a2204470d000b0b20012802a4012102200141e8026a411020012802a001220420012802a801100702402002450d002004102a0b200141e8026a41106a2009360200200141f4026a200c360200200141e8026a41086a2202200a360200200141003602ec022001410a3a00e80241014100200141e8026a10cc01200141d8006a41086a220442003703002001420037035841f9b5c200411d200141d8006a100820022004290300370300200120012903583703e802200141e8026a411010090c010b200c450d00200a102a0b200141d8006a41086a22024200370300200142003703584196b6c2004115200141d8006a1008200141e8026a41086a2002290300370300200120012903583703e802200141003602a001200141e8026a4110200141a0016a1006210220012802a0012204417f460d0f2002450d0f2004450d0e20022d0000220641034b0d0e0240024020060e04010f0100010b2004417f6a41074b0d0d0c0f0b2002102a0c0f0b200641041037000b200641041037000b41ac99c100200220131034000b41ac99c100200220131034000b200941011037000b200a41011037000b410841011037000b1036000b200241081037000b200241081037000b200241011037000b41c4d1c3004133200141d8036a419cd9c3001038000b20022800052106200228000121042002102a024020042000470d00200141043602a001200120063602a401200141e8026a200141a0016a10c30120014193026a200141f0026a280200360000200120012903e80237008b02200141f4026a2001418f026a290000370000200141c6a4b9da043600e902200141023a00e80220012001290088023700ed02200141e8026a10ce010b200620046a2000470d022001410036028802200141d8006a41086a22024200370300200142003703584196b6c2004115200141d8006a1008200141e8026a41086a2002290300370300200120012903583703e802200141a0016a20014188026a10da02200141e8026a411020012802a001220220012802a8011007024020012802a401450d002002102a0b200141023602ec022001410a3a00e80241014100200141e8026a10cc010c020b2004417f6a4108490d0020022800052106200228000121042002102a024020042000470d00200141033602a001200120063602a401200141e8026a200141a0016a10c30120014193026a200141f0026a280200360000200120012903e80237008b02200141f4026a2001418f026a290000370000200141c6a4b9da043600e902200141023a00e80220012001290088023700ed02200141e8026a10ce010b200620046a2000470d012001410236028802200141d8006a41086a22024200370300200142003703584196b6c2004115200141d8006a1008200141e8026a41086a2002290300370300200120012903583703e802200141a0016a20014188026a10da02200141e8026a411020012802a001220220012802a8011007024020012802a401450d002002102a0b200141013602ec022001410a3a00e80241014100200141e8026a10cc010c010b41c4d1c3004133200141d8036a419cd9c3001038000b02400240024002400240024020004180e101700d00200141e8026a10d301200141c8006a200141e8026a1091012001200141c8006a41086a29030022083703800120012001290348221037037820014180036a2008370300200141e8026a41106a2010370300200141e8026a41086a220441013a00002001410b3a00e8024100210241014100200141e8026a10cc01200141003a008f012001420037039801200142003703900120044200370300200142003703e8024181a2c6004112200141e8026a1008200141a0016a41086a2004290300370300200120012903e8023703a001200141003602e802200141a0016a4110200141e8026a100621040240024020012802e8022206417f470d000c010b024020040d000c010b2001200636028c022001200436028802200141e8026a20014188026a10820120012802e8022202450d0620012902ec0221082006450d002004102a0b2002410420021b210c024002402008420020021b2214422088a722040d004100210b0c010b200141f1026a210d200141c8026a211320014188026a41206a210e200141a0016a41086a2109200141a0036a21114100210a4100210b41002102024003400240024002400240200b450d00200c20024102746a2106200c2002200a6a4102746a21050340200220044f0d02200141a0016a2006280200220710e90220012903a0014201520d0420014188026a200941e000109a051a2001290378220f200129038802221554200141f8006a41086a290300220820014188026a41086a29030022105420082010511b450d03200141013a008f010240200a20026a220720044f0d0020052006280200360200200641046a2106200541046a2105200241016a22022004490d010c070b0b41c4b2c000200720041034000b200c20024102746a21060340200220044f0d01200141a0016a2006280200220710e90220012903a0014201520d0320014188026a200941e000109a051a2001290378220f20012903880222155a200141f8006a41086a290300220820014188026a41086a29030022105a20082010511b0d02200641046a2106200141013a008f01200241016a22022004490d000b4100210b0c050b41e8b1c000200220041034000b2001200f20157d3703782001200820107d200f201554ad7d37038001411210282206450d05200641106a41002f008086423b0000200641086a41002900f88542370000200641002900f08542370000200641124124102c2206450d0620062007360012200341186a22054200370000200341106a22124200370000200341086a22004200370000200342003700002006411620031000200141e8026a41186a2005290000370300200141e8026a41106a2012290000370300200141e8026a41086a2000290000370300200120032900003703e8022006102a200141e8026a41201009200e20012903980220014188026a41186a29030010aa02200141386a201320012903880220014188026a41086a220629030010d00120014190016a41086a2205427f20052903002208200141386a41086a2903007c200129039001221020012903387c220f2010542205ad7c22102005201020085420102008511b22051b3703002001427f200f20051b37039001200129038802210820112006290300370300200d2013290000370000200d41086a201341086a290000370000200d41106a201341106a290000370000200d41186a201341186a2900003700002001200837039803200141023a00f0022001410b3a00e802200120073602940341014100200141e8026a10cc010b200a417f6a210a200b41016a210b200241016a22022004490d000b0b200b450d00200220044f0d00200c20024102746a2206200b4102746b2006200420026b410274109b051a0b200141e8026a41086a22024200370300200142003703e8024181a2c6004112200141e8026a1008200141a0016a41086a2002290300370300200120012903e8023703a00102400240200c0d00200141a0016a411010090c010b200141003602f002200142013703e8022004200b6b2204200141e8026a10b4010240024020040d0020012802f002210920012802ec02210720012802e80221040c010b410020012802f00222026b2106200c20044102746a210b20012802ec022107200c210503402005280200210a02400240200720066a4104490d0020012802e80221040c010b200241046a22042002490d0a200741017422092004200920044b1b22094100480d0a0240024020070d002009102821040c010b20012802e80220072009102c21040b2004450d07200120093602ec02200120043602e802200921070b2001200241046a22093602f002200420026a200a3600002006417c6a210620092102200b200541046a2205470d000b0b2014a72102200141a0016a411020042009100702402007450d002004102a0b2002450d00200c102a0b024020012d008f010d004200210f200141286a20012903782208200141f8006a41086a2202290300221042c0843d420010a005200141186a20012903282215200141286a41086a290300221442c0fb42427f109f05200141086a2015201442a0c21e4200109f05200220102010200141086a41086a29030020012903082215200820012903187c42018842ffffffff0f837c2214201554ad7c22152014200856201520105620152010511b22041b22157d20082008201420041b221054ad7d3703002001200820107d370378200141e8026a41086a22024200370300200142003703e80241ace1c0004116200141e8026a1008200141d8006a41086a2002290300370300200120012903e802370358200141003602e802200141d8006a4110200141e8026a100621020240024020012802e8022204417f470d00420021080c010b20044110490d06200241086a29000021082002290000210f2002102a0b200141e8026a41086a22044200370300200142003703e80241ace1c0004116200141e8026a1008200141d8006a41086a2004290300370300200120012903e80237035820014200200820157d200f201054ad7d2214200f20107d2216200f56201420085620142008511b22021b3703f00220014200201620021b3703e802200141d8006a4110200141e8026a4110100720014190016a41086a2206427f200629030022142008201520021b7c2001290390012208200f201020021b7c220f2008542202ad7c22082002200820145420082014511b22021b3703002001427f200f20021b3703900120014180036a2015370300200141e8026a41106a2010370300200441033a00002001410b3a00e80241014100200141e8026a10cc010b200141e8026a10d30120014188026a200141e8026a200129039001220820014190016a41086a29030022104102109802024002402001280288020d00200141a0016a41106a201020014188026a41106a29030022157d2008200129039002220f54ad7d201520107d200f200854ad7d200f2008582015201058201520105122021b22041b37030020012008200f7d200f20087d20041b3703a8012001200f200856201520105620021b2202ad3703a001200141a0016a41086a2104024020020d0020012004360258200141d8006a109c010c020b20012004360258200141d8006a109d010c010b41abb6c20041ca00100b200120103703a801200120083703a0012001200141a0016a3602880220014188026a109c010b2001290378210820014180036a200141f8006a41086a290300370300200141f8026a2008370300200141e8026a41086a41043a00002001410b3a00e80241014100200141e8026a10cc010b200141d8006a41086a220242003703002001420037035841affec5004111200141d8006a1008200141e8026a41086a2002290300370300200120012903583703e802200141e8026a41101009200141e0036a24000f0b411241011037000b412441011037000b200941011037000b41c4d1c3004133200141d8036a419cd9c3001038000b41c4d1c3004133200141d8036a419cd9c3001038000b1031000bf52901047f230041c0006b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240411610282203450d002003410e6a41002900dffc45370000200341086a41002900d9fc45370000200341002900d1fc4537000020034116412c102c2203450d0120032000360016200241206a41186a22004200370300200241206a41106a22044200370300200241206a41086a22054200370300200242003703202003411a200241206a1000200241186a2000290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002003102a200128020021032001280208210120024100360228200242013703202001200241206a10b40102402001450d00200320014105746a2105034002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d052002200436022420022000360220200228022821010b2002200141016a360228200020016a20032d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d062002200436022420022000360220200228022821010b2002200141016a360228200020016a200341016a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d072002200436022420022000360220200228022821010b2002200141016a360228200020016a200341026a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d082002200436022420022000360220200228022821010b2002200141016a360228200020016a200341036a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d092002200436022420022000360220200228022821010b2002200141016a360228200020016a200341046a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d0a2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341056a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d0b2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341066a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d0c2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341076a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d0d2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341086a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d0e2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341096a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d0f2002200436022420022000360220200228022821010b2002200141016a360228200020016a2003410a6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d102002200436022420022000360220200228022821010b2002200141016a360228200020016a2003410b6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d112002200436022420022000360220200228022821010b2002200141016a360228200020016a2003410c6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d122002200436022420022000360220200228022821010b2002200141016a360228200020016a2003410d6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d132002200436022420022000360220200228022821010b2002200141016a360228200020016a2003410e6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d142002200436022420022000360220200228022821010b2002200141016a360228200020016a2003410f6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d152002200436022420022000360220200228022821010b2002200141016a360228200020016a200341106a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d162002200436022420022000360220200228022821010b2002200141016a360228200020016a200341116a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d172002200436022420022000360220200228022821010b2002200141016a360228200020016a200341126a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d182002200436022420022000360220200228022821010b2002200141016a360228200020016a200341136a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d192002200436022420022000360220200228022821010b2002200141016a360228200020016a200341146a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d1a2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341156a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d1b2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341166a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d1c2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341176a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d1d2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341186a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d1e2002200436022420022000360220200228022821010b2002200141016a360228200020016a200341196a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d1f2002200436022420022000360220200228022821010b2002200141016a360228200020016a2003411a6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d202002200436022420022000360220200228022821010b2002200141016a360228200020016a2003411b6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d212002200436022420022000360220200228022821010b2002200141016a360228200020016a2003411c6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d222002200436022420022000360220200228022821010b2002200141016a360228200020016a2003411d6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d232002200436022420022000360220200228022821010b2002200141016a360228200020016a2003411e6a2d00003a000002400240200228022420022802282201460d00200228022021000c010b200141016a22002001490d25200141017422042000200420004b1b22044100480d250240024020010d002004102821000c010b200228022020012004102c21000b2000450d242002200436022420022000360220200228022821010b2002200141016a360228200020016a2003411f6a2d00003a0000200341206a22032005470d000b0b2002280224210320024120200228022022012002280228100702402003450d002001102a0b200241c0006a24000f0b411641011037000b412c41011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b200441011037000b1031000bab0103017f017e027f230041206b2200240042002101200041106a41086a220242003703002000420037031041feb3c300410d200041106a1008200041086a2002290300370300200020002903103703002000410036021020004110200041106a100621020240024020002802102203417f460d002002450d0020034108490d01200229000021012002102a0b200041206a240020010f0b41c4d1c3004133200041106a419cd9c3001038000b0a0041d0c5c2001032000b3400200041bfcec20036020420004100360200200041146a4109360200200041106a41c4cec200360200200041086a42043702000bcf0101017f024002400240024002400240410110282202450d00200241003a0000200241014102102c2202450d01200241003a0001200241024104102c2202450d02200241003b0002200241044108102c2202450d0320024100360004200241084110102c2202450d0420024200370008200241104120102c2202450d052002420037001820024200370010200042a08080808004370204200020023602000f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000b130020004102360204200041a0e1c2003602000b3101017f02404108102822020d00410841011037000b20004288808080800137020420002002360200200242b8173700000b3101017f02404108102822020d00410841011037000b20004288808080800137020420002002360200200242c8013700000bcb0201047f230041d0006b220324002003410036022820012002200341286a1006210402400240024020032802282205417f460d0020040d010b200041003a00000c010b41002101200341003a00480340024020052001470d000240200141ff0171450d00200341003a00480b41c4d1c3004133200341286a419cd9c3001038000b200341286a20016a200420016a2d00003a00002003200141016a22023a00482002210120024120470d000b200341086a41186a2201200341286a41186a290300370300200341086a41106a2202200341286a41106a290300370300200341086a41086a2206200341286a41086a2903003703002003200329032837030802402005450d002004102a0b20002003290308370001200041013a0000200041196a2001290300370000200041116a2002290300370000200041096a20062903003700000b200341d0006a24000bd31803017f017e2b7f230041b00d6b22032400200320023602042003200136020042002104200341086a41086a220142003703002003420037030841aef2c2004115200341086a1008200341900d6a41086a2001290300370300200320032903083703900d200341e80c6a200341900d6a10a903024002400240024020032802ec0c22050d00410121050c010b20032903f00c220442ffffffff0f560d010b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20032802e80c2101200341086a410041e00c1099051a200541206a21062001411874411875210120052004422088a74105746a210741002108410021094100210a4100210b4100210c4100210d4100210e4100210f410021104100211141002112410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f4100212041002121410021224100212341002124410021254100212641002127200521024100212841d1002129024003402028212a02400240024002402001450d0020072005460d01200141016a210103400240024020022007470d002006212b200621022005212c0c010b2002212c200241206a222b21020b2001417f6a22010d000c030b0b024020022007460d00200241206a212b2002212c0c030b2006212b2005212c20072005460d040c010b200141016a2101034020072002460d04200241206a21022001417f6a22010d000b200241606a212c2002212b0b202c450d020b202b21020240024002400240024002402003280204220141056a222b417f4c0d002003280200212d02400240202b450d00202b10282228450d034100212e200341003602980d2003202b3602940d200320283602900d0c010b200341003602980d2003202b3602940d200341013602900d410110282228450d03200341013602940d200320283602900d20032802980d212e0b2003202e41016a3602980d2028202e6a202a3a00002001200341900d6a10b4010240024020032802940d222e20032802980d222b6b2001490d0020032802900d212e0c010b202b20016a2228202b490d05202e410174222b2028202b20284b1b222b4100480d0502400240202e0d00202b1028212e0c010b20032802900d202e202b102c212e0b202e450d042003202b3602940d2003202e3602900d20032802980d212b0b2003202b20016a3602980d202e202b6a202d2001109a051a2003200341900d6a36028c0d202c2003418c0d6a10c80120032802940d212c20032802900d210120032802980d212b200341900d6a41186a222e4200370300200341900d6a41106a22284200370300200341900d6a41086a222d4200370300200342003703900d2001202b200341900d6a1000200341e80c6a41186a222b202e290300370300200341e80c6a41106a222e2028290300370300200341e80c6a41086a222f202d290300370300200320032903900d3703e80c0240202c450d002001102a0b2029417f6a2129202a41016a2128200341086a202a4103704105746a220120032903e80c370000200141186a202b290300370000200141106a202e290300370000200141086a202f2903003700004100212c0340202a202a41036e222b417d6c6a4102470d06200341086a202c6a220141df006a2d000022082001411f6a2d000022097120082009722001413f6a2d00007172211f200141de006a2d000022082001411e6a2d000022097120082009722001413e6a2d00007172211e200141dd006a2d000022082001411d6a2d000022097120082009722001413d6a2d00007172211d200141dc006a2d000022082001411c6a2d000022097120082009722001413c6a2d00007172211c200141db006a2d000022082001411b6a2d000022097120082009722001413b6a2d00007172211b200141da006a2d000022082001411a6a2d000022097120082009722001413a6a2d00007172211a200141d9006a2d00002208200141196a2d00002209712008200972200141396a2d000071722119200141d8006a2d00002208200141186a2d00002209712008200972200141386a2d000071722118200141d7006a2d00002208200141176a2d00002209712008200972200141376a2d000071722117200141d6006a2d00002208200141166a2d00002209712008200972200141366a2d000071722116200141d5006a2d00002208200141156a2d00002209712008200972200141356a2d000071722115200141d4006a2d00002208200141146a2d00002209712008200972200141346a2d000071722114200141d3006a2d00002208200141136a2d00002209712008200972200141336a2d000071722113200141d2006a2d00002208200141126a2d00002209712008200972200141326a2d000071722112200141d1006a2d00002208200141116a2d00002209712008200972200141316a2d000071722111200141d0006a2d00002208200141106a2d00002209712008200972200141306a2d000071722110200141cf006a2d000022082001410f6a2d000022097120082009722001412f6a2d00007172210f200141ce006a2d000022082001410e6a2d000022097120082009722001412e6a2d00007172210e200141cd006a2d000022082001410d6a2d000022097120082009722001412d6a2d00007172210d200141cc006a2d000022082001410c6a2d000022097120082009722001412c6a2d00007172210c200141cb006a2d000022082001410b6a2d000022097120082009722001412b6a2d00007172210b200141ca006a2d000022082001410a6a2d000022097120082009722001412a6a2d00007172210a200141c9006a2d00002208200141096a2d00002209712008200972200141296a2d000071722109200141c8006a2d00002208200141086a2d00002220712008202072200141286a2d000071722108200141c7006a2d00002220200141076a2d00002221712020202172200141276a2d000071722120200141c6006a2d00002221200141066a2d00002222712021202272200141266a2d000071722121200141c5006a2d00002222200141056a2d00002223712022202372200141256a2d000071722122200141c4006a2d00002223200141046a2d00002224712023202472200141246a2d000071722123200141c3006a2d00002224200141036a2d00002225712024202572200141236a2d000071722124200141c2006a2d00002225200141026a2d00002226712025202672200141226a2d000071722125200141c1006a2d00002226200141016a2d00002227712026202772200141216a2d000071722126200141c0006a2d0000222720012d0000222e712027202e72200141206a2d000071722127202c41800c460d06200341086a202c202b410574202a41096e41e0006c6b6a6a220141ff006a201f3a0000200141fe006a201e3a0000200141fd006a201d3a0000200141fc006a201c3a0000200141fb006a201b3a0000200141fa006a201a3a0000200141f9006a20193a0000200141f8006a20183a0000200141f7006a20173a0000200141f6006a20163a0000200141f5006a20153a0000200141f4006a20143a0000200141f3006a20133a0000200141f2006a20123a0000200141f1006a20113a0000200141f0006a20103a0000200141ef006a200f3a0000200141ee006a200e3a0000200141ed006a200d3a0000200141ec006a200c3a0000200141eb006a200b3a0000200141ea006a200a3a0000200141e9006a20093a0000200141e8006a20083a0000200141e7006a20203a0000200141e6006a20213a0000200141e5006a20223a0000200141e4006a20233a0000200141e3006a20243a0000200141e2006a20253a0000200141e1006a20263a0000200141e0006a20273a0000202b212a202c41e0006a222c41e00c470d000c060b0b1036000b202b41011037000b410141011037000b202b41011037000b1031000b4100210120290d000b0b2000201f3a001f2000201e3a001e2000201d3a001d2000201c3a001c2000201b3a001b2000201a3a001a200020193a0019200020183a0018200020173a0017200020163a0016200020153a0015200020143a0014200020133a0013200020123a0012200020113a0011200020103a00102000200f3a000f2000200e3a000e2000200d3a000d2000200c3a000c2000200b3a000b2000200a3a000a200020093a0009200020083a0008200020203a0007200020213a0006200020223a0005200020233a0004200020243a0003200020253a0002200020263a0001200020273a00000b02402004a7450d002005102a0b200341b00d6a24000bfd0102057f017e230041306b220224002002410036022020014110200241206a10062101024002400240024020022802202203417f460d0020010d010b200041003602040c010b20022003360214200220013602102003450d0120022003417f6a3602142002200141016a36021020012d00002103200241206a200241106a106d20022802202204450d012002410c6a41026a2002411d6a41026a2d000022053a0000200220022f001d22063b010c20022902242107200020033a0000200020063b0001200041036a20053a000020002007370208200020043602042001102a0b200241306a24000f0b41c4d1c3004133200241206a419cd9c3001038000bfb0401057f230041106b2202240002400240024002400240024020002802704101460d0002400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d06200341017422052004200520044b1b22054100480d060240024020030d002005102821040c010b200128020020032005102c21040b2004450d0320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280274210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d06200441017422032005200320054b1b22034100480d060240024020040d002003102821040c010b200128020020042003102c21040b2004450d0420012004360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200420036a20063600000c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d05200341017422052004200520044b1b22054100480d050240024020030d002005102821040c010b200128020020032005102c21040b2004450d0420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00000b2000200110f1012000280278210320004180016a2802002200200110b40102402000450d002000410574210003402002200136020c20032002410c6a10c801200341206a2103200041606a22000d000b0b200241106a24000f0b200541011037000b200341011037000b200541011037000b1031000b860201017f0240024020002d00002201410e4b0d00024002400240024020010e0f050505050500050501050205030505050b200041086a2d00004101470d04200041146a280200450d04200041106a280200102a0c040b200041046a2d00004103470d0302402000410c6a280200450d00200041086a280200102a0b200041186a280200450d03200041146a280200102a0c030b200041046a2802000d022000410c6a280200450d02200041086a280200102a0c020b200041086a2d00004105490d01200041306a280200450d012000412c6a280200102a0c010b200041086a280200450d00200041046a280200102a0b0240200041fc006a280200450d002000280278102a0b0b130020004106360204200041c8f3c2003602000b3400200041d3f9c20036020420004100360200200041146a410f360200200041106a41dcf9c200360200200041086a42063702000b5501017f230041206b22022400200241003602082002420837030020024100360218200242013703104100200241106a10b401200041086a20022802183602002000200229031037020020021072200241206a24000b7201017f230041306b22022400200241186a4200370300200241106a4200370300200241086a42003703002002420037030020024100360228200242013703202002200241206a36022c20022002412c6a10c801200041086a200228022836020020002002290320370200200241306a24000b5d01027f230041106b2202240002404101102822030d00410141011037000b200341003a00002002428180808010370204200220033602004100200210b401200041086a200228020836020020002002290300370200200241106a24000b0900200042043702000b851805047f017e027f047e017f23004190026b22012400200141a8016a41086a22024200370300200142003703a80141f99fc6004115200141a8016a1008200141d0016a41086a22032002290300370300200120012903a8013703d001200141d0016a4110100920024200370300200142003703a801418ea0c600411a200141a8016a100820032002290300370300200120012903a8013703d00141002102200141003602a801200141d0016a4110200141a8016a100621030240024002400240024002400240024020012802a8012204417f460d002003450d0020044104490d01200328000021022003102a0b200141a8016a41086a22034200370300200142003703a80141bfa0c600411b200141a8016a1008200141d0016a41086a22042003290300370300200120012903a8013703d001200141186a200141d0016a109f02200129032021052001280218210620034200370300200142003703a80141bfa0c600411b200141a8016a1008200141086a4180e59af700200220024180e59af7004922071b20024180e59af70020071b6b2207ad2208420020084200109f0520042003290300370300200120012903a8013703d0012005420020061b2105200842a8c30180210842ffffffffffffffffff00428080808080808080807f20071b2001290308220920012903102009423f87521b42808090bbbad6adf00d7f210902400240200241ffe49af7004b0d0042ffffffffffffffffff00428080808080808080807f2005200820097d22097d22084200531b20082005427f5522022009427f554720022008427f5547711b22084280ec94a37c20084280ec94a37c551b21080c010b42ffffffffffffffffff00428080808080808080807f2005200820097c22097c22084200531b20082005427f5522022009427f554620022008427f5547711b21080b200120083703a801200141d0016a4110200141a8016a41081007200141a8016a41086a22024200370300200142003703a801418ea0c600411a200141a8016a1008200141d0016a41086a22032002290300370300200120012903a8013703d001200141d0016a4110100920024200370300200142003703a80141a8a0c6004117200141a8016a100820032002290300370300200120012903a8013703d001200141d0016a4110100920024200370300200142003703a80141d9efc200410d200141a8016a100820032002290300370300200120012903a8013703d00141002106200141003602a801200141d0016a4110200141a8016a10062102024020012802a8012203417f460d002002450d0020034104490d02200228000021062002102a200141d0016a411010090b200141a8016a41086a22024200370300200142003703a801419df2c2004111200141a8016a1008200141d0016a41086a2002290300370300200120012903a8013703d001200141a8016a200141d0016a411010a7030240024020012d00a8014101460d00200141286a41086a4200370300200141286a41106a4200370300200141286a41186a4200370300200141f0016a41186a200141c1016a290000370300200141f0016a41106a200141a8016a41116a290000370300200141f0016a41086a200141b1016a290000370300200120012900a9013703f00120014200370328200141f0016a21020c010b200141d0016a41101009200141f0016a41186a200141c1016a2900002208370300200141f0016a41106a200141a8016a41116a2900002205370300200141f0016a41086a200141b1016a2900002209370300200141286a41086a2009370300200141286a41106a2005370300200141286a41186a2008370300200120012900a90122083703f00120012008370328200141f0016a21020b42002108200141a8016a41086a22034200370300200142003703a80141b1f0c200410d200141a8016a1008200141d0016a41086a2003290300370300200120012903a8013703d001200141003602a801200141d0016a4110200141a8016a100621040240024020012802a8012203417f470d00410421070c010b200120033602f401200120043602f001200141a8016a200141f0016a107620012802a8012207450d0320012902ac01210802402003450d002004102a0b200141d0016a411010090b200141a8016a41086a22034200370300200142003703a80141e6efc2004115200141a8016a1008200141d0016a41086a2003290300370300200120012903a8013703d001200141a8016a200141d0016a411010a7030240024020012d00a8014101460d00200220012900a901370000200141c8006a41086a4200370300200141c8006a41106a4200370300200141c8006a41186a4200370300200241186a200141c1016a290000370000200241106a200141b9016a290000370000200241086a200141b1016a290000370000200142003703480c010b200141d0016a41101009200241186a200141c1016a2900002205370000200241106a200141b9016a2900002209370000200241086a200141b1016a290000220a370000200220012900a901220b370000200141c8006a41086a200a370300200141c8006a41106a2009370300200141c8006a41186a20053703002001200b3703480b0240200641fb01490d00200641857e6a2203450d00411010282202450d04200241086a41002900c6f042370000200241002900bef042370000200241104120102c2202450d0520022003360010200141a8016a41186a22034200370300200141a8016a41106a22044200370300200141a8016a41086a220c4200370300200142003703a80120024114200141a8016a1000200141f0016a41186a2003290300370300200141f0016a41106a2004290300370300200141f0016a41086a200c290300370300200120012903a8013703f0012002102a200141f0016a412010090b200141a8016a41186a22024200370300200141a8016a41106a22034200370300200141a8016a41086a22044200370300200142003703a801200141a8016a1014200141e8006a41186a2002290300370300200141e8006a41106a2003290300370300200141e8006a41086a2004290300370300200120012903a801370368200141f0016a41186a200141286a41186a290300370300200141f0016a41106a200141286a41106a290300370300200141f0016a41086a200141286a41086a290300370300200120012903283703f001200242003703002003420037030020044200370300200142003703a8010240200141f0016a4120200141a8016a1015450d0020014188016a41086a2004290300220537030020014188016a41106a2003290300220937030020014188016a41186a2002290300220a370300200120012903a801220b3703880120042005370300200320093703002002200a3703002001200b3703a8010240024020084220882205a722022008a7460d00200821090c010b200241016a22032002490d082005a74101742204200320032004491bad220942247e2205422088a70d082005a722034100480d080240024020020d002003102821070c010b2007200241246c2003102c21070b2007450d0720084220882205a721020b2007200241246c6a220241003a0000200220012903a801370001200241096a200141b0016a290300370000200241116a200141b8016a290300370000200241196a200141c0016a290300370000200220012f00f0013b0021200241236a200141f2016a2d00003a00002005422086200942ffffffff0f83844280808080107c21080b200020012903283700102000200636020020002001290368370030200041286a200141286a41186a290300370000200041206a200141286a41106a290300370000200041186a200141286a41086a290300370000200041386a200141e8006a41086a290300370000200041c0006a200141e8006a41106a290300370000200041c8006a200141e8006a41186a290300370000200041086a200837020020002007360204200041e8006a200141c8006a41186a290300370000200041e0006a200141c8006a41106a290300370000200041d8006a200141c8006a41086a2903003700002000200129034837005020014190026a24000f0b41c4d1c3004133200141a8016a419cd9c3001038000b41c4d1c3004133200141a8016a419cd9c3001038000b41c4d1c3004133200141a8016a419cd9c3001038000b411041011037000b412041011037000b200341041037000b1031000bb40202067f017e230041206b220224000240024002400240200128020422034104490d0020012802002204280000210520012003417c6a22063602042001200441046a36020020064104490d01200428000421062001200341786a3602042001200441086a360200200241106a2001106d200228021022030d02200041003602080c030b200041003602080c020b200041003602080c010b200241106a41086a280200210720022802142104200241106a2001106d02402002280210450d00200241086a200241106a41086a2802002201360200200220022903102208370300200041106a20073602002000200436020c200020033602082000200636020420002005360200200041146a20083702002000411c6a20013602000c010b200041003602082004450d002003102a0b200241206a24000ba60301067f230041106b22022400200241003602082002420137030020002802002103024002400240410410282204450d0020024284808080c0003702042002200436020020042003360000200028020421050240024020022802042206200228020822046b4104490d00200441046a2103200228020021060c010b200441046a22032004490d03200641017422072003200720034b1b22074100480d030240024020060d002007102821060c010b200228020020062007102c21060b2006450d0220022007360204200220063602000b20022003360208200620046a200536000020002802082104200041106a2802002203200210b40102402003450d0020034105742103034020042002108f01200441206a2104200341606a22030d000b0b200028021421042000411c6a2802002203200210b40102402003450d0020034105742103034020042002108f01200441206a2104200341606a22030d000b0b2002280204210420012802002001280204200228020022032002280208100702402004450d002003102a0b200241106a24000f0b410441011037000b200741011037000b1031000b1300200041043602042000418897c3003602000b3400200041879fc30036020420004100360200200041146a4105360200200041106a41a0a2c300360200200041086a42133702000b34002000418ca2c30036020420004100360200200041146a4105360200200041106a41a0a2c300360200200041086a42133702000bf90101047f230041206b22032400200341106a41086a220442003703002003420037031041a8a0c6004117200341106a1008200341086a200429030037030020032003290310370300410021042003410036021020034110200341106a100621050240024020032802102206417f460d002005450d0020064104490d01200528000021042005102a0b02400240417f200420026a220520052004491b2204418080c002418080f00120011b4b0d00200041046a2004360200410021040c010b200041800c3b0001200041036a41003a0000410121040b200020043a0000200341206a24000f0b41c4d1c3004133200341106a419cd9c3001038000b850201047f230041206b22032400200341106a41086a2204420037030020034200370310418ea0c600411a200341106a1008200341086a200429030037030020032003290310370300410021042003410036021020034110200341106a100621050240024020032802102206417f460d002005450d0020064104490d01200528000021042005102a0b02400240417f2004418094ebdc034180afd0e50220021b2205200120052001491b6a220120012004491b220420054b0d00200041046a2004360200410021040c010b200041800c3b0001200041036a41003a0000410121040b200020043a0000200341206a24000f0b41c4d1c3004133200341106a419cd9c3001038000bef1a04057f017e037f017e230041e0016b220124000240024002400240024002400240024041880110282202450d000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200028020022002802000e1500011402030405060708090a0b0c0d0e0f10111213000b0240024002400240024002400240200041086a280200417f6a220341054b0d004101210420030e06060102030405060b41e4f0c2001032000b200041146a2802002204417f4c0d1b2000410c6a28020021000240024020040d0020014200370360410121050c010b200410282205450d1d20014100360264200120043602600b20012004360264200520002004109a051a20012903602106410221040c040b200041106a2903002106410321040c030b200041146a2802002204417f4c0d192000410c6a28020021000240024020040d0020014200370360410121050c010b200410282205450d1c20014100360264200120043602600b20012004360264200520002004109a051a20012903602106410421040c020b200141e0006a2000410c6a106f2001290264210620012802602105410521040c010b200141e0006a2000410c6a10712001290264210620012802602105410621040b200220063703102002200536020c20022004360208200241003602000c140b10a103000b200141e0006a200041046a1070200241033602002002410c6a200141e8006a280200360200200220012903603702040c120b10bb03000b200141e0006a200041086a10ae02200241086a200141e0006a41e000109a051a200241053602000c100b200141e0006a200041086a10bc0320024106360200200241386a200141e0006a41306a290300370300200241306a200141e0006a41286a290300370300200241286a200141e0006a41206a290300370300200241206a200141e0006a41186a290300370300200241186a200141e0006a41106a290300370300200241106a200141e0006a41086a290300370300200220012903603703080c0f0b200141e0006a41186a200041286a290000370300200141e0006a41106a200041206a290000370300200141e8006a200041186a290000370300200141e0006a41286a200041386a290000370300200141e0006a41306a200041c0006a290000370300200141e0006a41386a200041c8006a290000370300200141e0006a41c8006a200041d8006a290000370300200141e0006a41d0006a200041e0006a290000370300200141e0006a41d8006a200041e8006a2900003703002001200041106a2900003703602001200041306a290000370380012001200041d0006a2900003703a0012000410c6a2802002205417f4c0d10200028020421030240024020050d0041012100410021040c010b20052104200510282200450d140b200020032005109a0521002001200141e0006a41e000109a0521032002200536020c2002200436020820022000360204200241106a200341e000109a051a200241073602000c0e0b200141e0006a200041086a10bd0320024108360200200241306a200141e0006a41286a290300370300200241286a200141e0006a41206a290300370300200241206a200141e0006a41186a290300370300200241186a200141e0006a41106a290300370300200241106a200141e0006a41086a290300370300200220012903603703080c0d0b02400240024002400240024020002d0004417f6a220541034b0d0020050e0401020304010b41c0f1c2001032000b200041106a280200220341ffffff3f712003470d1220034105742204417f4c0d12200041086a2802002100410121054101210702402004450d00200410282207450d170b024020030d0041002104410021030c040b2003410574210420072105034020052000290000370000200541186a200041186a290000370000200541106a200041106a290000370000200541086a200041086a290000370000200541206a2105200041206a2100200441606a22040d000b41012105200341057441606a41057641016a21040c030b200041086a10ba032107410221050c020b200041086a28020021072000410c6a10ba032103410321050c010b200141026a200041046a220541036a2d00003a0000200141e0006a41086a2000411c6a290000370300200141e0006a41106a200041246a2d00003a0000200120052f00013b01002001200041146a29000037036020002d00254100472108200041286a2802002109200041106a28000021042000410c6a2800002103200041086a2800002107410421050b200220053a0004200220012f01003b0005200220043602102002200336020c200220073602082002200129036037021420022009360228200220083a002520024109360200200241076a200141026a2d00003a00002002411c6a200141e8006a290300370200200241246a200141f0006a2d00003a00000c0c0b02400240024002400240024020002d0004417f6a220541034b0d0020050e0401020304010b41c0f1c2001032000b200041106a280200220341ffffff3f712003470d1120034105742204417f4c0d11200041086a2802002100410121054101210702402004450d00200410282207450d170b024020030d0041002104410021030c040b2003410574210420072105034020052000290000370000200541186a200041186a290000370000200541106a200041106a290000370000200541086a200041086a290000370000200541206a2105200041206a2100200441606a22040d000b41012105200341057441606a41057641016a21040c030b200041086a10ba032107410221050c020b200041086a28020021072000410c6a10ba032103410321050c010b200141026a200041046a220541036a2d00003a0000200141e0006a41086a2000411c6a290000370300200141e0006a41106a200041246a2d00003a0000200120052f00013b01002001200041146a29000037036020002d00254100472108200041286a2802002109200041106a28000021042000410c6a2800002103200041086a2800002107410421050b200220053a0004200220012f01003b0005200220043602102002200336020c200220073602082002200129036037021420022009360228200220083a00252002410a360200200241076a200141026a2d00003a00002002411c6a200141e8006a290300370200200241246a200141f0006a2d00003a00000c0b0b200141e0006a200041086a10d3022002410b360200200241c0006a200141e0006a41386a290300370300200241386a200141e0006a41306a290300370300200241306a200141e0006a41286a290300370300200241286a200141e0006a41206a290300370300200241206a200141e0006a41186a290300370300200241186a200141e0006a41106a290300370300200241106a200141e0006a41086a290300370300200220012903603703080c0a0b200141e0006a200041046a10be03200241046a200141e0006a41c400109a051a2002410c3602000c090b200028020421002002410d360200200220003602040c080b2000410c6a2802002205417f4c0d09200028020421030240024020050d0041012100410021040c010b20052104200510282200450d100b200020032005109a0521002002200536020c20022004360208200220003602042002410e3602000c070b024002400240024002400240200041086a280200417f6a220541024b0d0020050e03010203010b418486c2001032000b200041386a2903002106200041306a290300210a41012105024002402000410c6a2d00004101460d00200141e8006a2000411c6a290200370300200141e0006a41106a200041246a290200370300200141f8006a2000412c6a2d00003a00002001200041146a29020037036020002f000d2000410f6a2d0000411074722104200041106a2802002103410021050c010b200041106a28020021030b200141186a200141e0006a41186a280200360200200141106a200141e0006a41106a290300370300200141086a200141e0006a41086a29030037030020012001290360370300410121000c030b2000410c6a28020022054108762104410221000c010b2000410c6a28020022054108762104410321000b0b2002200a3703302002200336021020022000360208200220012903003702142002410f360200200241386a200637030020022004410874200541ff01717236020c2002411c6a200141086a290300370200200241246a200141106a2903003702002002412c6a200141186a2802003602000c060b200141e0006a200041086a10bf03200241086a200141e0006a418001109a051a200241103602000c050b200141e0006a200041046a10c003200241113602002002412c6a20014188016a280200360200200241246a20014180016a2903003702002002411c6a200141f8006a290300370200200241146a200141f0006a2903003702002002410c6a200141e8006a290300370200200220012903603702040c040b200141e0006a200041046a10af02200241046a200141e0006a41e400109a051a200241123602000c030b10c103000b10d501000b200041086a290300210620024102360200200220063703080b200141e0016a240020020f0b41880141081037000b1036000b200441011037000b200441011037000b200541011037000b200441011037000b200441011037000b200541011037000b0a0041acb4c3001032000b910c03047f017e057f230041206b2202240002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2203410c4b0d0020030e0d0102030405060708090a0b0c0d010b41e0ffc4001032000b4101210302400240200141046a2d00004101460d002002411e6a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b011c20022001410c6a290000370300200141086a2800002104410021030c010b200141086a28020021040b200041286a2001290328370300200041046a20033a0000200041056a20022f011c3b0000200041086a20043602002000410c6a2002290300370200200041306a200141306a290300370300200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a28020036020020012d00012101200041013a0000200020013a00010c0c0b200041023a0000200041106a200141106a290300370300200041086a200141086a2903003703000c0b0b200041033a0000200041106a200141106a290300370300200041086a200141086a2903003703000c0a0b200041043a00000c090b200041053a0000200041106a200141106a290300370300200041086a200141086a2903003703000c080b2001410c6a2802002205ad42247e2206422088a70d082006a72204417f4c0d08200141046a28020021030240024020040d00410421070c010b200410282207450d0a0b0240024020050d00410021040c010b200541246c2108410021042002411e6a21092007210103400240024020032d00004101460d002009200341036a2d00003a0000200341046a280000210a200341016a2f0000210b200241086a200341106a290000370300200241106a200341186a290000370300200241186a200341206a2d00003a00002002200b3b011c2002200341086a2900003703004100210b0c010b200341046a280200210a4101210b0b200341246a21032001200b3a0000200141046a200a360200200141016a20022f011c3b0000200141036a20092d00003a0000200141086a2002290300370200200141106a200241086a290300370200200141186a200241106a290300370200200141206a200241186a280200360200200141246a2101200441016a21042008415c6a22080d000b0b200041063a00002000410c6a2004360200200041086a2005360200200041046a20073602000c070b200041073a00000c060b200041083a0000200020012d00013a00010c050b4101210302400240200141046a2d00004101460d002002411e6a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b011c20022001410c6a290000370300200141086a2800002101410021030c010b200141086a28020021010b200041093a0000200041046a20033a0000200041056a20022f011c3b0000200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c040b2000410a3a0000200041046a200141046a2802003602000c030b2000410b3a00000c020b2000410c3a00000c010b2001410c6a280200220841ffffff3f712008470d0120084105742203417f4c0d01200141046a28020021010240024020030d004101210a0c010b20031028220a450d040b0240024020080d0041002108410021010c010b20084105742104200a2103034020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200341206a2103200141206a2101200441606a22040d000b200841057441606a41057641016a21010b2000410d3a00002000410c6a2001360200200041086a2008360200200041046a200a3602000b200241206a24000f0b1036000b200441041037000b200341011037000bab0701017f024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a220241104b0d0020020e110102030405060708090a0b0c0d0e0f1011010b41e8d0c5001032000b41880110282202450d102002200141046a28020010cf03200041046a2002360200200041013a0000200041106a200141106a290300370300200041086a200141086a2903003703000f0b200041023a0000200041046a200141046a2802003602000f0b200041033a0000200041046a200141046a280200360200200041026a200141026a2d00003a0000200020012d00014101713a00010f0b200041043a0000200041046a200141046a280200360200200041026a200141026a2d00003a0000200020012d00014101713a00010f0b200041053a0000200041046a200141046a2802003602000f0b41880110282202450d0c2002200141046a28020010cf03200041063a0000200041046a20023602000f0b41880110282202450d0c2002200141046a28020010cf03200041073a0000200041046a20023602000f0b41880110282202450d0c2002200141046a28020010cf03200041083a0000200041046a20023602000f0b200041093a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2902003702000f0b2000410a3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b2000410b3a0000200041046a200141046a2802003602000f0b2000410c3a00002000410c6a2001410c6a280200360200200041046a200141046a2902003702000f0b2000410d3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b2000410e3a00000f0b2000410f3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041103a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000f0b200041113a00000f0b41880141081037000b41880141081037000b41880141081037000b41880141081037000bb60401047f0240024002400240024020012d0000417f6a220241034b0d0020020e0401020304010b4188b5c3001032000b200041013a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041023a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041033a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000f0b024002402001410c6a280200220341ffffff3f712003470d0020034105742202417f4c0d00200141046a28020021010240024020020d00410121040c010b200210282204450d020b0240024020030d0041002103410021010c010b2003410574210520042102034020022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a290000370000200241206a2102200141206a2101200541606a22050d000b200341057441606a41057641016a21010b200041043a00002000410c6a2001360200200041086a2003360200200041046a20043602000f0b1036000b200241011037000b8d0c07037f017e017f017e017f017e017f230041c0006b220224000240024002400240024002400240024002400240024020012d0000417f6a220341044b0d0020030e050102030405010b41d093c4001032000b200041f9006a2002280020360000200041086a200141086a290300370300200041fc006a200241236a280000360000200041106a200141106a290300370300200041186a200141186a290300370300200041206a200141206a290300370300200041286a200141286a290300370300200041306a200141306a290300370300200041386a200141386a290300370300200041c0006a200141c0006a290300370300200041c8006a200141c8006a290300370300200041d0006a200141d0006a290300370300200041d8006a200141d8006a290300370300200041e0006a200141e0006a290300370300200041e8006a200141e8006a290300370300200041f0006a200141f0006a290300370300200041f8006a200141f8006a2d00004100473a0000200041013a00000c040b2001410c6a2802002203417f4c0d04200141046a2802002104200141106a29030021050240024020030d0041002101410121060c010b20032101200310282206450d060b200620042003109a0521042000410c6a2003360200200041086a2001360200200041046a2004360200200041106a2005370300200041023a00000c030b4101210402400240200141046a2d00004101460d00200241026a200141076a2d00003a0000200241206a41086a200141146a290000370300200241306a2001411c6a290000370300200241386a200141246a2d00003a00002002200141056a2f00003b010020022001410c6a290000370320200141086a2800002106410021040c010b200141086a28020021060b200141306a2802002203417f4c0d03200141c0006a29030021052001290338210720012802282108200129034821090240024020030d00410021014101210a0c010b2003210120031028220a450d060b200a20082003109a052108200041c0006a2005370300200041386a2007370300200041046a20043a0000200041086a2006360200200041c8006a2009370300200041306a20033602002000412c6a2001360200200041286a2008360200200041056a20022f01003b0000200041076a200241026a2d00003a00002000410c6a2002290320370200200041146a200241206a41086a2903003702002000411c6a200241306a290300370200200041246a200241386a280200360200200041033a00000c020b200141386a2903002105200141306a2903002107200141c0006a2903002109200241386a200141196a290000370300200241306a200141116a290000370300200241286a200141096a290000370300200220012900013703202001412c6a2802002203417f4c0d02200141246a28020021010240024020030d0041012104410021060c010b20032106200310282204450d060b200420012003109a052101200041386a2005370300200041306a2007370300200041c0006a20093703002000412c6a2003360200200041286a2006360200200041246a2001360200200041043a000020002002290320370001200041096a200241286a290300370000200041116a200241306a290300370000200041196a200241386a2903003700000c010b200241186a2204200141196a290000370300200241106a2206200141116a290000370300200241086a2208200141096a29000037030020022001290001370300410021030240200141216a2d00004101470d00200241206a41186a2001413a6a290000370300200241206a41106a200141326a290000370300200241206a41086a2001412a6a2900003703002002200141226a290000370320410121030b20002002290300370001200041216a20033a0000200041226a2002290320370000200041196a2004290300370000200041116a2006290300370000200041096a20082903003700002000412a6a200241206a41086a290300370000200041326a200241206a41106a2903003700002000413a6a200241206a41186a290300370000200041053a00000b200241c0006a24000f0b1036000b200341011037000b200341011037000b200341011037000b920501047f230041206b2202240002400240024002400240024002402001280200417f6a220341024b0d0020030e03010203010b41dc9cc4001032000b41880110282203450d032003200128020410cf0320004101360200200020033602040c020b410121030240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002101410021030c010b200141086a28020021010b200020033a0004200020022f011c3b000520004102360200200041086a20013602002000410c6a2002290300370200200041076a2002411c6a41026a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c010b410121040240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002105410021040c010b200141086a28020021050b41880110282203450d022003200128022810cf03200020043a0004200041086a2005360200200041286a200336020020004103360200200020022f011c3b0005200041076a2002411e6a2d00003a00002000410c6a2002290300370200200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000b200241206a24000f0b41880141081037000b41880141081037000b0a0041b095c4001032000bad0301047f230041106b22022400024002400240024002400240024002400240024002402001280200417f6a220341054b0d0020030e06010203040506010b41e4f0c2001032000b200041013602000c050b2001410c6a2802002203417f4c0d05200128020421010240024020030d0041002104410121050c010b20032104200310282205450d070b200520012003109a0521012000410c6a2003360200200041086a200436020020002001360204200041023602000c040b20004103360200200041086a200141086a2903003703000c030b2001410c6a2802002203417f4c0d03200128020421010240024020030d0041012104410021050c010b20032105200310282204450d060b200420012003109a0521012000410c6a2003360200200041086a200536020020002001360204200041043602000c020b2002200141046a106f200041053602002000410c6a200241086a280200360200200020022903003702040c010b2002200141046a1071200041063602002000410c6a200241086a280200360200200020022903003702040b200241106a24000f0b1036000b200341011037000b200341011037000bdd0301047f024002400240024002400240024020012d0000417f6a220241034b0d0020020e0401020304010b41c0f1c2001032000b2001410c6a280200220341ffffff3f712003470d0320034105742202417f4c0d03200141046a28020021010240024020020d00410121040c010b200210282204450d050b0240024020030d0041002103410021010c010b2003410574210520042102034020022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a290000370000200241206a2102200141206a2101200541606a22050d000b200341057441606a41057641016a21010b200041013a00002000410c6a2001360200200041086a2003360200200041046a20043602000f0b200141046a10ba032101200041023a0000200041046a20013602000f0b200141046a2802002102200041086a200141086a10ba03360200200041046a2002360200200041033a00000f0b200041043a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a280200360200200041216a200141216a2d00004100473a00000f0b1036000b200241011037000b3400200041c5b6c30036020420004100360200200041146a4102360200200041106a41ccb6c300360200200041086a42073702000be40201047f230041c0006b2202240002400240410f10282203450d00200341076a4100290092b4433700002003410029008bb4433700002003410f411e102c2203450d012003200036000f200241206a41186a22004200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034113200241206a1000200241186a2000290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002003102a200128020021042001280208210320024100360228200242013703202003200241206a10b40102402003450d00200341057421002004210303402003200241206a108f01200341206a2103200041606a22000d000b0b2002280224210320024120200228022022002002280228100702402003450d002000102a0b0240200141046a280200450d002004102a0b200241c0006a24000f0b410f41011037000b411e41011037000b8a1401037f200141046a2802002102200141086a28020021030240024002400240024002400240024002400240024002400240024002400240024020002d00004101460d000240024020022003460d00200128020021020c010b200341016a22022003490d11200341017422042002200420024b1b22044100480d110240024020030d002004102821020c010b200128020020032004102c21020b2002450d0220012002360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200220036a41003a00000240024002400240024002400240024020002d00010e080001020304050607000b02400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d18200341017422022000200220004b1b22024100480d180240024020030d002002102821000c010b200128020020032002102c21000b2000450d0a20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000f0b02400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d17200341017422022000200220004b1b22024100480d170240024020030d002002102821000c010b200128020020032002102c21000b2000450d0a20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41013a00000f0b02400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d16200341017422022000200220004b1b22024100480d160240024020030d002002102821000c010b200128020020032002102c21000b2000450d0a20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41023a00000f0b02400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d15200341017422022000200220004b1b22024100480d150240024020030d002002102821000c010b200128020020032002102c21000b2000450d0a20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41033a00000f0b02400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d14200341017422022000200220004b1b22024100480d140240024020030d002002102821000c010b200128020020032002102c21000b2000450d0a20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41043a00000f0b02400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d13200341017422022000200220004b1b22024100480d130240024020030d002002102821000c010b200128020020032002102c21000b2000450d0a20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41053a00000f0b02400240200141046a28020020042802002203460d00200128020021000c010b200341016a22002003490d12200341017422022000200220004b1b22024100480d120240024020030d002002102821000c010b200128020020032002102c21000b2000450d0a20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41063a00000f0b02400240200141046a28020020042802002203460d00200128020021020c010b200341016a22022003490d11200341017422042002200420024b1b22044100480d110240024020030d002004102821020c010b200128020020032004102c21020b2002450d0a20012002360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200220036a41073a000002400240200141046a28020020042802002203460d00200128020021020c010b200341016a22022003490d11200341017422042002200420024b1b22044100480d110240024020030d002004102821020c010b200128020020032004102c21020b2002450d0b20012002360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200220036a20002d00023a00000f0b0240024020022003460d00200128020021020c010b200341016a22022003490d10200341017422042002200420024b1b22044100480d100240024020030d002004102821020c010b200128020020032004102c21020b2002450d0b20012002360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200220036a41013a0000024020002d0001220341024b0d0002400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d13200341017422022000200220004b1b22024100480d130240024020030d002002102821000c010b200128020020032002102c21000b2000450d0f20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000f0b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d12200341017422022000200220004b1b22024100480d120240024020030d002002102821000c010b200128020020032002102c21000b2000450d0f20012000360200200141046a2002360200200141086a28020021030b200141086a200341016a360200200020036a41013a00000f0b02400240200141046a280200200141086a2802002203460d00200128020021020c010b200341016a22022003490d11200341017422042002200420024b1b22044100480d110240024020030d002004102821020c010b200128020020032004102c21020b2002450d0f20012002360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200220036a41023a000002400240200141046a28020020042802002203460d00200128020021020c010b200341016a22022003490d11200341017422042002200420024b1b22044100480d110240024020030d002004102821020c010b200128020020032004102c21020b2002450d1020012002360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200220036a20002d00023a00000b0f0b200441011037000b200241011037000b200241011037000b200241011037000b200241011037000b200241011037000b200241011037000b200241011037000b200441011037000b200441011037000b200441011037000b200241011037000b200241011037000b200441011037000b200441011037000b1031000bac64070e7f017e047f017e047f0f7e087f230041900b6b220124004100210241002103410421040240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402000410c6a28020041246c2205450d00200028020421064104210441002102410021030340024020062d00004101470d00200641106a2802002207417f4c0d1a200641086a2802002108200641016a28000021090240024020070d004101210a4100210b0c010b2007210b20071028220a450d040b200a20082007109a05210a20014188076a41026a220c200141f0056a41026a2d00003a0000200141a0086a41086a220d200141c0096a41086a290200370300200120012f00f0053b018807200120012902c0093703a008024020022003470d00200241016a22082002490d1d2002410174220e2008200e20084b1b2203ad42247e220f422088a70d1d200fa722084100480d1d0240024020020d002008102821040c010b2004200241246c2008102c21040b2004450d050b2004200241246c6a220841013a000020082009360001200820073600102008200b36000c2008200a360008200820012f0188073b0005200841076a200c2d00003a0000200820012903a0083702142008411c6a200d290300370200200241016a21020b200641246a21062005415c6a22050d000b0b200141003602a0084188e8c2004110200141a0086a4104100720014188076a41086a22064200370300200142003703880741d9efc200410d20014188076a1008200141f0056a41086a2208200629030037030020012001290388073703f0052001200028020022073602a008200141f0056a4110200141a0086a4104100720064200370300200142003703880741b1f0c200410d20014188076a10082008200629030037030020012001290388073703f005200141103602a4082001200141f0056a3602a00820042002200141a0086a10e102200642003703002001420037038807419df2c200411120014188076a10082008200629030037030020012001290388073703f005200141103602a4082001200141f0056a3602a008200041106a2205200141a0086a10f002411010282206450d02200641086a41002900c6f042370000200641002900bef042370000200641104120102c2208450d0320082007417f6a360010200141d8046a41186a22064200370300200141d8046a41106a22074200370300200141d8046a41086a22094200370300200142003703d80420084114200141d8046a100020014188076a41186a200629030037030020014188076a41106a200729030037030020014188076a41086a22062009290300370300200120012903d804370388072008102a200141203602a408200120014188076a3602a0082005200141a0086a10f00220064200370300200142003703880741e6efc200411520014188076a1008200141f0056a41086a2208200629030037030020012001290388073703f005200141103602a4082001200141f0056a3602a008200041d0006a200141a0086a10f00220064200370300200142003703880741aef2c200411520014188076a10082008200629030037030020012001290388073703f005200141a0086a200141f0056a10a903024020012802a40822070d00200141013602d804410021094100210641002105410021080c060b200120073602d804200141ac086a280200210620012802a008210920012802a8082105024020012903a808220f422088a741d1004f0d00200fa721080c060b200141a0086a41186a220a200041286a290000370300200141a0086a41106a220b200041206a290000370300200141a0086a41086a220c200041186a290000370300200120002900103703a00820062009411874220941187522084d0d04200720084105746a220820012903a008370000200841186a200a290300370000200841106a200b290300370000200841086a200c290300370000200941808080086a41187541d1006f21090c060b200741011037000b200841041037000b411041011037000b412041011037000b41c4f2c200200820061034000b200141a0086a41186a220a200041286a290000370300200141a0086a41106a220b200041206a290000370300200141a0086a41086a220c200041186a290000370300200120002900103703a008024020062008470d0020052006470d00200641016a22082006490d14200641017422072008200720084b1b220541ffffff3f712005470d14200541057422074100480d140240024020060d002007102821080c010b20012802d80420064105742007102c21080b2008450d02200120083602d8040b20012802d804220720064105746a220820012903a008370000200841086a200c290300370000200841106a200b290300370000200841186a200a290300370000200641016a21060b20014188076a41086a22084200370300200142003703880741aef2c200411520014188076a1008200141f0056a41086a200829030037030020012001290388073703f0050240024020070d00200141f0056a411010090c010b410110282208450d0220014281808080103702a408200120083602a008200820093a00002006200141a0086a10b40102402006450d00200641057421082007210603402001200141a0086a3602c0092006200141c0096a10c801200641206a2106200841606a22080d000b0b20012802a4082106200141f0056a411020012802a008220820012802a808100702402006450d002008102a0b2007450d002005450d002007102a0b20014188076a41086a22084200370300200142003703880741d4f2c200410d20014188076a1008200141f0056a41086a2206200829030037030020012001290388073703f005200141f0056a4110100920084200370300200142003703880741eea0c600411120014188076a10082006200829030037030020012001290388073703f005200141f0056a41101009411210282206450d02200641106a41002f00f1f2423b0000200641086a41002900e9f242370000200641002900e1f242370000200141d8046a41186a22074200370300200141d8046a41106a22054200370300200141d8046a41086a22094200370300200142003703d80420064112200141d8046a100020014188076a41186a200729030037030020014188076a41106a200529030037030020082009290300370300200120012903d804370388072006102a20014188076a4120100e2000280200211010eb0220104105490d07200141f0056a41086a22064200370300200142003703f0054193cdc2004111200141f0056a1008200141a0086a41086a2006290300370300200120012903f0053703a008200141003602c009200141a0086a4110200141c0096a100621060240024020012802c0092208417f460d002006450d002001200836028c072001200636028807200141c0096a20014188076a107b20012802c009220a450d0520012902c409210f2008450d012006102a0c010b4104210a4200210f0b2010417b6a2105200a200f422088a7220b41c4006c22066a21090240200641cd014f0d0041002106200a21080c060b200a41d0016a21084100210603400240200841b07e6a22072d00004101460d00200841b47e6a28020020054f0d080b0240200741c4006a2d00004101460d00200841f87e6a2802002005490d00200641016a21060c080b024020074188016a2d00004101460d00200841bc7f6a2802002005490d00200641026a21060c080b02400240200741cc016a2d00004101460d00200828020020054f0d010b20084190026a2108200641046a2106200920074190026a6b41cc014d0d060c010b0b200641036a21060c060b200741011037000b410141011037000b411241011037000b41c4d1c3004133200141f0056a419cd9c3001038000b200841b07e6a21080b20082009460d00200a200b41c4006c6a21070340024020082d00004101460d00200841046a28020020054f0d020b200641016a21062007200841c4006a2208470d000b0b2006200b4b0d01200f42ffffffff0f83210f0240200b20066b2208450d0002402006450d00200a200a200641c4006c6a200841c4006c109b051a0b2008ad422086200f84210f0b200141f0056a41086a22064200370300200142003703f0054193cdc2004111200141f0056a1008200141a0086a41086a2006290300370300200120012903f0053703a008200141c0096a200a200f422088a7109202200141a0086a411020012802c009220820012802c8091007200fa72106024020012802c409450d002008102a0b2006450d00200a102a0b200141003a00c009200141f0056a41086a22064200370300200142003703f00541c8fbc5004117200141f0056a1008200141a0086a41086a22082006290300370300200120012903f0053703a008200141a0086a4110200141c0096a41011007200141a0086a10f801412410282206450d01200620012903a00837000020064114360220200641186a200141a0086a41186a290300370000200641106a200141a0086a41106a290300370000200641086a200829030037000020014281808080103702c409200120063602c009200141c0096a10f901201010ea0202400240201041809c3170450d0020014188076a21110c010b200141f0056a41086a22064200370300200142003703f00541d590c600411f200141f0056a100820014188076a41086a2006290300370300200120012903f00537038807200141003602a00820014188076a4110200141a0086a1006210602400240024020012802a0082208417f460d002006450d002008450d0120062d000021082006102a20014188076a4110100920084102460d0020084101710d020b20014188076a2111201010c803450d02201010c9031a0c020b41c4d1c3004133200141f0056a419cd9c3001038000b20014188076a2111201010c903450d00201010c8031a0b200141f0056a41086a22064200370300200142003703f00541c290c6004113200141f0056a100820014188076a41086a2006290300370300200120012903f0053703880741002106200141003602a00820114110200141a0086a10062108024020012802a0082207417f460d002008450d0020074104490d03200828000021062008102a0b200141f0056a41086a22084200370300200142003703f00541a990c6004119200141f0056a100820014188076a41086a2008290300370300200120012903f0053703880741002108200141003602a00820114110200141a0086a10062107024020012802a0082205417f460d002007450d0020054104490d04200728000021082007102a0b02400240200620084f0d0002400340200141c0096a200610ca0320012802c00922074113470d012008200641016a2206470d000c020b0b20014188076a200141c0096a410472419401109a051a200141f0056a20014188076a419401109a051a200141d8046a200141f0056a419401109a051a200120073602a80820012006ad220f3703a008200141ac086a200141d8046a419401109a052105200141b0096a2802002010460d01200141a8086a106a0b4108211241002106410021130c080b200141c0036a2005419401109a051a200141a0086a200141c0036a419401109a051a41a00110282212450d04201220073602082012200f3703002012410c6a200141a0086a419401109a051a02400240200641016a220720084f0d000340200141c0096a200710ca0320012802c00922054113470d022008200741016a2207470d000b0b41012106410121130c080b20014188076a200141c0096a410472220c419401109a051a200141f0056a20014188076a419401109a051a200141d8046a200141f0056a419401109a051a200120053602a80820012007ad220f3703a008200141a0086a410c6a200141d8046a419401109a05210a41012106200141a8086a210b200141b0096a2802002010470d06200741016a2107200141c0036a200a419401109a051a41012106410121130340200141a0086a200141c0036a419401109a051a024020132006470d00200641016a22092006490d0c2006410174220d2009200d20094b1b2213ad42a0017e2214422088a70d0c2014a722094100480d0c024002402006450d002012200641a0016c2009102c21120c010b2009102821120b2012450d070b2012200641a0016c6a220920053602082009200f3703002009410c6a200141a0086a419401109a051a200641016a2106200720084f0d0802400340200141c0096a200710ca03024020012802c00922054113460d0020014188076a200c419401109a051a200141f0056a20014188076a419401109a051a200141d8046a200141f0056a419401109a051a200120053602a80820012007ad220f3703a008200a200141d8046a419401109a05210920012802b0092010470d02200741016a2107200141c0036a2009419401109a051a0c030b2008200741016a2207470d000c0a0b0b0b200b106a0c070b41e4e8c5001032000b412441041037000b41c4d1c3004133200141f0056a419cd9c3001038000b41c4d1c3004133200141f0056a419cd9c3001038000b41a00141081037000b200941081037000b200b106a410121130b2012200641a0016c6a2115024020060d00201221160c020b20014188076a4104722106200141a0086a410472211720014198026a41086a21182012211603402016280200210520162802082108200141a0086a2016410c6a419401109a051a201641a0016a211620084113460d02200141c0096a200141a0086a419401109a051a200120083602a0082017200141c0096a419401109a051a200141f0056a200510cb0320012802f005210b0240024020012802f80522080d00420021194200211a4200211b4200211c4200211d4200211e0c010b200841057421094200211d200b21084200211e4200211b4200211c420021194200211a034020014198036a2008109d0220014198036a41086a2903002114200129039803210f20062008290000370000200641086a200841086a290000370000200641106a200841106a290000370000200641186a200841186a290000370000200120053602880720014190036a20014188076a10cc0320012d00900341017121070240024020012d009103220a0d00200141d0026a200f2014420a420010a00520012903d002221f210f200141d0026a41086a290300222021140c010b200141f0026a20144200200aad221f4200109f0520014180036a200f4200201f4200109f05200141e0026a42004200200f4200109f05427f20014180036a41086a290300221f20012903f00220012903e0027c7c222020012903f80220012903e802844200522020201f5472220a1b2120427f200129038003200a1b211f0b200841206a21084200202020071b201c7c4200201f20071b2221201b7c221b202154ad7c211c2020420020071b201a7c201f420020071b221f20197c2219201f54ad7c211a2014201e7c200f201d7c221d200f54ad7c211e200941606a22090d000b0b024020012802f405450d00200b102a0b200141f0056a200510cb0320012802f00521000240024020012802f80522080d004200212142002122420021234200212442002120420021250c010b2008410574210942002120200021084200212542002123420021244200212142002122034020062008290000370000200641086a200841086a2207290000370000200641106a200841106a220a290000370000200641186a200841186a220b2900003700002001200536028807200141c8026a20014188076a10cc0320012d00c802210c20012d00c902210d20014188076a41186a200b29000037030020014188076a41106a200a29000037030020014188076a41086a20072900003703002001200829000037038807200141a8026a200520014188076a200d411010cd03200141a8026a41186a29030020257c20012903b802220f20207c2220200f54ad7c21254200200141a8026a41086a290300220f200c41017122071b20247c420020012903a802221420071b221f20237c2223201f54ad7c2124200f420020071b20227c2014420020071b220f20217c2221200f54ad7c2122200841206a2108200941606a22090d000b0b024020012802f405450d002000102a0b20014198026a10a1022018290300210f2001290398022114024002402020201d7c221f4202882025201e7c201f202054ad7c2220423e8684221d2020420288221e84500d00201d201f85201e20208584500d00410021080240034020014188026a201f2020200841046a41fe0071109e05200841026a2108200129038802221d20014188026a41086a290300221e84500d01201d201f85201e2020858450450d000b0b200141f8016a201f2020200841fe0071109e0520012903f801200141f8016a41086a29030084211d4200211e024020080d00201d420052ad211d0c020b201d420052ad211d0340200141d8016a201f202041002008417e6a2207200720084b1b220841ff0071109e05200141e8016a201d42018622264201842225201e420186201d423f8884221e2025201e109f052026202520012903e80120012903d80156200141e8016a41086a290300221d200141d8016a41086a290300222756201d2027511b1b211d20080d000c020b0b4200211e201f202084420052ad211d0b024002402014420288200f423e8684221f200f420288222084500d00201f2014852020200f8584500d004100210802400340200141c8016a2014200f200841046a41fe0071109e05200841026a210820012903c801221f200141c8016a41086a290300222084500d01201f2014852020200f858450450d000b0b200141b8016a2014200f200841fe0071109e0520012903b801200141b8016a41086a29030084211f42002120024020080d00201f420052ad211f0c020b201f420052ad211f034020014198016a2014200f41002008417e6a2207200720084b1b220841ff0071109e05200141a8016a201f420186222642018422252020420186201f423f8884222020252020109f052026202520012903a80120012903980156200141a8016a41086a290300221f20014198016a41086a290300222756201f2027511b1b211f20080d000c020b0b420021202014200f84420052ad211f0b02400240024002400240201d201e8450450d004100210b0c010b2024201c7c2023201b7c2214202354ad7c21232022201a7c202120197c220f202154ad7c212102400240024020012d00b0090e03010200010b200f201456202120235620212023511b210b0c020b0340200141c8006a20142023201d201e10a005201f22192020221a844200510d04200141c8006a41086a290300211f20012903482120200141386a200f20212019201a10a0054101210b20202001290338221b54201f200141386a41086a290300222554201f20255122081b0d020240201b2020542025201f5420081b450d004100210b0c030b200141286a2020201f201d201e109f05200141186a201b20252019201a109f050240200f2001290318221f7d22202021200141186a41086a2903007d200f201f54ad7d222584500d002023200141286a41086a2903007d211b20142001290328220f5421082014200f7d211f201d210f201e21212020211d2025211e20192114201a2123201f201b2008ad7d222084500d030c010b0b4100210b0c010b0340201e2125201d2119201f2020844200510d02200141f8006a200f20212019202510a00520014188016a20142023201f202010a0054101210b200129038801221a2001290378221b5420014188016a41086a290300221d200141f8006a41086a290300221e54201d201e5122081b0d010240201b201a54201e201d5420081b450d004100210b0c020b200141e8006a201a201d201f2020109f05200141d8006a201b201e20192025109f050240200f2001290358221d7d221e2021200141d8006a41086a2903007d200f201d54ad7d221a8450450d004100210b0c020b2023200141e8006a41086a2903007d211b20142001290368220f5421082014200f7d211d201f210f20202121201e211f201a21202019211420252123201d201b2008ad7d221e844200520d000b0b20014188076a200510cb032001280288072128200128028c0721292001280290072208450d0220282008410574222a6a212b2028210802400340200141f0056a41186a2207200841186a220c290000370300200141f0056a41106a2209200841106a220d290000370300200141f0056a41086a220a200841086a2200290000370300200120082900003703f0052008290000210f200641186a222c200c2900003700002006200f370000200641086a222d2000290000370000200641106a222e200d2900003700002001200536028807200141106a20014188076a10cc0320012d0011210e20012d0010212f20014188076a41186a220c200729030037030020014188076a41106a220d200929030037030020014188076a41086a2200200a290300370300200120012903f005370388070240200b202f41017145734101470d00200841206a21080c020b200841206a2108202a41606a222a0d000c040b0b0340200141d8046a41186a200c290300220f370300200141d8046a41106a200d2903002214370300200141d8046a41086a2000290300221f370300200120012903880722203703d804200c200f370300200d20143703002000201f370300200142e4cab5fbb6ccdcb0e3003703a8032001202037038807200141a8036a20014188076a200e41187441187541027441f48fc6006a2802004180de346c20106a10a8022008202b460d03024003402007200841186a220e2900003703002009200841106a222f290000370300200a200841086a222a290000370300200120082900003703f0052001200536028807202a290000210f202f29000021142008290000211f202c200e290000370000202e2014370000202d200f3700002006201f370000200141086a20014188076a10cc0320012d0009210e20012d0008212f200c2007290300370300200d20092903003703002000200a290300370300200120012903f00537038807200b202f41017145730d01202b200841206a2208470d000c050b0b200841206a21080c000b0b41f895c1001032000b41f895c1001032000b02402029450d002028102a0b200510ce0302400240200b0d00200141053a009007200141053a00880720012005360294074101410020014188076a10cc01200141f0056a41086a22084200370300200142003703f00541c290c6004113200141f0056a100820014188076a41086a2008290300370300200120012903f005370388072001200541016a3602f00520114110200141f0056a41041007200141a0086a106a0c010b2001200536029407200141043a009007200141053a0088074101410020014188076a10cc01024020012802ac092207450d00200141f0056a200141a0086a418801109a051a200120053602f80602400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240411710282208450d002008410f6a41002900918945220f370000200841086a410029008a89452214370000200841002900828945221f37000020084117412e102c2208450d012008200720106a2200360017200141d8046a41186a22074200370300200141d8046a41106a22094200370300200141d8046a41086a220a4200370300200142003703d8042008411b200141d8046a100020014188076a41186a220e200729030037030020014188076a41106a222f200929030037030020014188076a41086a220c200a290300370300200120012903d804370388072008102a200141003602d80420014188076a4120200141d8046a1006210b0240024020012802d8042208417f470d00200141003602e004200142013703d8044100200141d8046a10b40120012802e004210820012802dc04210d20012802d804210b0c010b2008210d0b200120083602b8032001200d3602b4032001200b3602b003024002400240024002402008450d00200141d8046a200b2008410110d60220012802d8044101460d0420012802dc04212a20012802e404220820012802e004220b460d0320012802b8032008200b6b6a220d4190016a222c417f4c0d1f202c0d014101212d0c020b4101200141b0036a10b40120012802b403210b20012802b8032108024020012802f0054113470d0002400240200b2008460d0020012802b003210b0c010b200841016a220b2008490d222008410174220d200b200d200b4b1b220d4100480d220240024020080d00200d1028210b0c010b20012802b0032008200d102c210b0b200b450d082001200d3602b4032001200b3602b00320012802b80321080b2001200841016a3602b803200b20086a41003a00000c150b02400240200b2008460d0020012802b003210b0c010b200841016a220b2008490d212008410174220d200b200d200b4b1b220d4100480d210240024020080d00200d1028210b0c010b20012802b0032008200d102c210b0b200b450d082001200d3602b4032001200b3602b00320012802b80321080b2001200841016a3602b803200b20086a41013a0000200141f0056a200141b0036a10eb01200141f0056a4188016a280200210d0240024020012802b403220b20012802b80322086b4104490d0020012802b003210b0c010b200841046a222a2008490d21200b4101742208202a2008202a4b1b22084100480d2102400240200b0d0020081028210b0c010b20012802b003200b2008102c210b0b200b450d09200120083602b4032001200b3602b00320012802b80321080b2001200841046a3602b803200b20086a200d3600000c140b202c1028222d450d080b2001202c3602dc0a2001202d3602d80a2001200d3602e00a2001200141d80a6a3602d804202a200141d8046a200810d701200d2008490d0820012802e00a222a200d490d0920012802b803222a200b490d0a20012802d80a212c20012802b003212d2001200d20086b220d3602e80a2001202a200b6b222a3602ec0a200d202a470d0b202c20086a202d200b6a200d109a051a20012802dc0a210b20012802e00a21080240024020012802f0054113470d0002400240200b2008460d0020012802d80a210b0c010b200841016a220b2008490d212008410174220d200b200d200b4b1b220d4100480d210240024020080d00200d1028210b0c010b20012802d80a2008200d102c210b0b200b450d0f2001200d3602dc0a2001200b3602d80a20012802e00a21080b2001200841016a3602e00a200b20086a41003a00000c010b02400240200b2008460d0020012802d80a210b0c010b200841016a220b2008490d202008410174220d200b200d200b4b1b220d4100480d200240024020080d00200d1028210b0c010b20012802d80a2008200d102c210b0b200b450d0f2001200d3602dc0a2001200b3602d80a20012802e00a21080b2001200841016a3602e00a200b20086a41013a0000200141f0056a200141d80a6a10eb01200141f0056a4188016a280200210d0240024020012802dc0a220b20012802e00a22086b4104490d0020012802d80a210b0c010b200841046a222a2008490d20200b4101742208202a2008202a4b1b22084100480d2002400240200b0d0020081028210b0c010b20012802d80a200b2008102c210b0b200b450d10200120083602dc0a2001200b3602d80a20012802e00a21080b2001200841046a3602e00a200b20086a200d3600000b20012802e00a210b20012802dc0a210d20012802d80a210820012802b403450d1320012802b003102a0c130b2001200141b0036a3602d804202a200141d8046a200b10d70120012802b403210b20012802b8032108024020012802f0054113470d0002400240200b2008460d0020012802b003210b0c010b200841016a220b2008490d1f2008410174220d200b200d200b4b1b220d4100480d1f0240024020080d00200d1028210b0c010b20012802b0032008200d102c210b0b200b450d102001200d3602b4032001200b3602b00320012802b80321080b2001200841016a3602b803200b20086a41003a00000c120b02400240200b2008460d0020012802b003210b0c010b200841016a220b2008490d1e2008410174220d200b200d200b4b1b220d4100480d1e0240024020080d00200d1028210b0c010b20012802b0032008200d102c210b0b200b450d102001200d3602b4032001200b3602b00320012802b80321080b2001200841016a3602b803200b20086a41013a0000200141f0056a200141b0036a10eb01200141f0056a4188016a280200210d0240024020012802b403220b20012802b80322086b4104490d0020012802b003210b0c010b200841046a222a2008490d1e200b4101742208202a2008202a4b1b22084100480d1e02400240200b0d0020081028210b0c010b20012802b003200b2008102c210b0b200b450d11200120083602b4032001200b3602b00320012802b80321080b2001200841046a3602b803200b20086a200d3600000c110b20012802b403450d1220012802b003102a0c120b411741011037000b412e41011037000b200d41011037000b200d41011037000b200841011037000b202c41011037000b2008200d1044000b200d202a103c000b200b202a1044000b200141c0036a41146a4108360200200141cc036a4125360200200141f00a6a41146a4103360200200142033702f40a200141c8afc6003602f00a200141253602c4032001200141e80a6a3602880b2001200141ec0a6a36028c0b200142043703e804200142013702dc042001419cb0c6003602d8042001200141c0036a3602800b2001200141d8046a3602d00320012001418c0b6a3602c8032001200141880b6a3602c003200141f00a6a41d8b0c600103e000b200d41011037000b200d41011037000b200841011037000b200d41011037000b200d41011037000b200841011037000b20012802b803210b20012802b403210d20012802b00321080b2008450d0020014188076a41202008200b1007200d450d012008102a0c010b41900110282208450d014113210b024020012802f0054113460d0020014188076a200141f0056a10cf032001200141f0056a4188016a28020036029008200128028807210b200141d8046a2006418c01109a051a0b2008200b360200200841046a200141d8046a418c01109a051a41171028220b450d02200b410f6a200f370000200b41086a2014370000200b201f370000200b4117412e102c220b450d03200b20003600172007420037030020094200370300200a4200370300200142003703d804200b411b200141d8046a1000200e2007290300370300202f2009290300370300200c200a290300370300200120012903d80437038807200b102a200141d8046a2008410110ac0220014188076a412020012802d804220720012802e0041007024020012802dc04450d002007102a0b024020082802004113460d002008106a0b2008102a0b024020012802f0054113460d00200141f0056a106a0b200141f0056a41086a22084200370300200142003703f00541c290c6004113200141f0056a1008200c2008290300370300200120012903f005370388072001200541016a3602f00520114110200141f0056a410410070c040b41900141081037000b411741011037000b412e41011037000b20014188076a200141a0086a418801109a051a200141003b01f005200141d8046a20014188076a200141f0056a10f401200120012d00e0044102463a009107200141073a009007200141053a00880720012005360294074101410020014188076a10cc01200141f0056a41086a22084200370300200142003703f00541c290c6004113200141f0056a100820014188076a41086a2008290300370300200120012903f005370388072001200541016a3602f00520114110200141f0056a410410070b20162015470d000b201521160c010b1036000b024020162015460d00200141a0086a41086a2108200141a0086a410c6a21070340201641086a28020021062016290300210f200141a0086a2016410c6a419401109a051a20064113460d01200141c0096a200141a0086a419401109a051a200120063602a8082001200f3703a0082007200141c0096a419401109a051a2008106a201641a0016a22162015470d000b0b02402013450d002012102a0b0240024002400240411710282206450d002006410f6a41002900918945370000200641086a410029008a894537000020064100290082894537000020064117412e102c2206450d01200620103600174200210f200141d8046a41186a22084200370300200141d8046a41106a22074200370300200141d8046a41086a22054200370300200142003703d8042006411b200141d8046a100020014188076a41186a200829030037030020014188076a41106a200729030037030020014188076a41086a2005290300370300200120012903d804370388072006102a200141003602a00820014188076a4120200141a0086a100621080240024020012802a0082206417f470d004108210b0c010b200120063602c409200120083602c009200141a0086a200141c0096a10800120012802a008220b450d0320012902a408210f02402006450d002008102a0b20014188076a412010090b200b200f422088a722084190016c22076a2105200b210602402008450d00200741f07e6a2107200141a0086a410472210a200b21060240034020062802002108200141c0096a200641046a418401109a051a20084114460d01200141a0086a200141c0096a418401109a051a02400240024020084113470d0020070d01200521060c050b20064188016a280200210920014188076a200141a0086a418401109a051a200120083602a008200a20014188076a418401109a051a200141003b01c009200141f0056a200141a0086a200141c0096a10f40120012d00f8052108200120093602ac08200120084102463a00a908200141073a00a808200141053a00a00841014100200141a0086a10cc012007450d010b20064190016a2106200741f07e6a21070c010b0b200521060c010b20064190016a21060b200fa7210920062005460d03200141a0086a4104722107034020062802002108200141a0086a200641046a418c01109a051a20084114460d04200141c0096a200141a0086a418c01109a051a200120083602a0082007200141c0096a418c01109a051a024020084113460d00200141a0086a106a0b20064190016a22062005470d000c040b0b411741011037000b412e41011037000b41c4d1c3004133200141f0056a419cd9c3001038000b02402009450d00200b102a0b201010bd0202402002450d00200241246c21082004210603400240024020062d0000220741034b0d0002400240024020070e0404000102040b2006410c6a280200450d03200641086a280200102a0c030b2006410c6a280200450d02200641086a280200102a0c020b2006410c6a280200450d01200641086a280200102a0c010b200641086a280200450d00200641046a280200102a0b200641246a21062008415c6a22080d000b0b02402003450d002004102a0b200141900b6a24000f0b1031000be80201067f230041b0026b2201240020014198016a41086a22024200370300200142003703980141988bc500411620014198016a100820014188016a41086a2203200229030037030020012001290398013703880120014198016a20014188016a10df030240024020012802980122044113470d0041ae8bc50021020c010b20014188016a41101009200141046a20014198016a4104722205418401109a051a200141a0026a2d00002106200141013a00af0220024200370300200142003703980141d590c600411f20014198016a10082003200229030037030020012001290398013703880120014188016a4110200141af026a41011007200241023a0000200141053a009801410021024101410020014198016a10cc0120012004360298012005200141046a418401109a051a20014188016a200041809c316a20014198016a20064180de3410b7042001280288014101470d00200128028c0121020b200141b0026a240020020bc01802117f187e230041f0056b22012400200141a0046a41086a22024200370300200142003703a00441ac89c5004115200141a0046a1008200141306a41086a2002290300370300200120012903a004370330200141003602a004200141306a4110200141a0046a10062103024002400240024002400240024002400240024020012802a0042204417f460d002003450d002001200436024420012003360240200141286a200141c0006a106c20012802280d09200128024441b0016e220541b0016c2202417f4c0d02200128022c21060240024020020d00410821070c010b200210282207450d040b02402006450d0020014198036a4104722108410021094100210a0340024002400240200128024422024104490d002001280240220b280000210c20012002417c6a3602442001200b41046a360240200141a0046a200141c0006a10810120012802a0044113460d00200a41016a210d20014198036a200141a0046a418801109a051a4100210b200141003a00e8052001280244417f6a2102024003402002417f460d01200141c8056a200b6a2001280240220e2d00003a00002001200e41016a3602402001200b41016a220e3a00e805200120023602442002417f6a2102200e210b200e4120470d000b200141a8056a41186a2202200141c8056a41186a290300370300200141a8056a41106a220e200141c8056a41106a290300370300200141a8056a41086a220f200141c8056a41086a290300370300200120012903c8053703a805200128029803210b20014190026a2008418401109a051a200141f0016a41086a2210200f290300370300200141f0016a41106a220f200e290300370300200141f0016a41186a220e2002290300370300200120012903a8053703f001200b4113460d01200141ec006a20014190026a418401109a051a200141c8006a41186a2211200e290300370300200141c8006a41106a220e200f290300370300200141c8006a41086a220f2010290300370300200120012903f0013703482005200a470d030240200a4101742202200d2002200d4b1b2205ad42b0017e2212422088a70d002012a7220241004e0d030b1031000b0240200b41ff0171450d00200141003a00e8050b20014198036a106a0b0240200a450d002007210203402002106a200241b0016a2102200941d07e6a22090d000b0b2005450d0d2007102a0c0d0b02400240200a0d002002102821070c010b2007200a41b0016c2002102c21070b2007450d070b2007200a41b0016c6a2202200b360200200241046a200141ec006a418401109a051a2002200c360288012002200129034837028c0120024194016a200f2903003702002002419c016a200e290300370200200241a4016a2011290300370200200941b0016a2109200d210a200d2006470d000b0b2007450d092006ad42208621122005ad211302402004450d002003102a0b201220138421140c010b41082107420021140b024002402014422088a72204450d00200141a0046a20072802880110b8040240024020012802b00422020d0042002115420021120c010b200141186a20012903a004200141a0046a41086a290300200141b8046a3502004200109f05200141186a41086a29030021122001290318211520012802b404450d002002102a0b4100210e20044101460d012007200441b0016c6a210a200741b0016a21024100210e200721034101210b0340200141a0046a20024188016a28020010b8040240024020012802b00422090d0042002116420021130c010b200141086a20012903a004200141a0046a41086a29030020013502b8044200109f05200141086a41086a29030021132001290308211620012802b404450d002009102a0b201220132015201656201220135620122013511b22091b21122015201620091b21152003200220091b2103200e200b20091b210e200b41016a210b200241b0016a2202200a470d000b20030d01200441b0016c21092007210203402002106a200241b0016a2102200941d07e6a22090d000b0b41e789c50021022014a7450d072007102a0c070b200e20044f0d0320072004417f6a220941b0016c6a22024180016a290300211320024188016a290300211520024190016a290300211620024198016a2903002117200241e0006a2903002118200241e8006a2903002119200241f0006a290300211a200241f8006a290300211b200241c0006a290300211c200241c8006a290300211d200241d0006a290300211e200241d8006a290300211f200241206a2903002120200241286a2903002121200241306a2903002122200241386a2903002123200229030021242002290308212520022903102126200241186a2903002127200241a0016a2903002112200141306a41086a220b200241a8016a29030022283703002007200e41b0016c6a220241186a220e2903002129200e2027370300200229031021272002202637031020022903082126200220253703082002290300212520022024370300200241386a220e2902002124200e2023370200200241306a220e2902002123200e2022370200200241286a220e2902002122200e2021370200200241206a220e2902002121200e2020370200200241d8006a220e2902002120200e201f370200200241d0006a220e290200211f200e201e370200200241c8006a220e290200211e200e201d370200200241c0006a220e290200211d200e201c370200200241f8006a220e290200211c200e201b370200200241f0006a220e290200211b200e201a370200200241e8006a220e290200211a200e2019370200200241e0006a220e2902002119200e201837020020024198016a201737020020024190016a201637020020024188016a2203280200210e2003201537020020024180016a220329020021152003201337020020012012370330200241a0016a2012370200200241a8016a202837020020014198036a41f8006a201c37030020014198036a41f0006a201b37030020014198036a41e8006a201a37030020014198036a41e0006a201937030020014198036a41d8006a202037030020014198036a41d0006a201f37030020014198036a41c8006a201e37030020014198036a41c0006a201d37030020014198036a41386a202437030020014198036a41306a202337030020014198036a41286a202237030020014198036a41206a202137030020014198036a41186a202937030020014198036a4180016a2015370300200120273703a803200120263703a0032001202537039803200141a0046a41086a22024200370300200142003703a00441ac89c5004115200141a0046a1008200b2002290300370300200120012903a004370330200141103602a4042001200141306a3602a00420072009200141a0046a10ef0102402009450d00200441b0016c41d07e6a21092007210203402002106a200241b0016a2102200941d07e6a22090d000b0b02402014a7450d002007102a0b411310282202450d042002410f6a41002800e38945360000200241086a41002900dc8945370000200241002900d48945370000200241134126102c2202450d052002200e360013200141a8056a41186a22094200370300200141a8056a41106a220b4200370300200141a8056a41086a22034200370300200142003703a80520024117200141a8056a100020014190026a41186a200929030037030020014190026a41106a200b29030037030020014190026a41086a2003290300370300200120012903a805370390022002102a200141a0046a20014190026a10e003024020012802b004220b450d0020014190026a412010090b02400240200b450d00200141a8046a290300211220012903a004211320012802b40421030240200141a0046a41186a280200220a4105742209450d00200b2102034020022013201210aa02200241206a2102200941606a22090d000b0b200141c8046a2012370300200141c0046a2013370300200141b8046a200a360200200141b4046a2003360200200141b0046a200b360200200141ac046a200e360200200141a8046a41013a0000200141053a00a00441014100200141a0046a10cc01200141a0046a20014198036a418801109a051a20014190026a200041809c316a200141a0046a41004180de3410b7042001280290024101470d0120012802940221020c080b20014198036a106a0b410021020c060b1036000b200241081037000b200241081037000b41c489c500200e20041034000b411341011037000b412641011037000b200141f0056a240020020f0b41c4d1c3004133200141a0046a419cd9c3001038000b810601067f230041d0026b2202240002400240024002400240411a10282203450d00200341186a41002f00ce88453b0000200341106a41002900c68845370000200341086a41002900be8845370000200341002900b688453700002003411a4134102c2203450d012003200136001a200241c0016a41186a22014200370300200241c0016a41106a22044200370300200241c0016a41086a22054200370300200242003703c0012003411e200241c0016a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903c0013703002003102a200241003602c00120024120200241c0016a1006210320022802c0012201417f460d032003450d03200220033602282002200136022c20014104490d022003280000210620022001417c6a36022c2002200341046a360228200241c0016a200241286a10810120022802c0014113460d02200241386a200241c0016a418801109a051a02400240200228022c2207450d00200228022822012d0000210420022007417f6a220536022c2002200141016a360228200441034f0d00200541034b0d01200241386a106a0c040b200241386a106a0c030b2001280001210520022007417b6a36022c2002200141056a36022820022802382101200241c0016a200241386a410472418401109a051a200220022800303602202002200241336a28000036002320014113460d02200241386a200241c0016a418401109a051a20022002280023360033200220022802203602302003102a0c040b411a41011037000b413441011037000b41c4d1c3004133200241c8026a419cd9c3001038000b411321010b200241c0016a200241386a418401109a051a2002200228003336002b200220022802303602280240024020014113470d00200041133602000c010b20002001360200200041046a200241c0016a418401109a051a20004190016a20043a00002000418c016a200536020020004188016a2006360200200020022802283600910120004194016a200228002b3600000b200241d0026a24000bfb0202047f017e230041d0006b22022400024002400240411310282203450d002003410f6a41002800a88945360000200341086a41002900a18945370000200341002900998945370000200341134126102c2203450d0120032001360013200241286a41186a22014200370300200241286a41106a22044200370300200241286a41086a220542003703002002420037032820034117200241286a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903283703002003102a2002410036022820024120200241286a100621010240024020022802282203417f460d002002200336022420022001360220200241286a200241206a106d20022802282204450d04200229022c210602402003450d002001102a0b20002006370204200020043602000c010b20004100360208200042013702000b200241d0006a24000f0b411341011037000b412641011037000b41c4d1c3004133200241c8006a419cd9c3001038000ba40301057f230041d0006b22022400024002400240411010282203450d00200341002900a68845370000200341086a41002900ae88453700002002429080808080023702242002200336022020012802002104200341104120102c2203450d0120032004360010200242a0808080c00237022420022003360220200141046a200241206a108f012002280228210320022802202101200241306a41186a22044200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020012003200241306a1000200241186a2004290300370300200241106a2005290300370300200241086a20062903003703002002200229033037030002402002280224450d002002280220102a0b410021032002410036023020024120200241306a100621010240024020022802302204417f470d00410021010c010b2004450d0320012d0000220441ff0071220341074f0d032001102a200441077621010b200020033a0001200020013a0000200241d0006a24000f0b411041011037000b412041011037000b41c4d1c3004133200241306a419cd9c3001038000bf00b04017f047e117f087e23004190046b22052400024002400240024020040d00420021064200210742002108420021090c010b42002108200541f0036a41186a220a4200370300200541f0036a41106a220b4200370300200541f0036a41086a220c4200370300200542003703f00341e588c500411d200541f0036a100020054198036a41186a220d200a29030037030020054198036a41106a220e200b29030037030020054198036a41086a220f200c290300370300200520052903f0033703980320054198016a20054198036a412010fd01200541c0016a41206a20054198016a41206a2d00003a0000200541c0016a41186a20054198016a41186a290300370300200541c0016a41106a20054198016a41106a290300370300200541c0016a41086a20054198016a41086a29030037030020052005290398013703c001200541e8016a200541c0016a10af0142002109420021064200210720052d00a8024107460d002004417f6a2110200541b8036a4104722111200541f0026a2112200541b0026a41206a2113200541b0026a41186a211442002106420021074200210842002109034020142007370300200520063703c002200520083703b002200520093703b8022013200541e8016a41c100109a0521040240024020122002460d00201220024120109c050d010b20112004290200370200201141086a200441086a2215290200370200201141106a200441106a2216290200370200201141186a200441186a2217290200370200200520013602b803411010282218450d03201841002900a68845370000201841086a41002900ae88453700002005429080808080023702e403200520183602e00320052802b8032119201841104120102c2218450d04200541203602e403200520052802e803221a41046a3602e803200520183602e0032018201a6a20193600002011200541e0036a108f0120052802e803211820052802e0032119200a4200370300200b4200370300200c4200370300200542003703f00320192018200541f0036a1000200d200a290300370300200e200b290300370300200f200c290300370300200520052903f00337039803024020052802e403450d0020052802e003102a0b20054198036a41204101410041001003417f470d0020052d0090032118200a2017290000370300200b2016290000370300200c2015290000370300200520042900003703f00320054188016a200541f0036a109d0220054188016a41086a290300211b200529038801211c02400240201820032018200341ff0171491b220441ff01710d00200541086a201c201b420a420010a005200541b8036a41186a200a290300370300200541b8036a41106a200b290300370300200541b8036a41086a200c290300370300200520052903f0033703b803200541186a2001200541b8036a4100201010cd03200541186a41186a290300211d200541186a41086a290300211e2005290328211f2005290318212020052903082221211c200541086a41086a2903002222211b0c010b200541c8006a201b42002004ad42ff018322214200109f05200541d8006a201c420020214200109f05200541b8036a41186a200a290300370300200541b8036a41106a200b290300370300200541b8036a41086a200c290300370300200520052903f0033703b803200541e8006a2001200541b8036a2004201010cd03200541386a42004200201c4200109f05427f200541d8006a41086a2903002221200529034820052903387c7c221d2005290350200529034084420052201d2021547222041b2122427f200529035820041b2121200541e8006a41186a290300211d200541e8006a41086a290300211e2005290378211f200529036821200b201b20077c201c20067c2207201c54ad7c201d7c2007201f7c2206200754ad7c2107202220097c202120087c2209202154ad7c201e7c200920207c2208200954ad7c21090b200541e8016a200541c0016a10af0120052d00a8024107470d000b0b2000200637031020002008370300200041186a20073703002000200937030820054190046a24000f0b411041011037000b412041011037000be907030b7f047e027f230041a0016b22012400024002400240024002400240411a10282202450d00200241186a41002f00ce88453b0000200241106a41002900c68845370000200241086a41002900be8845370000200241002900b688453700002002411a4134102c2202450d012002200036001a20014180016a41186a2203420037030020014180016a41106a2204420037030020014180016a41086a2205420037030020014200370380012002411e20014180016a1000200141286a41186a2003290300370300200141286a41106a2004290300370300200141286a41086a200529030037030020012001290380013703282002102a200141286a41201009411310282202450d022002410f6a41002800a88945360000200241086a41002900a18945370000200241002900998945370000200241134126102c2202450d032002200036001320014180016a41186a2205420037030020014180016a41106a2206420037030020014180016a41086a2203420037030020014200370380012002411720014180016a1000200141286a41186a22072005290300370300200141286a41106a22082006290300370300200141286a41086a200329030037030020012001290380013703282002102a200141286a41201009200141c8006a200010cb03200128024c21092001280248210a024020012802502202450d002002410574210b200141c8006a4104722103200a21020340200141086a41186a200241186a290000220c370300200141086a41106a200241106a290000220d370300200141086a41086a200241086a290000220e37030020012002290000220f3703082003200f370200200341086a200e370200200341106a200d370200200341186a200c37020020012000360248411010282204450d06200441002900a68845370000200441086a41002900ae88453700002001429080808080023702742001200436027020012802482110200441104120102c2204450d072001412036027420012001280278221141046a36027820012004360270200420116a20103600002003200141f0006a108f012001280278210420012802702110200542003703002006420037030020014180016a41086a2211420037030020014200370380012010200420014180016a10002007200529030037030020082006290300370300200141286a41086a2011290300370300200120012903800137032802402001280274450d002001280270102a0b200241206a2102200141286a41201009200b41606a220b0d000b0b02402009450d00200a102a0b200141a0016a24000f0b411a41011037000b413441011037000b411341011037000b412641011037000b411041011037000b412041011037000b801102047f027e230041e0016b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1514000102030405060708090a0b0c0d0e0f10111213140b10a103000b20004102360200200041086a200141086a2903003703000c130b200241e0006a200141046a1070200041033602002000410c6a200241e8006a280200360200200020022903603702040c120b10bb03000b200241e0006a200141086a10ae02200041086a200241e0006a41e000109a051a200041053602000c100b200241e0006a200141086a10bc0320004106360200200041386a200241e0006a41306a290300370300200041306a200241e0006a41286a290300370300200041286a200241e0006a41206a290300370300200041206a200241e0006a41186a290300370300200041186a200241e0006a41106a290300370300200041106a200241e0006a41086a290300370300200041086a20022903603703000c0f0b200241e0006a41186a200141286a290000370300200241e0006a41106a200141206a290000370300200241e8006a200141186a290000370300200241e0006a41286a200141386a290000370300200241e0006a41306a200141c0006a290000370300200241e0006a41386a200141c8006a290000370300200241e0006a41c8006a200141d8006a290000370300200241e0006a41d0006a200141e0006a290000370300200241e0006a41d8006a200141e8006a2900003703002002200141106a2900003703602002200141306a290000370380012002200141d0006a2900003703a0012001410c6a2802002203417f4c0d0f200128020421010240024020030d0041012104410021050c010b20032105200310282204450d110b200420012003109a0521012002200241e0006a41e000109a0521042000410c6a2003360200200041086a200536020020002001360204200041106a200441e000109a051a200041073602000c0e0b200241e0006a200141086a10bd0320004108360200200041306a200241e0006a41286a290300370300200041286a200241e0006a41206a290300370300200041206a200241e0006a41186a290300370300200041186a200241e0006a41106a290300370300200041106a200241e0006a41086a290300370300200041086a20022903603703000c0d0b200241e0006a200141046a10c30320004109360200200041246a20024180016a2903003702002000411c6a200241f8006a290300370200200041146a200241f0006a2903003702002000410c6a200241e8006a290300370200200020022903603702040c0c0b200241e0006a200141046a10c3032000410a360200200041246a20024180016a2903003702002000411c6a200241f8006a290300370200200041146a200241f0006a2903003702002000410c6a200241e8006a290300370200200020022903603702040c0b0b200241e0006a200141086a10d3022000410b360200200041c0006a200241e0006a41386a290300370300200041386a200241e0006a41306a290300370300200041306a200241e0006a41286a290300370300200041286a200241e0006a41206a290300370300200041206a200241e0006a41186a290300370300200041186a200241e0006a41106a290300370300200041106a200241e0006a41086a290300370300200041086a20022903603703000c0a0b200241e0006a200141046a10be03200041046a200241e0006a41c400109a051a2000410c3602000c090b2000410d360200200020012802043602040c080b2001410c6a2802002203417f4c0d08200128020421010240024020030d0041002104410121050c010b20032104200310282205450d0b0b200520012003109a0521012000410c6a2003360200200041086a2004360200200020013602042000410e3602000c070b024002400240024002400240200141086a280200417f6a220341024b0d0020030e03010203010b418486c2001032000b200141386a2903002106200141306a290300210741012103024002402001410c6a2d00004101460d00200241e8006a2001411c6a290200370300200241e0006a41106a200141246a290200370300200241f8006a2001412c6a2d00003a00002002200141146a29020037036020012f000d2001410f6a2d0000411074722104200141106a2802002105410021030c010b200141106a28020021050b200241186a200241e0006a41186a280200360200200241106a200241e0006a41106a290300370300200241086a200241e0006a41086a29030037030020022002290360370300410121010c030b2001410c6a28020022034108762104410221010c010b2001410c6a28020022034108762104410321010b0b2000410f360200200041386a2006370300200041306a2007370300200041106a2005360200200041086a2001360200200041146a20022903003702002000410c6a2004410874200341ff0171723602002000411c6a200241086a290300370200200041246a200241106a2903003702002000412c6a200241186a2802003602000c060b200241e0006a200141086a10bf03200041086a200241e0006a418001109a051a200041103602000c050b200241e0006a200141046a10c003200041113602002000412c6a20024188016a280200360200200041246a20024180016a2903003702002000411c6a200241f8006a290300370200200041146a200241f0006a2903003702002000410c6a200241e8006a290300370200200020022903603702040c040b200241e0006a200141046a10af02200041046a200241e0006a41e400109a051a200041123602000c030b10c103000b10d501000b200241e0006a200141086a10c20320004100360200200041106a200241e0006a41086a290300370300200041086a20022903603703000b200241e0016a24000f0b1036000b200341011037000b200341011037000bfe1a03087f047e037f23004180076b22042400200441c8036a200141a002109a051a200441e8016a200441c8036a10d10341012105024002400240024002400240024020042d00e8014101470d00200020042f00e9013b0001200041013a0000200041036a20042d00eb013a000020032802002106410021000c010b200441106a200441e8016a41086a41d801109a051a0240024002400240024002400240024002400240024020032802002206450d00200341086a28020021072003280204210841002109200441003602c8034188e8c2004110200441c8036a10062101024020042802c8032205417f460d002001450d0020054104490d02200128000021092001102a0b411410282201450d0241002105200141106a41002800eaa046360000200141086a41002900e2a046370000200141002900daa046370000200141144128102c2201450d0320012009360014200441e8016a41186a22094200370300200441e8016a41106a220a4200370300200441e8016a41086a220b4200370300200442003703e80120014118200441e8016a1000200441c0066a41186a2009290300370300200441c0066a41106a200a290300370300200441c0066a41086a200b290300370300200420042903e8013703c0062001102a200441203602cc032004200441c0066a3602c80320062007200441c8036a10cb012008450d002006102a0b200441086a200441106a41d0006a10f3012004280208210720042d000c2108200441c8036a200441106a41d801109a051a4100210120042903e803220c4202510d0c20044198066a41186a200441c8036a41186a29030037030020044198066a41106a200441c8036a41106a29030037030020044198066a41086a200441c8036a41086a290300370300200420042903c8033703980620044188046a290300210d20044180046a290300210e20044190046a280200210920042903f003210f200441e8016a41086a22014200370300200442003703e80141d9efc200410d200441e8016a1008200441c0066a41086a2001290300370300200420042903e8013703c006200441003602e801200441c0066a4110200441e8016a10062101024020042802e801220a417f460d002001450d00200a41034d0d042001102a0b0240200c4201520d00200f4200510d050b411310282201450d05200141002900cef0423700002001410f6a41002800ddf042360000200141086a41002900d6f04237000020044293808080b0023702fc05200420013602f80520044198066a200441f8056a108f01200428028006210120042802f805210a200441e8016a41186a220b4200370300200441e8016a41106a22104200370300200441e8016a41086a22114200370300200442003703e801200a2001200441e8016a1000200441c0066a41186a200b290300370300200441c0066a41106a2010290300370300200441c0066a41086a2011290300370300200420042903e8013703c006024020042802fc05450d0020042802f805102a0b200441003602e801200441c0066a4120200441e8016a1006210a0240024020042802e8012201417f470d00410021010c010b0240200a0d00410021010c010b20014104490d07200a2800002101200a102a0b200441c8036a41d0006a210a024020012009470d00411310282201450d0820084101712108200941016a2109200141002900cef0423700002001410f6a41002800ddf042360000200141086a41002900d6f04237000020044293808080b0023702fc05200420013602f80520044198066a200441f8056a108f01200428028006210120042802f805210b200441e8016a41186a22104200370300200441e8016a41106a22114200370300200441e8016a41086a22124200370300200442003703e801200b2001200441e8016a1000200441c0066a41186a2010290300370300200441c0066a41106a2011290300370300200441c0066a41086a2012290300370300200420042903e8013703c006024020042802fc05450d0020042802f805102a0b200420093602e801200441c0066a4120200441e8016a41041007200441e8016a2008200210b803024020042903e801220ca741ff01714101460d00200441e8016a41086a22014200370300200442003703e80141a8a0c6004117200441e8016a1008200441c0066a41086a22092001290300370300200420042903e8013703c0062004200c4220883e02e801200441c0066a4110200441e8016a41041007200441e8016a2007200810b90320042903e801220ca741ff01714101460d0020014200370300200442003703e801418ea0c600411a200441e8016a100820092001290300370300200420042903e8013703c0062004200c4220883e02e801200441c0066a4110200441e8016a410410070c0a0b200c420888a7220941ff01714104460d09200c421088a721010c0a0b41034102200120094b1b2101410021090c090b41c4d1c3004133200441e8016a419cd9c3001038000b411441011037000b412841011037000b41c4d1c3004133200441e8016a419cd9c3001038000b41fcf8c5001032000b411341011037000b41c4d1c3004133200441e8016a419cd9c3001038000b411341011037000b200441e8016a200e200d20044198066a200720082002109e020240024020042d00e8014101460d0020044194026a280200210920044190026a280200210b2004418c026a280200210720044184026a280200211020044180026a2802002108024020044188026a2802002201450d002001410c6c21022008210103400240200141046a280200450d002001280200102a0b2001410c6a2101200241746a22020d000b0b02402010450d002008102a0b02402009450d002009410c6c21022007210103400240200141046a280200450d002001280200102a0b2001410c6a2101200241746a22020d000b0b200b450d012007102a0c010b20042f01ea01210120042d00e9012209417e6a220241024b0d0120020e03000100000b200441e8016a200a10d203024020042d00e8014101460d0020044194026a280200210920044190026a280200210a2004418c026a280200210720044184026a280200210b20044180026a2802002108024020044188026a2802002201450d002001410c6c21022008210103400240200141046a280200450d002001280200102a0b2001410c6a2101200241746a22020d000b0b0240200b450d002008102a0b02402009450d002009410c6c21022007210103400240200141046a280200450d002001280200102a0b2001410c6a2101200241746a22020d000b0b200a450d032007102a0c030b20042f01ea01210120042d00e9012209417e6a220241024b0d0020020e03020002020b200a106a200441f0056a41026a200441f4056a41026a2d00003a0000200420042f00f4053b01f005200041036a20014108763a000020002001410874200941ff0171723b0001200041013a000020054521000b20000d032006450d03200341046a2802000d020c030b200441e0066a41186a20044198066a41186a290300370300200441e0066a41106a20044198066a41106a290300370300200441e0066a41086a20044198066a41086a29030037030020042004290398063703e006410121010b200441f8056a41186a2208200441e0066a41186a2202290300370300200441f8056a41106a220a200441e0066a41106a2209290300370300200441f8056a41086a220b200441e0066a41086a2207290300370300200420042903e0063703f805200441e8016a200441c8036a41d0006a418801109a051a200220082903003703002009200a2903003703002007200b290300370300200420042903f8053703e0064102210802402001450d00200441c0066a41186a2002290300370300200441c0066a41106a2009290300370300200441c0066a41086a2007290300370300200420042903e0063703c006410121080b200441a2066a200441c0066a41086a290300370100200441aa066a200441c0066a41106a290300370100200441b2066a200441c0066a41186a290300370100200420083a009906200420042903c00637019a06200441003a009806200441e0066a200441e8016a20044198066a10f401200441e8016a41026a200441eb066a2d00003a0000200420042f00e9063b01e80120042903e006210c024020042d00e80622014102460d0020044198066a41026a200441e8016a41026a2d00003a0000200420042f01e8013b0198060b200441ec056a41026a220220044198066a41026a2d00003a0000200420042f0198063b01ec05024020014102460d00200441e8016a41026a20022d00003a0000200420042f01ec053b01e8010b200441d4036a20013a0000200441d5036a20042f01e8013b0000200441d7036a200441e8016a41026a2d00003a00002004200c3702cc03200441003a00c8034101210941014100200441c8036a10cc01200441003602c8034188e8c2004110200441c8036a10062102024020042802c8032207417f460d002002450d0020074104490d03200228000021092002102a200941016a21090b200420093602c8034188e8c2004110200441c8036a410410072000410c6a20013a0000200041046a200c3702002000410d6a20042f01ec053b00002000410f6a200441ee056a2d00003a0000200041003a00002006450d012005450d01200341046a280200450d010b2006102a0b20044180076a24000f0b41c4d1c3004133200441e8016a419cd9c3001038000bf41f05017f037e077f017e037f230041a00a6b22022400420221030240024002400240024002400240024002400240024002400240200129036822044202520d00200220014198016a418801109a051a0c010b20024188026a200141dc006a29000037030020024180026a200141d4006a290000370300200241f8016a200141cc006a290000370300200241d0016a41206a200141c4006a290000370300200241d0016a41186a2001413c6a290000370300200241d0016a41106a200141346a290000370300200241d0016a41086a2001412c6a290000370300200220012900243703d00120024190026a41086a20014188016a29030037030020024190026a41106a20014190016a290300370300200220014180016a29030037039002200141f8006a2903002103200129037021052001280204210620012d00002107200241800a6a41026a2208200141036a2d00003a0000200241c8026a41086a2209200141106a290200370300200241c8026a41106a220a200141186a290200370300200241c8026a41186a220b200141206a280200360200200220012f00013b01800a200220012902083703c80202400240024020074101460d00200241e0096a41026a20082d00003a0000200241b0066a41086a2009290300370300200241b0066a41106a200a290300370300200241b0066a41186a200b2d00003a0000200220022f01800a3b01e009200220022903c8023703b0060c010b200241c0076a200641067610fe0120022802c00721070240024020022802c8072006413f7122064b0d00410021080c010b200241e0096a41026a200720064105746a220641026a2d00003a0000200241b8066a2006410f6a290000370300200241c0066a200641176a290000370300200241c8066a2006411f6a2d00003a0000200220062f00003b01e009200220062900073703b00620062800032106410121080b024020022802c407450d002007102a0b20080d00410121070c010b200241c0076a41026a200241e0096a41026a2d00003a0000200241c8026a41086a200241b0066a41086a290300370300200241c8026a41106a200241b0066a41106a290300370300200241c8026a41186a200241b0066a41186a2d00003a0000200220022f01e0093b01c007200220022903b0063703c802410021070b200241c0096a41026a2208200241c0076a41026a2d00003a0000200241a0056a41086a2209200241c8026a41086a290300370300200241a0056a41106a220a200241c8026a41106a290300370300200241a0056a41186a220b200241c8026a41186a2d00003a0000200220022f01c0073b01c009200220022903c8023703a00502402007450d00200041013b0001200041013a0000200041036a41003a000020014198016a106a0c0c0b200241b7026a2009290300370000200241bf026a200a290300370000200241c7026a200b2d00003a0000200220022f01c0093b01a802200220063600ab02200220022903a0053700af02200220082d00003a00aa02200241c0076a20014198016a418801109a051a200241c8086a41106a20024190026a41106a290300370300200241c8086a41086a20024190026a41086a29030037030020022002290390023703c80841002107200241800a6a410010f701200241c0096a41086a2002418b0a6a290000370300200241c0096a41106a200241930a6a290000370300200241d5096a200241800a6a41186a290000370000200220022900830a3703c00920022f01800a210b20022d00820a210c200241800a6a41086a22014200370300200242003703800a41d9efc200410d200241800a6a1008200241e0096a41086a2001290300370300200220022903800a3703e009200241003602800a200241e0096a4110200241800a6a10062101024020022802800a2206417f460d002001450d0020064104490d02200128000021072001102a0b41002106024020044201520d0020054200510d03417f21062007ad220d20032003200d541b220d200d20037d2005827d220d42ffffffff0f560d00200da721060b411010282201450d03200141086a41002900c6f042370000200141002900bef042370000200141104120102c2201450d0420012006360010200241800a6a41186a22074200370300200241800a6a41106a22084200370300200241800a6a41086a22094200370300200242003703800a20014114200241800a6a1000200241e0096a41186a2007290300370300200241e0096a41106a220a2008290300370300200241e0096a41086a2009290300370300200220022903800a3703e0092001102a4101210102400240200241e0096a41204101410041001003417f470d000c010b200241800a6a200610f701200241a0096a41086a2002418b0a6a290000370300200241a0096a41106a200241930a6a290000370300200241a0096a41156a2007290000370000200241e0096a41086a200241c0096a41086a290300370300200a200241c0096a41106a290300370300200241e0096a41156a200241c0096a41156a290000370000200220022900830a3703a009200220022903c0093703e00920022f01800a20022d00820a411074722106410021010b20024180096a41156a2207200241e0096a41156a29000037000020024180096a41106a2208200241e0096a41106a29030037030020024180096a41086a2209200241e0096a41086a290300370300200241e0086a41086a220a200241a0096a41086a290300370300200241e0086a41106a220e200241a0096a41106a290300370300200241e0086a41156a220f200241a0096a41156a290000370000200220022903e00937038009200220022903a0093703e00802402001450d00200241c0076a106a200041036a41003a0000200041800a3b0001200041013a00000c0c0b200241e8046a41156a22012007290000370000200241e8046a41106a22072008290300370300200241e8046a41086a22082009290300370300200241c8046a41086a2209200a290300370300200241c8046a41106a220a200e290300370300200241c8046a41156a220e200f29000037000020022002290380093703e804200220022903e0083703c80420024188056a41106a220f200241c8086a41106a29030037030020024188056a41086a2210200241c8086a41086a290300370300200220022903c80837038805200241b0066a41046a200241c0076a418801109a051a200241a0056a200241b0066a418c01109a051a200241c8026a200241a0056a41046a418801109a051a20024186046a200b200c41107472220b4110763a000020024184046a220c200b3b0100200241e0036a2003370300200241d8036a2005370300200241e8036a220b200229038805370300200241f0036a2010290300370300200241f8036a2210200f29030037030020024187046a20022903e8043700002002418f046a200829030037000020024197046a20072903003700002002419c046a2001290000370000200220043703d003200241a30136028004200241a6046a20064110763a0000200241a4046a220720063b0100200241a7046a20022903c804370000200241af046a2009290300370000200241b7046a200a290300370000200241bc046a200e290000370000410410282201450d05200242043702b406200220013602b006200241c8026a200241b0066a10eb010240024020022903d0034201510d000240024020022802b40620022802b8062201460d0020022802b00621060c010b200141016a22062001490d0c200141017422082006200820064b1b22084100480d0c0240024020010d002008102821060c010b20022802b00620012008102c21060b2006450d09200220083602b406200220063602b00620022802b80621010b2002200141016a3602b806200620016a41003a00000c010b20022903e00320022903d8032203420c882204420120044201561b8021040240024020022802b406220620022802b80622016b4102490d0020022802b00621060c010b200141026a22082001490d0b200641017422012008200120084b1b22014100480d0b0240024020060d002001102821060c010b20022802b00620062001102c21060b2006450d09200220013602b406200220063602b00620022802b80621010b2002200141026a3602b806200620016a2004a741047420037aa7417f6a22014101200141014b1b2201410f2001410f491b723b00000b2010200241b0066a10a0012002200b3602a005200241a0056a200241b0066a10a30120022802800421080240024020022802b406220620022802b80622016b4104490d0020022802b00621060c010b200141046a22092001490d0a200641017422012009200120094b1b22014100480d0a0240024020060d002001102821060c010b20022802b00620062001102c21060b2006450d09200220013602b406200220063602b00620022802b80621010b2002200141046a3602b806200620016a20083600002002200241b0066a3602a005200c200241a0056a10c8012002200241b0066a3602a0052007200241a0056a10c80120022802b006210120022802b40621060240024020022802b80622074180024b0d00200241d0016a20012007200241a8026a10dd0321070c010b200241800a6a41186a22084200370300200241800a6a41106a22094200370300200241800a6a41086a220a4200370300200242003703800a20012007200241800a6a1000200241e0096a41186a2008290300370300200241e0096a41106a2009290300370300200241e0096a41086a200a290300370300200220022903800a3703e009200241d0016a200241e0096a4120200241a8026a10dd0321070b02402006450d002001102a0b2007450d0a200241b0016a41086a200241a8026a41086a290300370300200241b0016a41106a200241a8026a41106a290300370300200241b0016a41186a200241a8026a41186a29030037030020024188016a41086a200241e0036a29030037030020024188016a41106a200241e8036a29030037030020024188016a41186a200241f0036a290300370300200241a8016a200241f8036a290300370300200220022903a8023703b0012002200241d8036a2903003703880120022903d00321032002200241c8026a418801109a051a0b200041086a20022903b001370300200041286a2003370300200041306a200229038801370300200041206a200241b0016a41186a290300370300200041186a200241b0016a41106a290300370300200041106a200241b0016a41086a290300370300200041386a20024188016a41086a290300370300200041c0006a20024188016a41106a290300370300200041c8006a20024188016a41186a290300370300200041d0006a20024188016a41206a290300370300200041d8006a2002418801109a051a200041003a0000200241a00a6a24000f0b41c4d1c3004133200241800a6a419cd9c3001038000b41fcf8c5001032000b411041011037000b412041011037000b410441011037000b200841011037000b200141011037000b200141011037000b1031000b20004180083b0001200041013a0000200041036a41003a0000200241c8026a106a0b200241a00a6a24000be00402037f017e230041306b220224000240024020012802004110460d00200041003a0000200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a42003703000c010b024002400240024002400240200141086a2d00000e06050402010004050b200141c8006a21030c020b200141d0006a21030c010b200141186a21030b200241086a41086a220142003703002002420037030841affec5004111200241086a1008200241206a41086a20012903003703002002200229030837032020024100360208200241206a4110200241086a1006210102400240024020022802082204417f470d004280ade20421050c010b024020010d004280ade20421050c010b20044108490d01200129000021052001102a4280ade20420057d21050b024020032903002005560d00200041003a0000200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a42003703000c040b200041800c3b0001200041013a0000200041036a41003a00000c030b41c4d1c3004133200241086a419cd9c3001038000b200041003a0000200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a42003703000c010b2002411c6a41013602002002420137020c200241ccd1c50036020820024104360224200241ccd0c3003602202002200241206a360218200241086a41f0d0c300103e000b200241306a24000ba60201037f412e210241f8f4c50021030240024002402001417e6a22044102200441ff01714102491b41ff01710e03020001020b4130210241c8f4c50021030c010b20014180feff07714108762104024020014101710d00411f210241b4f5c50021030240024002400240024002400240200441ff01710e080006010203040508000b4120210241baf7c50021030c070b4127210241daf6c50021030c060b4117210241c3f6c50021030c050b41a4f6c50021030c040b4126210241fef5c50021030c030b412b210241d3f5c50021030c020b413921024181f7c50021030c010b411f210241daf7c500210302400240200441ff01710e03000102000b41c100210241baf8c50021030c010b41c100210241f9f7c50021030b20002002360204200020033602000b13002000410136020420004188bcc3003602000b3400200041e7bfc30036020420004100360200200041146a4102360200200041106a41f0bfc300360200200041086a42093702000b130020004101360204200041bcc2c3003602000b3101017f02404108102822020d00410841011037000b20004288808080800137020420002002360200200242dc0b3700000b130020004104360204200041e0c5c3003602000b3400200041beccc30036020420004100360200200041146a4101360200200041106a41d4ccc300360200200041086a42133702000beb050a067f017e017f017e017f017e017f017e017f017e230041206b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200020044105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c37000020052008370000024020032001490d00200321040c030b2006410d7420067322054111762005732205410574200573220620077122054100200120052001491b6b220520014f0d01200020034105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c370000200520083700002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200020044105746a22012900002108200020054105746a220041086a2205290000210a200041106a2204290000210c200041186a2203290000210e20012000290000370000200141186a220629000021102006200e370000200141106a2206290000210e2006200c370000200141086a2201290000210c2001200a370000200320103700002004200e3700002005200c370000200020083700000b200241206a24000f0b4190cec300200520011034000b4180cec300200420011034000be90609067f017e017f017e017f027e017f017e027f230041206b22022400024020014101762203450d0003402003417f6a2203210402400240024003402004410174220541017221060240200541026a220520014f0d00200620014f0d0220052006200020064105746a200020054105746a4120109c054100481b21060b200620014f0d03200420014f0d02200020044105746a2204200020064105746a22054120109c0541004e0d03200541086a22072900002108200541106a2209290000210a200541186a220b290000210c2004290000210d20042005290000370000200441186a220e290000210f200e200c370000200441106a220e290000210c200e200a370000200441086a2204290000210a20042008370000200b200f3700002009200c3700002007200a3700002005200d370000200621040c000b0b41c8cfc300200620011034000b41d8cfc300200420011034000b20030d000b0b0240024020014102490d002001210703402007417f6a220720014f0d02200241186a2209200041186a2204290000370300200241106a220b200041106a2205290000370300200241086a220e200041086a2203290000370300200020074105746a220641086a2900002108200641106a290000210a200641186a290000210c2000290000210d200020062900003700002004200c3700002005200a370000200320083700002002200d37030041002105024002400240034020062002290300370000200641186a2009290300370000200641106a200b290300370000200641086a200e2903003700002005410174220641017221040240200641026a220620074f0d00200420074f0d0220062004200020044105746a200020064105746a4120109c054100481b21040b200420074f0d03200520074f0d02200020054105746a2205200020044105746a22064120109c0541004e0d032009200541186a2203290000370300200b200541106a2210290000370300200e200541086a2211290000370300200641086a2900002108200641106a290000210a200641186a290000210c2005290000210d200520062900003700002003200c3700002010200a370000201120083700002002200d370300200421050c000b0b41c8cfc300200420071034000b41d8cfc300200520071034000b200741014b0d000b0b200241206a24000f0b4190cec300200720011034000b9009030a7f017e0a7f230041c0006b22022400200041807f6a21032001417f6a2104200141324921054101210641002107024003400240024020062001490d00410021080c010b41012108200020064105746a2209200941606a4120109c054100480d0003404101210a20042006460d03200641016a2106200941206a220a20094120109c052108200a21092008417f4a0d000b200620014921080b2006200146210a20050d0120062001460d01024002400240024002402006417f6a220920014f0d002008450d0120002006410574220b6a220a290000210c200a200020094105746a22092900003700002009200c370000200a41086a220d290000210c200d200941086a22082900003700002008200c370000200a41106a220e290000210c200e200941106a220f290000370000200f200c370000200a41186a2210290000210c2010200941186a22112900003700002011200c37000020064102490d04200920002006417e6a22124105746a22134120109c05417f4a0d042009290000210c20092013290000370000200241206a41186a22142011290000370300200241206a41106a2215200f290000370300200241206a41086a221620082900003703002008201341086a290000370000200f201341106a2900003700002011201341186a2900003700002002200c370320024020120d00410021120c040b200241206a20002006417d6a22084105746a4120109c05417f4a0d032003200b6a21090340200941d8006a200941386a290000370000200941d0006a200941306a290000370000200941c8006a200941286a290000370000200941c0006a200941206a2900003700002008450d032008417f6a2108200241206a20094120109c05210f200941606a2109200f4100480d000b200841016a21120c030b4180cec300200920011034000b4190cec300200620011034000b410021120b200020124105746a22092002290320370000200941186a2014290300370000200941106a2015290300370000200941086a20162903003700000b200741016a21070240200120066b220f4102490d00200a41206a2209200a4120109c05417f4a0d00200a290000210c200a2009290000370000200241206a41186a22112010290000370300200241206a41106a2213200e290000370300200241206a41086a2212200d290000370300200d200941086a290000370000200e200941106a2900003700002010200941186a2900003700002002200c3703204101210d0240200f4103490d00200a41c0006a2209200241206a4120109c05417f4a0d00410321084102210e02400340200e410574200a6a41606a220d2009290000370000200d41186a200941186a290000370000200d41106a200941106a290000370000200d41086a200941086a2900003700002008200f4f0d0120084105742109200e210d2008210e200841016a2108200a20096a2209200241206a4120109c054100480d000c020b0b200e210d0b200a200d4105746a22092002290320370000200941186a2011290300370000200941106a2013290300370000200941086a20122903003700000b20074105470d000b4100210a0b200241c0006a2400200a0b8305010f7f230041a0026b22042400200441c0016a41386a2205200041386a2206290000370300200441c0016a41306a2207200041306a2208290000370300200441c0016a41286a2209200041286a220a290000370300200441c0016a41206a220b200041206a220c290000370300200441c0016a41186a220d200041186a220e290000370300200441c0016a41106a220f200041106a2210290000370300200441c0016a41086a2211200041086a2212290000370300200420002900003703c0010240024020012002200441c0016a2003100a0d00410121000c010b20052006290000370300200720082900003703002009200a290000370300200b200c290000370300200d200e290000370300200f20102900003703002011201229000037030020044188026a2205200341086a29000037030020044190026a2206200341106a29000037030020044198026a2207200341186a290000370300200420002900003703c00120042003290000370380022004200441c0016a41e000109a05220041c0016a200041e000109a051a200041e0006a41386a200041386a290000370300200041e0006a41306a200041306a290000370300200041e0006a41286a200041286a290000370300200041e0006a41206a200041206a290000370300200041e0006a41186a200041186a290000370300200041e0006a41106a200041106a290000370300200041e0006a41086a200041086a29000037030020002000290000370360200041a0016a41186a2007290300370300200041a0016a41106a2006290300370300200041a0016a41086a200529030037030020002000290380023703a00120012002200041e0006a200041a0016a10164521000b200441a0026a240020000bc50101037f230041206b220224002002410036021020014110200241106a10062101024002400240024020022802102203417f460d0020010d010b200041003602040c010b200220013602082002200336020c20034104490d0120022003417c6a36020c2002200141046a36020820012800002103200241106a200241086a10820120022802102204450d012000200229021437020820002004360204200020033602002001102a0b200241206a24000f0b41c4d1c3004133200241106a419cd9c3001038000be80201057f230041b0036b22022400200241003602a80220014110200241a8026a1006210302400240024020022802a8022201417f470d00200041133602000c010b20022001360294012002200336029001200241a8026a20024190016a10810120022802a8024113460d01200241a0016a200241a8026a418801109a051a024002402002280294012204450d0020022802900122052d0000210620022004417f6a360294012002200541016a3602900120064103490d010b200241a0016a106a0c020b20022802a00121042002410c6a200241a0016a410472418401109a051a2002200228009901360204200220024199016a41036a28000036000720044113460d0120002004360200200041046a2002410c6a418401109a051a20004188016a20063a000020002002280204360089012000418c016a20022800073600002001450d002003102a0b200241b0036a24000f0b41c4d1c3004133200241a8026a419cd9c3001038000bdb0102027f037e230041206b220224002002410036021020014120200241106a10062101024002400240024020022802102203417f460d0020010d010b200041003602100c010b200220013602082002200336020c20034110490d012002200341706a36020c2002200141106a360208200141086a290000210420012900002105200241106a200241086a106d20022802102203450d0120022902142106200020043703082000200537030020002006370214200020033602102001102a0b200241206a24000f0b41c4d1c3004133200241106a419cd9c3001038000bc40101037f230041206b220224002002410036021020014120200241106a10062101024002400240024020022802102203417f460d0020010d010b200041003602040c010b200220013602082002200336020c20034104490d0120022003417c6a36020c2002200141046a36020820012800002103200241106a200241086a106d20022802102204450d012000200229021437020820002004360204200020033602002001102a0b200241206a24000f0b41c4d1c3004133200241106a419cd9c3001038000bd20101037f230041106b22022400200241003602082002420137030020012d00002103410110282104024002400240024020034101460d002004450d02200242818080801037020420022004360200200441003a0000200141086a200210e3030c010b2004450d02200242818080801037020420022004360200200441013a00002002200236020c200141016a2002410c6a10c8010b2002280204210420004120200228020022012002280208100702402004450d002001102a0b200241106a24000f0b410141011037000b410141011037000ba60a02067f027e230041106b2202240020002802102103200041186a2802002204200110b4010240024002400240024002400240024002400240200141046a2802002205200141086a28020022066b2004490d00200128020021050c010b200620046a22072006490d08200541017422062007200620074b1b22064100480d080240024020050d002006102821050c010b200128020020052006102c21050b2005450d0120012005360200200141046a2006360200200141086a28020021060b200141086a2207200620046a360200200520066a20032004109a051a200028021c210502400240200141046a2802002206200728020022046b4104490d00200128020021060c010b200441046a22032004490d08200641017422042003200420034b1b22044100480d080240024020060d002004102821060c010b200128020020062004102c21060b2006450d0220012006360200200141046a2004360200200141086a28020021040b200141086a2203200441046a360200200620046a20053600002002200136020c2000412c6a2002410c6a10c801200041086a29030021082000290300210902400240200141046a2802002206200328020022046b4110490d00200128020021060c010b200441106a22052004490d08200641017422042005200420054b1b22044100480d080240024020060d002004102821060c010b200128020020062004102c21060b2006450d0320012006360200200141046a2004360200200141086a28020021040b200141086a2205200441106a360200200620046a22042008370008200420093700002000280220210302400240200141046a2802002206200528020022046b4104490d00200128020021060c010b200441046a22052004490d08200641017422042005200420054b1b22044100480d080240024020060d002004102821060c010b200128020020062004102c21060b2006450d0420012006360200200141046a2004360200200141086a28020021040b200141086a2205200441046a360200200620046a20033600000240024020002802244101460d0002400240200141046a28020020052802002200460d00200128020021040c010b200041016a22042000490d0a200041017422062004200620044b1b22064100480d0a0240024020000d002006102821040c010b200128020020002006102c21040b2004450d0720012004360200200141046a2006360200200141086a28020021000b200141086a200041016a360200200420006a41003a00000c010b02400240200141046a28020020052802002204460d00200128020021060c010b200441016a22062004490d09200441017422052006200520064b1b22054100480d090240024020040d002005102821060c010b200128020020042005102c21060b2006450d0720012006360200200141046a2005360200200141086a28020021040b200141086a2205200441016a360200200620046a41013a00002000280228210602400240200141046a2802002204200528020022006b4104490d00200128020021040c010b200041046a22052000490d09200441017422002005200020054b1b22004100480d090240024020040d002000102821040c010b200128020020042000102c21040b2004450d0820012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a20063600000b200241106a24000f0b200641011037000b200441011037000b200441011037000b200441011037000b200641011037000b200541011037000b200041011037000b1031000b910101047f230041106b2201240041002102200141003602044188e8c2004110200141046a1006210302400240024020012802042204417f470d000c010b024020030d000c010b20044104490d01200328000021042003102a4188e8c20041101009410121020b2000200236020020002004360204200141106a24000f0b41c4d1c3004133200141086a419cd9c3001038000bfb0103017f017e027f230041206b2201240042002102200141106a41086a220342003703002001420037031041affec5004111200141106a1008200141086a2003290300370300200120012903103703002001410036021020014110200141106a100621030240024020012802102204417f460d002003450d0020044108490d01200329000021022003102a0b200141106a41086a220342003703002001420037031041affec5004111200141106a1008200141086a2003290300370300200120012903103703002001200220007c37031020014110200141106a41081007200141206a24000f0b41c4d1c3004133200141106a419cd9c3001038000b1300200041053602042000418cdac3003602000b3400200041a4d5c30036020420004100360200200041146a4107360200200041106a41e4ecc300360200200041086a42083702000b3701017f02404110102822020d00411041011037000b2002420037000820024201370000200042908080808002370204200020023602000bc70101017f23004190016b22022400200241003a00782002428080848080023703682002420137035820024201370350200242af0137034820024287013703402002420137033820024201370330200242013703282002420137032020024201370318200242013703102002420137030820024280808080c00037036020024280808180800437037020024100360288012002420137038001200241086a20024180016a10ee01200041086a200228028801360200200020022903800137020020024190016a24000b130020004110360204200041c0f6c3003602000b3301017f02404108102822020d00410841011037000b2000428880808080013702042000200236020020024280ade2043700000b3201017f02404104102822020d00410441011037000b20004284808080c000370204200020023602002002418080013600000b3101017f02404104102822020d00410441011037000b20004284808080c0003702042000200236020020024180083600000b3101017f02404108102822020d00410841011037000b20004288808080800137020420002002360200200242e8073700000b3c01017f02404110102822020d00411041011037000b2002420037000820024280a094a58d1d370000200042908080808002370204200020023602000b3b01017f02404110102822020d00411041011037000b2002420037000820024280c8afa025370000200042908080808002370204200020023602000b3e01017f02404110102822020d00411041011037000b20024200370008200242808086bdbacdd21a370000200042908080808002370204200020023602000b3f01017f02404110102822020d00411041011037000b200242003700082002428080a8ec85afd1b101370000200042908080808002370204200020023602000b3001017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241083600000b3001017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241023600000bc81603027f047e117f230041a0096b22072400200741e0006a41186a200141186a290000370300200741e0006a41106a200141106a290000370300200741e0006a41086a200141086a2900003703002007200129000037036020074180016a41186a200241186a29000037030020074180016a41106a200241106a29000037030020074180016a41086a200241086a2900003703002007200229000037038001200628020021012006280204210220062802082108200741d0006a10f6030240024002400240024020072903502209200741d0006a41086a290300220a8450450d004200210b4200210c0c010b200741306a200a420020054200109f05200741c0006a2009420020054200109f05200741206a4200420020094200109f0502402007290338200729032884420052200741c0006a41086a290300220b200729033020072903207c7c220c200b5472450d004127210641a6b5c00021080c020b2007290340210b0b200741c0016a200741e0006a200b200c41081098024101210d20072802c0014101470d0120072802c801210620072802c40121080b2000200836020420004101360200200041146a41003602002000410c6a4201370200200041086a20063602002002450d012001102a0c010b200741c0016a41106a290300210b20072903c801210c200741a0016a41186a220e200a370300200720093703b001200720053703a801200720053703a001200741c0016a10f703200741c0026a4200370300200741f0026a4200370300200741e0026a4200370300200741d0026a42003703002007428080e983b1de163703b80220074280a094a58d1d3703e80220074280a094a58d1d3703d80220074280a094a58d1d3703c802200742808880808080103703f8022007200741c0016a360280032007200741c0016a36028403200741d0056a41186a220f200741e0006a41186a290300370300200741d0056a41106a2206200741e0006a41106a290300370300200741d0056a41086a2210200741e0006a41086a290300370300200720072903603703d00510a00321051098012111200741c0036a4200370300200741b4036a41d0b5c000360200200741b0036a4101360200200741a8036a4200370300200741a4036a41f8b9c000360200200741e0036a2010290300370300200741e8036a2006290300370300200741f0036a200f29030037030020074200370390032007428080808080013703b803200741003602a003200720072903d0053703d803200720074184036a3602d003200720074180036a3602cc032007200741c0016a3602c803200720113602d4032007200537038803200f20074180016a41186a290300370300200620074180016a41106a290300370300201020074180016a41086a29030037030020072007290380013703d005200720083602a804200720023602a404200720013602a004200741f8036a20074188036a200741d0056a20032004200741a0016a200741a0046a10c101024020072802f8030d00200741f8036a41106a2d00000d00200741d0056a41086a200741a8036a290300370300200741a0046a41086a200741dc056a280200360200200720072903a0033703d005200720072902d4053703a00420074198096a200741a0046a1092014100210d0b200720072903b001200e29030020072903a80122054200109f0520072903a00120057d10e503200741106a200741e0006a2007290300200741086a29030010d0012006200b200741106a41086a29030022097d200c2007290310220554ad7d2009200b7d2005200c54ad7d2005200c582009200b582009200b5122021b22011b220a3703002007200c20057d2005200c7d20011b22033703d80520072005200c562009200b5620021b2202ad22053703d00541012101024020020d00200720033703a0042007200a3703a8042007200741a0046a3602e007200741e0076a109d014100210120072903d00521050b0240024020054200520d002001450d01200720103602a004200741a0046a109d010c010b200720103602a004200741a0046a109c010b20072802c403210120072802c0032106200720072802bc032202360298042007200636029404200720023602900420072002200141b0016c6a221236029c0402402001450d00200741e0076a410172211320074187076a2114200741e9076a210820074180076a4102722110200741d0056a41106a2115200741f8056a2116200741b4066a211720074191066a210f200741f1056a210e200741d0056a4101722118200741c8066a2119034020022d00002101200741a0046a200241016a41af01109a051a0240024020014103460d00200720013a00d0052018200741a0046a41af01109a052106024002400240024020010e03000102000b20072802d805211a20072802dc05210620072802d40521012014201541d800109a051a2007410c3a00e007201320074180076a41df00109a051a20012006200741e0076a10cc0141012106410021110240201a450d002001102a0b4100211a0c020b200741e8086a41186a2201200641186a2211290000370300200741e8086a41106a221a200641106a221b290000370300200741e8086a41086a221c200641086a221d290000370300200720062900003703e808200741e0076a2016418801109a051a20102006290000370000201041086a201d290000370000201041106a201b290000370000201041186a201129000037000020074180023b01800720074188096a200741e0076a20074180076a10f40120072d0090092106200820072903e808370000200841086a201c290300370000200841106a201a290300370000200841186a2001290300370000200741043a00e8072007410c3a00e007200720064102463a008908410021064101211141014100200741e0076a10cc014100211a0c010b2019290300210520072903c0062109200741e8086a41186a200641186a290000370300200741e8086a41106a200641106a290000370300200741e8086a41086a200641086a290000370300200720062900003703e80820074180076a41186a200e41186a29000037030020074180076a41106a200e41106a29000037030020074180076a41086a200e41086a2900003703002007200e29000037038007200741e0076a41186a200f41186a290000370300200741e0076a41106a200f41106a290000370300200741e0076a41086a200f41086a2900003703002007200f2900003703e00720074188096a41086a201741086a2802003602002007201729020037038809200741e8086a20074180076a200741e0076a2009200520074188096a10f80341012111410121064101211a0b024020072d00d005220141014b0d000240024020010e020001000b2011450d03024020072802d805450d0020072802d405102a0b20072d00e0054105490d03200728028806450d03200728028406102a0c030b2006450d022016106a0c020b201a20072802b80645720d0120072802b406102a0c010b2007200241b0016a360298040c020b200241b0016a22022012470d000b20072012360298040b20074190046a1069200041106a200741f8036a41106a290300370200200041086a200741f8036a41086a290300370200200020072903f80337020002402007280294032202450d0020074188036a41106a280200450d002002102a0b200d450d0020074188036a411c6a280200210220072802ac0321080240024020072802a80322060d00200221010c010b2006210020022101034020012802880b21012000417f6a22000d000b0340200220022f01064102746a41880b6a28020021022006417f6a22060d000b0b200741d0056a411c6a20022f0106360200200741e8056a4100360200200741e4056a2002360200200720083602f005200741003602e005200742003703d805200720013602d405200741003602d005200741d0056a109b010b200741a0096a24000bc70104017f017e027f017e230041206b2201240042002102200141106a41086a22034200370300200142003703104188d9c3004111200141106a1008200141086a2003290300370300200120012903103703002001410036021020014110200141106a1006210302400240024020012802102204417f470d00420121050c010b20044110490d01200341086a2900002102200329000021052003102a0b2000200537030020002002370308200141206a24000f0b41c4d1c3004133200141106a419cd9c3001038000be20301047f23004190026b2201240020014190016a41086a22024200370300200142003703900141c0fec500411820014190016a100820014180016a41086a2002290300370300200120012903900137038001200141003602900120014180016a411020014190016a100621030240024002402001280290012204417f470d00410221020c010b2001200436028c02200120033602880220014190016a20014188026a10ea0120012d00800222024102460d01200141106a20014190016a41f000109a051a200120014184026a28000036000b20012001280081023602082004450d002003102a0b20014190016a200141106a41f000109a051a2001200128000b3600830120012001280208360280010240024020024102470d002000428080818080043703682000428080848080023703602000420137035020004201370348200042af0137034020004287013703382000420137033020004201370328200042013703202000420137031820004201370310200042013703082000420137030020004280808080c000370358410021020c010b200020014190016a41f000109a05220441f4006a20012800830136000020042001280280013600710b200020023a007020014190026a24000f0b41c4d1c3004133200141106a419cd9c3001038000b891d01117f230041b0036b2206240020064190026a2000108c01410221070240024020062d00900222084102470d00410121094134210a410221080c010b20064190036a41086a2209200641a4026a29020037030020064190036a41106a220b200641ac026a29020037030020064190036a41186a220c200641b4026a290200370300200641e8026a41086a220d200641c8026a290300370300200641e8026a41106a220e200641d0026a290300370300200641e8026a41186a220f200641d8026a290300370300200641e8026a41206a2210200641e0026a29030037030020062006419c026a290200370390032006200641c0026a2903003703e80220064190026a41086a280200210a024020080d00200641bc026a2802002107200641e8016a41186a200c290300370300200641e8016a41106a200b290300370300200641e8016a41086a2009290300370300200641c0016a41086a200d290300370300200641c0016a41106a200e290300370300200641c0016a41186a200f290300370300200641c0016a41206a201029030037030020062006290390033703e801200620062903e8023703c0010b41022108024020074102470d00410121094134210a0c010b200641e8026a41186a200641e8016a41186a290300370300200641e8026a41106a200641e8016a41106a290300370300200641e8026a41086a200641e8016a41086a29030037030020064190026a41086a200641c0016a41086a29030037030020064190026a41106a200641c0016a41106a29030037030020064190026a41186a200641c0016a41186a29030037030020064190026a41206a200641c0016a41206a290300370300200620062903e8013703e802200620062903c0013703900241002109200721080b200641a0016a41086a2207200641e8026a41086a290300370300200641a0016a41106a220b200641e8026a41106a290300370300200641a0016a41186a220c200641e8026a41186a290300370300200641f8006a41086a220d20064190026a41086a290300370300200641f8006a41106a220e20064190026a41106a290300370300200641f8006a41186a220f20064190026a41186a290300370300200641f8006a41206a221020064190026a41206a290300370300200620062903e8023703a00120062006290390023703780240024020090d00200641d0006a22112006290378370300200641346a20072903003702002006413c6a200b290300370200200641c4006a200c290300370200200641d8006a200d290300370300200641e0006a200e290300370300200641e8006a200f290300370300200641f0006a20102903003703002006200a360228200620062903a00137022c2006200836024c41012109109801210d0240024020084101470d002011280200200d460d010b20064190026a2001108c010240024020062d009002220a4102470d00412e210a419d8fc400210b0c010b200641e8016a41026a20062d0093023a0000200641e8026a41086a2209200641a4026a280200360200200620062f0091023b01e80120062006419c026a2902003703e802200641ac026a2802002108200641a8026a28020021070240200a0d0041012109412e210a419d8fc400210b024020080d000c020b2007102a0c010b20064190026a41086a280200210a200628029402210b200641a0016a41026a200641e8016a41026a2d00003a0000200641c0016a41086a2009280200360200200620062f01e8013b01a001200620062903e8023703c001200641b0026a2d0000210c410021090b2006418c026a41026a200641a0016a41026a2d00003a000020064190036a41086a220e200641c0016a41086a280200360200200620062f01a0013b018c02200620062903c0013703900320090d002006418b016a200e280200360000200620062f018c023b01782006200a36007f2006200b36007b2006200629039003370083012006200c3a00970120062008360093012006200736008f0120062006418e026a2d00003a007a200628024c211220062802502113200620052802002211200541086a28020022144105746a3602940320062011360290032006200641286a3602980320064190026a20064190036a106802400240024002400240024002400240024002402006280290020d0041002109200641003602f001200642043703e801410421074100210a0c010b411010282207450d012007200629039002370200200741086a20064190026a41086a220b290300370200200641c0016a41086a20064190036a41086a28020036020020062006290390033703c001200641e8026a200641c0016a10680240024020062802e8020d00410121094101210a0c010b410121084101210a0340200b200641e8026a41086a290300370300200620062903e8023703900202400240200a2008460d00200841016a21090c010b200841016a22092008490d082008410174220a2009200a20094b1b220a41ffffffff0071200a470d08200a410474220c4100480d080240024020080d00200c102821070c010b20072008410474200c102c21070b2007450d050b200720084104746a2208200629039002370200200841086a200b290300370200200641e8026a200641c0016a10682009210820062802e8020d000b0b200620093602f0012006200a3602ec01200620073602e8010b200641286a41186a28020021082006280238210b2006410036029002200b200820064190026a100d2110200628029002220f417f460d02200641e8026a41186a200241186a290000370300200641e8026a41106a200241106a290000370300200641e8026a41086a200241086a290000370300200620022900003703e802200641003602980320064201370390032010200f20064190036a10b20202400240200628029403220e200628029803220c6b4120490d00200c41206a210b20062802900321080c010b200c41206a220b200c490d05200e4101742208200b2008200b4b1b22154100480d0502400240200e0d002015102821080c010b200628029003200e2015102c21080b2008450d04200620153602940320062008360290032015210e0b2006200b360298032008200c6a220c20062903e802370000200c41086a200641e8026a41086a290300370000200c41106a200641e8026a41106a290300370000200c41186a200641e8026a41186a29030037000020064190026a41186a220c420037030020064190026a41106a2215420037030020064190026a41086a2216420037030020064200370390022008200b20064190026a1000200641c0016a41186a200c290300370300200641c0016a41106a2015290300370300200641c0016a41086a201629030037030020062006290390023703c0010240200e450d002008102a0b0240200f450d002010102a0b0240200641c0016a200641f8006a4120109c050d000240024020090d004100210b0c010b2009410474210c2007410c6a21084100210b03402008280200200b6a210b200841106a2108200c41706a220c0d000b0b20062006280244200b6b360244411710282208450d06200d201320141b210f4101201220141b2110200641286a41106a210b200841002900f1d8433700002008410f6a4100290080d943370000200841086a41002900f9d84337000020064297808080f002370294032006200836029003200020064190036a108f012006280298032115200628029003211620064190026a41186a2208420037030020064190026a41106a220c420037030020064190026a41086a220e420037030020064200370390022016201520064190026a1000200641e8026a41186a2008290300370300200641e8026a41106a200c290300370300200641e8026a41086a200e29030037030020062006290390023703e8020240200628029403450d00200628029003102a0b200641e8026a41201009200c2004370300200641c0026a200f360200200641bc026a2010360200200641b8026a200d360200200641b4026a20062802443602002008200b29030037030020064190026a41206a200b41086a280200360200200641c4026a2002290000370200200641cc026a200241086a290000370200200641d4026a200241106a290000370200200641dc026a200241186a2900003702002006200337039802200641003a009002200120064190026a109a01200641186a2000109101200641186a41086a29030021032006290318210420064190026a200042004200109401024002402006290390024200520d002006200e3602e802200641e8026a109c010c010b2006200e3602e802200641e8026a109d010b200641086a20012004200310d0012006200641106a290300370398022006200629030837039002200620064190026a3602e802200641e8026a109c0102402009450d0020094104742109200741046a210803400240200841046a280200450d002008280200102a0b200841106a2108200941706a22090d000b0b0240200a450d002007102a0b200541046a280200450d0b2011102a0c0b0b200720094104746a2101200721082009450d0620072108034002402008280200220b0d00200841106a21080c080b200841046a2802002109200841086a28020021002008410c6a280200210c200628024021022006280238210d20064190026a41186a220e420037030020064190026a41106a220f420037030020064190026a41086a221042003703002006420037039002200b412020064190026a1000200641e8026a41186a200e290300370300200641e8026a41106a200f290300370300200641e8026a41086a201029030037030020062006290390023703e802200d2002200641e8026a41202009200c100502402000450d002009102a0b200841106a22082001470d000c080b0b411041041037000b200c41041037000b41eef3c50041381050000b201541011037000b1031000b411741011037000b20082001460d0003402008280200450d010240200841086a280200450d00200841046a280200102a0b200841106a22082001470d000b0b200a450d002007102a0b2006413c6a280200450d002006280238102a0b200541046a280200450d002005280200102a0b200641b0036a24000bf46504177f017e077f017e23004180036b2204240041002105200441003602f002200420023602ec02200420013602e8020240024002400240024002400240200241034b0d0041012106200441013a00d002200441ec016a4101360200200442013702dc01200441a4e2c5003602d801200441263602c4022004200441c0026a3602e8012004200441d0026a3602c00220044180016a200441d8016a10332004280280012107200428028401210820042802880121094105210a4100210b0c010b200441043602f002024020012800004180c2cdeb06460d004101210a410121060c010b024002402002417c714104460d00200241074b0d0141082002103c000b41012106200441013a00d002200441ec016a4101360200200442013702dc01200441a4e2c5003602d801200441263602c4022004200441c0026a3602e8012004200441d0026a3602c00220044180016a200441d8016a10332004280280012107200428028401210820042802880121094105210a410021054100210b0c010b200441083602f002410121060240200128000422074101460d004102210a0c010b200441d8016a200441e8026a10fa0402400240024020042802d8014101470d00410421084100210c410021090c010b200441d8016a410572210d41042108412c210a410021054100210c410021094100210b02400340200441d0026a41026a2201200d41026a2d00003a00002004200d2f00003b01d002200428028802210e200428028402210f200428028002211020042802fc01211120042802f801211220042802f401211320042802f001211420042802ec01211520042802e801211620042802e401211720042802e0012118024020042d00dc012206417e6a41ff0171410b4b0d0041002119024002400240024002400240024002400240024002400240024020060e100c0c000102030405060708090a0b0c0c0c0b410121190c0b0b410221190c0a0b410321190c090b410421190c080b410521190c070b410621190c060b410721190c050b410821190c040b410921190c030b410a21190c020b410b21190c010b410c21190b0240200b41ff0171221a20194d0d004113210a0c030b41002119024002400240024002400240024002400240024002400240024020060e100c0c000102030405060708090a0b0c0c0c0b410121190c0b0b410221190c0a0b410321190c090b410421190c080b410521190c070b410621190c060b410721190c050b410821190c040b410921190c030b410a21190c020b410b21190c010b410c21190b0240201a2019470d004114210a0c030b4100210b02400240024002400240024002400240024002400240024020060e100c0c000102030405060708090a0b0c0c0c0b4101210b0c0b0b4102210b0c0a0b4103210b0c090b4104210b0c080b4105210b0c070b4106210b0c060b4107210b0c050b4108210b0c040b4109210b0c030b410a210b0c020b410b210b0c010b410c210b0b20044180016a41026a221920012d00003a0000200420042f01d0023b01800102400240200c2009470d00200c41016a2201200c490d0720052001200520014b1b2209ad42307e221b422088a70d07201ba722014100480d0702400240200c0d002001102821080c010b2008200a41546a2001102c21080b2008450d010b2008200a6a220141546a20063a00002001200e3602002001417c6a200f360200200141786a2010360200200141746a2011360200200141706a20123602002001416c6a2013360200200141686a2014360200200141646a2015360200200141606a20163602002001415c6a2017360200200141586a2018360200200141556a220120042f0180013b0000200141026a20192d00003a0000200541026a2105200a41306a210a200c41016a210c200441d8016a200441e8026a10fa0420042802d8014101460d030c010b0b200141041037000b024002402006410e4b0d00024002400240024002400240024002400240024002400240024020060e0f0001020304050607080e090e0a0b0c000b2017450d0d2018102a0c0d0b02402017450d002018102a0b2014450d0c2015102a0c0c0b02402016450d00201641047421062018210103400240200141046a280200450d002001280200102a0b200141106a2101200641706a22060d000b0b2017450d0b2018102a0c0b0b02402016450d00201641286c21062018210103400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101200641586a22060d000b0b2017450d0a2018102a0c0a0b2017450d092018102a0c090b2017450d082018102a0c080b2017450d072018102a0c070b02402016450d00201820164104746a2114201821160340024020162802082206450d0020162802002101200641047421060340024020012d00004109470d000240200141046a220d280200220528020441ffffffff0371450d002005280200102a200d28020021050b2005102a0b200141106a2101200641706a22060d000b0b201641106a21010240201641046a280200450d002016280200102a0b2001211620012014470d000b0b2017450d062018102a0c060b02402016450d00201641146c21062018210103400240200141046a280200450d002001280200102a0b200141146a21012006416c6a22060d000b0b2017450d052018102a0c050b02402016450d0020182016411c6c6a2114201821160340024020162802042201450d0002402016410c6a2802002206450d00200641047421060340024020012d00004109470d000240200141046a220d280200220528020441ffffffff0371450d002005280200102a200d28020021050b2005102a0b200141106a2101200641706a22060d000b0b201641086a280200450d002016280204102a0b2016411c6a21010240201641146a280200450d002016280210102a0b2001211620012014470d000b0b2017450d042018102a0c040b02402016450d002018201641186c6a21142018211603400240201641046a280200450d002016280200102a0b0240201641146a2802002206450d00201628020c2101200641047421060340024020012d00004109470d000240200141046a220d280200220528020441ffffffff0371450d002005280200102a200d28020021050b2005102a0b200141106a2101200641706a22060d000b0b201641186a21010240201641106a280200450d00201628020c102a0b2001211620012014470d000b0b2017450d032018102a0c030b02402016450d0020182016411c6c6a2114201821160340024020162802042201450d0002402016410c6a2802002206450d00200641047421060340024020012d00004109470d000240200141046a220d280200220528020441ffffffff0371450d002005280200102a200d28020021050b2005102a0b200141106a2101200641706a22060d000b0b201641086a280200450d002016280204102a0b2016411c6a21010240201641146a280200450d002016280210102a0b2001211620012014470d000b0b2017450d022018102a0c020b02402018450d002017450d002018102a0b02402014450d0002402012450d002012410c6c2106201421010340024020012802002205450d00200141046a280200450d002005102a0b2001410c6a2101200641746a22060d000b0b2013450d002014102a0b2010450d010240200e450d002010200e4104746a21172010211803402018220d41106a21180240200d2802042201450d000240200d410c6a2802002206450d002006410c6c21060340024020012802002205450d00200141046a280200450d002005102a0b2001410c6a2101200641746a22060d000b0b200d41086a280200450d00200d280204102a0b20182017470d000b0b200f450d012010102a0c010b02402017450d002018102a0b02402014450d002013450d002014102a0b2010450d002011102a0b0c010b024020042d00dc010d002008200c41306c6a21062008210102400340024020062001470d004100210d0c020b20012d0000210a200141306a220b2101200a410c470d000b200b415c6a280200210d0b2008200c41306c6a210b20082101024003404100210a0240200b2001470d00410021010c020b20012d00002106200141306a2205210120064104470d000b200441f8006a200541546a10fa03200428027c21010b0240200d2001470d004101210741e100210b41f3da012105410021060c030b0240200c450d00200c41306c210a2008210103402001108204200141306a2101200a41506a220a0d000b0b41012106411a210a024020090d000c030b2008102a0c020b20042802dc01220a4110762105200a410876210b200441d8016a41106a280200210d200441e4016a2802002118200441d8016a41086a28020021070b0240200c450d00200c41306c21062008210103402001108204200141306a2101200641506a22060d000b0b4101210602402009450d002008102a0b200d2109201821080b02402006450d00200821060c040b20042802f0022002470d022005411074200b41ff017141087472200a41ff017172211c2008200c41306c6a210a200821010240024002400240024002400240024002400240024002400340200a2001460d0120012d00002102200141306a2206210120024102470d000b200441f0006a200641546a10fa034104211d02402004280274221e0d004100211e0c020b201e41047422014100480d0c2004280270210220011028221d450d0a201e410474210641002115201d21010340200241086a280200220a417f4c0d042002410c6a2d0000210b2002280200210502400240200a0d004101210d0c010b200a1028220d450d060b200d2005200a109a0521052001410d6a2002410d6a2d00003a00002001410c6a200b3a0000200141086a200a360200200141046a200a36020020012005360200200141106a2101201541016a2115200241106a2102200641706a22060d000b201d0d020b4100211e4104211d0b410021150b2008200c41306c6a210a2008210102400340410021174104210b0240200a2001470d0041042102410021010c020b20012d00002102200141306a2206210120024103470d000b200441e8006a200641546a10fa0341042102410021012004280268220a450d00200428026c2101200a21020b024020010d004101211a41002102410021184100210541002110410121124100210a4100211141042116410021064100211f410421134100210e0c090b200141286c210d2002411c6a21014104210b410021174101211a41002102410021184100210541002110410121124100210a4100211141042116410021064100211f410421134100210e0340024002400240024002402001417c6a2d00000e0400010203000b20012802002114024020022018470d00200241016a22182002490d0f2002410174220f2018200f20184b1b221841ffffffff03712018470d0f2018410274220f4100480d0f0240024020020d00200f1028210b0c010b200b2002410274200f102c210b0b200b450d080b200b20024102746a2014360200200241016a21020c030b200441d8016a41086a2214200141086a280200360200200420012902003703d8010240200a2011470d00200a41016a2211200a490d0e200a410174220f2011200f20114b1b2211ad420c7e221b422088a70d0e201ba7220f4100480d0e02400240200a0d00200f102821160c010b2016200a410c6c200f102c21160b2016450d080b2016200a410c6c6a220f20042903d801370200200f41086a2014280200360200200a41016a210a0c020b200441d8016a41086a2214200141086a280200360200200420012902003703d80102402006201f470d00200641016a220f2006490d0d20064101742219200f2019200f4b1b221fad420c7e221b422088a70d0d201ba7220f4100480d0d0240024020060d00200f102821130c010b20132006410c6c200f102c21130b2013450d080b20132006410c6c6a220f20042903d801370200200f41086a2014280200360200200641016a21060c010b2001417e6a22142d0000210f2001417d6a22192d00002120024020052010470d00200541016a22102005490d0c200541017422212010202120104b1b221020106a22222010490d0c20224100480d0c0240024020050d002022102821120c010b201220212022102c21120b2012450d080b201220054101746a2222200f4101713a0001202220203a000020142d0000211420192d0000210f02400240200e2017460d00200e21190c010b201741016a22192017490d0c201741017422222019202220194b1b222020206a22192020490d0c20194100480d0c0240024020170d0020191028211a0c010b201a20222019102c211a0b201a450d0920172119202021170b200541016a2105201a20194101746a221920144101713a00012019200f3a0000200e41016a210e0b200141286a2101200d41586a220d450d090c000b0b1036000b200a41011037000b200f41041037000b200f41041037000b200f41041037000b202241011037000b201941011037000b200141041037000b2008200c41306c6a21142008210102400240024002400240024002400240024002400240024002400240034020142001460d0120012d0000210d200141306a220f2101200d4104470d000b200441e0006a200f41546a10fa0320042802642201450d002004280260210d2001410274210f20024101742114200241027421010340200d2802002119024020022018470d00200241016a22182002490d1020142018201420184b1b221841ffffffff03712018470d10201841027422204100480d100240024020020d0020201028210b0c010b200b20012020102c210b0b200b450d030b200d41046a210d200b20016a2019360200201441026a2114200141046a2101200241016a2102200f417c6a220f0d000b0b2008200c41306c6a21142008210102400240034020142001460d0120012d0000210d200141306a220f2101200d4105470d000b200441d8006a200f41546a10fa03200428025c410c6c2219450d0020042802582101200a4101742114200a410c6c210d0340200141086a210f024002400240200141046a2802004101470d002004200f28020022203602c0022001280200222220204b0d010b20044100360280010c010b200441023602ec01200442023702dc01200441e8a7c6003602d801200441013602f402200441013602ec02200420223602d0022004200441e8026a3602e8012004200441d0026a3602f0022004200441c0026a3602e80220044180016a200441d8016a1033200428028001450d0020044180016a21010c0e0b2001290200211b200441d8016a41086a2220200f2802003602002004201b3703d8010240200a2011470d00200a41016a2211200a490d1120142011201420114b1b2211ad420c7e221b422088a70d11201ba7220f4100480d1102400240200a0d00200f102821160c010b2016200d200f102c21160b2016450d030b2001410c6a21012016200d6a220f20042903d801370200200f41086a2020280200360200201441026a2114200d410c6a210d200a41016a210a201941746a22190d000b0b2008200c41306c6a21142008210102400240034020142001460d0120012d0000210d200141306a220f2101200d4106470d000b200441d0006a200f41546a10fa032004280254220d450d0020042802502101200d410c6c210f200641017421142006410c6c210d0340200441d8016a2001108305024020042802d801450d00200441d8016a21010c0f0b2001290200211b200441d8016a41086a2219200141086a2802003602002004201b3703d80102402006201f470d00200641016a221f2006490d122014201f2014201f4b1b221fad420c7e221b422088a70d12201ba722204100480d120240024020060d002020102821130c010b2013200d2020102c21130b2013450d030b2001410c6a21012013200d6a222020042903d801370200202041086a2019280200360200201441026a2114200d410c6a210d200641016a2106200f41746a220f0d000b0b2008200c41306c6a21142008210102400240034020142001460d0120012d0000210d200141306a220f2101200d4107470d000b200441c8006a200f41546a10fa03200428024c220d450d0020042802482201200d4104746a21222005410174210d200441d8016a41047221200340200441d8016a2001201a200e10840502400240024020042d00d8014101460d00200420042d00d90122143a00c002024020142001410c6a2d0000220f470d0020044100360280010c030b200441023602ec01200442023702dc01200441fca8c6003602d801200441273602f402200441273602ec022004200f3a00d0022004200441e8026a3602e8012004200441c0026a3602f0022004200441d0026a3602e80220044180016a200441d8016a10330c010b20044180016a41086a202041086a28020036020020042020290200370380010b0240200428028001450d0020044180016a21010c110b2001410c6a2d000021140b2001410d6a2d0000210f024020052010470d00200541016a22102005490d13200d2010200d20104b1b221020106a22192010490d1320194100480d130240024020050d002019102821120c010b2012200d2019102c21120b2012450d030b2012200d6a221920143a0000201941016a200f4101713a0000200d41026a210d200541016a2105200141106a22012022470d000b0b200441b8016a2002360200200441b4016a2018360200200441ac016a2015360200200441a8016a201e360200200441a0016a20053602002004419c016a201036020020044194016a200a36020020044190016a20113602002004200b3602b0012004201d3602a40120042012360298012004201636028c0120042006360288012004201f3602840120042013360280012008200c41306c6a210a20082101024003400240200a2001470d004100210b0c020b20012d00002102200141306a2206210120024104470d000b200441c0006a200641546a10fa032004280244210b0b2004200b3602bc012008200c41306c6a210a20082101024003400240200a2001470d00410021010c020b20012d00002102200141306a220621012002410c470d000b2006415c6a28020021010b200420013602c001200b2001470d0a024002400240200b450d002008200c41306c6a210a200821010340200a2001460d0320012d00002102200141306a2206210120024104470d000b2008200c41306c6a210b200821010340200b2001460d0220012d00002102200141306a220a21012002410c470d000b200441386a200641546a10fa03200428023c2201450d002004280238220d20014102746a2114200a415c6a2118200a41546a211620044191026a210f410021050340200420053602c4012018280200210120162802002102200442013702dc012004418487c6003602d801200441013602d402200441013602ec012004200441d0026a3602e8012004200441c4016a3602d002200441e8026a200441d8016a103320042802e802210a20042902ec02211b200120054d0d100240201ba7450d00200a102a0b2004200d28020022013602c002024002400240024020042802ac0120014b0d00200441013602ec01200442023702dc0120044188acc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a103320042902ec02221b422088a7210120042802e8022106201ba721020c010b0240024002402002200541186c6a22022802142215450d0020042802a40120014104746a220a2d000d2110200a2802002111200228020c210120022802002113200a2802082212210602402002280208220e450d00200e410374210b201221022013210a034002402002200a2802006a220620024f0d0002404120102822060d00412041011037000b200641186a41002900e8ae46370000200641106a41002900e0ae46370000200641086a41002900d8ae46370000200641002900d0ae463700000c040b200a41086a210a20062102200b41786a220b0d000b0b0240410810282202450d0020022010ad42ff0183422886370200200441d0026a41026a220a200441e8026a41026a2d00003a0000200420042f00e8023b01d002200420103a00900220044180800136028c022004428180808010370284022004200236028002200442808080808080103703f801200442013703f001200420063602ec012004200e3602e801200420133602e401200420123602e001200420113602dc01200420044180016a3602d801200f20042f01d0023b0000200f41026a200a2d00003a00002015410474210a41002102034020042002360298022004200136029c02200441b0026a200441d8016a2001108505024020042802b002450d00200441c0026a41086a200441b0026a41086a280200360200200420042903b0023703c002200441033602e402200442033702d402200441e881c6003602d002200441283602fc02200441013602f402200441293602ec022004200441e8026a3602e0022004200441c0026a3602f802200420044198026a3602f00220042004419c026a3602e802200441a0026a200441d0026a1033024020042802c402450d0020042802c002102a0b20042802a0022206450d0020042902a402211b024020042802f401450d0020042802f001102a0b201b42208821230240200428028402450d00200428028002102a0b2023a72101201ba721020c070b200141106a2101200241016a2102200a41706a220a0d000b02402004280288020d00024020042802f401450d0020042802f001102a0b200428028402450d07200428028002102a0c070b418082c6001032000b410841041037000b412010282206450d01200641186a41002900df8146370000200641106a41002900d78146370000200641086a41002900cf8146370000200641002900c781463700000b41202102412021010c010b412041011037000b2006450d010b200420063602d00220042001ad4220862002ad843702d4022004200441d0026a3602c002200441023602ec01200442023702dc012004418c87c6003602d8012004412a3602f402200441013602ec022004200441e8026a3602e8012004200441c0026a3602f0022004200441c4016a3602e802200441c8016a200441d8016a1033024020042802d402450d0020042802d002102a0b20042802c801220a450d0020042902cc01211b0c110b200541016a2105200d41046a220d2014470d000b0b2008200c41306c6a210a200821010240024002400340200a2001460d0120012d00002102200141306a2206210120024109470d000b2004200641546a28020022013602b002024020042802b80120014b0d00200441ec016a4101360200200442023702dc01200441e4abc6003602d801200441013602d4022004200441d0026a3602e8012004200441b0026a3602d002200441e8026a200441d8016a10330c0c0b200420042802b00120014102746a28020022013602c002024020042802ac0120014b0d00200441ec016a4101360200200442023702dc0120044188acc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c0c0b20042802a40120014104746a220131000d4220862001350208844280808080c000510d00412d1028220a450d01200a41256a41002900c18746370000200a41206a41002900bc8746370000200a41186a41002900b48746370000200a41106a41002900ac8746370000200a41086a41002900a48746370000200a410029009c874637000042ad808080d005211b0c110b2008200c41306c6a210a200821010340200a2001460d0a20012d00002102200141306a2206210120024108470d000b200441306a200641546a221610fa03200428023021014100210a02400240200428023422020d004104210b410021180c010b200241ffffffff01712002470d15200241037422064100480d1520061028220b450d02200221180b02402002450d002001200241146c6a21062002410274417c6a2105200b210203402001280200210a200241046a200141086a2802003602002002200a360200200241086a2102200141146a22012006470d000b200541027641016a210a0b200b200a200441d8016a41004120200a676b10fd04200b200a4103746a2206200b460d084101210a200b2101200b2102034002400240200a450d00200620016b410376200a4d0d0b2001200a4103746a22010d010c0b0b20062001460d0a0b200420023602c00202400240200241046a280200220a200141046a280200470d00200228020022052001280200220d460d012005200d200a109c05450d010b200141086a21014100210a200241086a22022006470d010c0a0b0b200441ec016a4101360200200442013702dc01200441cc87c6003602d8012004412b3602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c0c0b412d41011037000b200641041037000b41ba86c60041c8001050000b419c86c600411e1050000b201941011037000b202041041037000b200f41041037000b202041041037000b200441286a201610fa030240200428022c2201450d00200141146c2102200428022841106a210102400340024002400240024002402001417c6a2802000e0400030201000b20042001280200220a3602b002024020042802b801200a4b0d00200441ec016a4101360200200442023702dc01200441e4abc6003602d801200441013602d4022004200441d0026a3602e8012004200441b0026a3602d002200441e8026a200441d8016a10330c0b0b200420042802b001200a4102746a280200220a3602c00220042802ac01200a4b0d03200441013602ec01200442023702dc0120044188acc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c0a0b20042001280200220a3602b002024020042802a001200a4b0d00200441ec016a4101360200200442023702dc01200441a8acc6003602d801200441013602d4022004200441d0026a3602e8012004200441b0026a3602d002200441e8026a200441d8016a10330c0a0b200428029801200a4101746a2d0001450d02200441ec016a4101360200200442023702dc01200441c8acc6003602d801200441013602d4022004200441d0026a3602e8012004200441b0026a3602d002200441e8026a200441d8016a10330c090b20042001280200220a3602c002200428028801200a4b0d01200441013602ec01200442023702dc0120044194abc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a103320042802e802220a0d090c010b20042001280200220a3602c002200428029401200a4d0d020b200141146a21012002416c6a22020d000c020b0b200441ec016a4101360200200442023702dc01200441c4abc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c040b2018450d00200b102a0b2008200c41306c6a210a2008210102400340200a2001460d0120012d00002102200141306a2206210120024103470d000b200441206a200641546a10fa0320042802242201450d0020042802202106200141286c210b41002101034002400240024002400240200620016a220241186a2d00000e0400030201000b20042002411c6a28020022023602c00220042802ac0120024b0d03200441ec016a4101360200200442023702dc0120044188acc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c060b2002411a6a2d0000450d022002410c6a2802002101200241146a2802002102200441d8016a41146a4101360200200420023602d402200420013602d002200441043602c402200442013702dc01200441d487c6003602d8012004200441d0026a3602c0022004200441c0026a3602e801200441e8026a200441d8016a10330c050b200441d8016a2002411c6a10830520042802d801220a450d0120042902dc01211b0c0a0b200241206a2802004101470d002002411c6a280200210a2004200241246a28020022023602b002200a20024d0d00200441023602ec01200442023702dc01200441e8a7c6003602d801200441013602f402200441013602ec022004200a3602c0022004200441e8026a3602e8012004200441c0026a3602f0022004200441b0026a3602e802200441d0026a200441d8016a103320042802d002220a0d080b200b200141286a2201470d000b0b02400240024002400240200428029401220141014b0d00200428028801220141014b0d012008200c41306c6a210a200821010240024002400240024002400340200a2001460d0120012d00002102200141306a220621012002410d470d000b200441186a200641546a10fa0320042802182201200428021c411c6c6a2106034020012006460d012004200128020022023602c002024020042802880120024b0d00200441013602ec01200442023702dc0120044194abc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a103320042802e802220a450d0020042902ec02211b0c130b200141046a2201280200450d02200441d8016a200120042802980120042802a00110840520042d00d8014101460d03200141186a210120042d00d901450d000b41201028220a450d08200a41186a41002900848846370000200a41106a41002900fc8746370000200a41086a41002900f48746370000200a41002900ec874637000042a08080808004211b0c110b2008200c41306c6a210a2008210102400340200a2001460d0120012d00002102200141306a220621012002410a470d000b200441106a200641546a10fa0320042802142201450d002004280210220b2001411c6c6a21050340200b450d012004200b28020022013602c00220042802940120014d0d04200b280204450d05200441d8016a200b41046a20042802980120042802a00110840520042d00d8014101460d0620042d00d9010d0d200441086a200b10cd0402400240200428020c2201450d00200428020821022001410274210a20042802b801210603402004200228020022013602b0020240200620014b0d00200441ec016a4101360200200442023702dc01200441e4abc6003602d801200441013602d4022004200441d0026a3602e8012004200441b0026a3602d002200441e8026a200441d8016a10330c100b200420042802b00120014102746a28020022013602c00220042802ac0120014d0d02200241046a2102200a417c6a220a0d000b0b200b411c6a220b2005460d020c010b0b200441013602ec01200442023702dc0120044188acc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c0b0b0240200428028401450d00200428028001102a0b0240200428029001450d00200428028c01102a0b0240200428029c01450d00200428029801102a0b024020042802ac012202450d0020042802a40121012002410474210203400240200141046a280200450d002001280200102a0b200141106a2101200241706a22020d000b0b024020042802a801450d0020042802a401102a0b024020042802b401450d0020042802b001102a0b2017450d13201a102a0c130b41291028220a450d07200a41286a41002d00b488463a0000200a41206a41002900ac8846370000200a41186a41002900a48846370000200a41106a410029009c8846370000200a41086a41002900948846370000200a410029008c884637000042a98080809005211b0c0f0b200441e0016a290300211b20042802dc01210a0c0e0b200441ec016a4101360200200442023702dc01200441c4abc6003602d801200441013602d4022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c070b412a1028220a450d05200a41286a41002f00dd88463b0000200a41206a41002900d58846370000200a41186a41002900cd8846370000200a41106a41002900c58846370000200a41086a41002900bd8846370000200a41002900b5884637000042aa808080a005211b0c0c0b200441e0016a290300211b20042802dc01210a0c0b0b200441ec016a4101360200200442013702dc01200441dc87c6003602d801200441013602d402200420013602c0022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c040b200441ec016a4101360200200442013702dc01200441e487c6003602d801200441013602d402200420013602c0022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10330c030b412041011037000b412941011037000b412a41011037000b20042802e802210a20042902ec02211b0c050b024041201028220a450d00200a41186a41002900848846370000200a41106a41002900fc8746370000200a41086a41002900f48746370000200a41002900ec874637000042a08080808004211b0c050b412041011037000b20042802e802210a0b20042902ec02211b2018450d02200b102a0c020b200441ec016a4102360200200441f4026a4101360200200442023702dc012004418c86c6003602d801200441013602ec022004200441e8026a3602e8012004200441c0016a3602f0022004200441bc016a3602e802200441d0026a200441d8016a103320042802d002210a0b20042902d402211b0b0240200428028401450d00200428028001102a0b0240200428029001450d00200428028c01102a0b0240200428029c01450d00200428029801102a0b024020042802ac012202450d0020042802a40121012002410474210203400240200141046a280200450d002001280200102a0b200141106a2101200241706a22020d000b0b024020042802a801450d0020042802a401102a0b024020042802b401450d0020042802b001102a0b2017450d01201a102a200a0d040c020b2001290204211b2001280200210a02402017450d00201a102a0b0240201f450d002013102a0b02402011450d002016102a0b02402010450d002012102a0b02402015450d0020154104742102201d210103400240200141046a280200450d002001280200102a0b200141106a2101200241706a22020d000b0b0240201e450d00201d102a0b2018450d00200b102a0b200a0d020b2000201c36020420004100360200200041186a2003360200200041146a200c360200200041106a20093602002000410c6a2008360200200041086a20073602000c040b1031000b0240201ba7450d00200a102a0b200041ea8ac60036020420004101360200200041086a41133602000240200c450d00200c41306c21022008210103402001108204200141306a2101200241506a22020d000b0b2009450d022008102a0c020b200441003a00d002200441ec016a4101360200200442013702dc01200441a4e2c5003602d801200441263602c4022004200441c0026a3602e8012004200441d0026a3602c00220044180016a200441d8016a1033200428028001210720042802840121060240200c450d00200c41306c21022008210103402001108204200141306a2101200241506a22020d000b0b4105210a2009450d002008102a0b02402006450d00200a41ff01714105470d002007102a0b200041d48ac60036020420004101360200200041086a41163602000b20044180036a24000b160020002001280208360204200020012802003602000bd21301177f23004190026b220224000240024002400240024002402000280200220341f8b9c000460d00200028020421040c010b41002104200241b8016a410041d8001099051a2002411f6a220542003700002002420037011a41ec0010282203450d0120034100360200200320022902183702042003410b6a2005290000370000200341136a200241b7016a41d900109a051a20004100360204200020033602000b200141ff0171210602400340200341066a210720032f01062108410c21094100210502400240034020082005460d01200320056a210a200941086a2109200541016a210502404100417f4101200a41086a2d0000220a20064b1b200a2006461b41016a0e03000301000b0b2005417f6a21080b2004450d022004417f6a2104200320084102746a41ec006a28020021030c010b0b200320096a42013702000c030b2000200028020841016a360208024002400240024020072f01002205410b490d00200241276a41016a410041d8001099051a200241003a001941ec001028220b450d03200b4100360200200b410036000f200b4200370007200b20022f01183b0005200b41136a200241276a41d900109a051a2003410e6a2d0000210c2003280248210d2003280244210e200b41086a2003410f6a20032f010641796a2205109a052109200b41146a200341cc006a2005410374109a052106200341063b0106200b20053b010620084107490d0120092008417a6a220a6a2009200841796a22086a2209200541ffff037120086b109b051a200920013a00002006200a4103746a200620084103746a2205200b41066a22072f010020086b410374109b051a2005410136020020072f010021050c020b200341086a2209200841016a22066a200920086a2209200520086b220a109b051a200920013a0000200341146a220920064103746a200920084103746a2209200a410374109b051a200941013602002003200541016a3b01060c050b200341086a2205200841016a22096a200520086a220620072f0100220520086b220a109b051a200620013a0000200341146a220620094103746a200620084103746a2209200a410374109b051a200941013602000b2007200541016a3b01002003280200220a450d02200341046a2105200241276a41016a210f200241a8016a2101200241a0016a211020024198016a211120024190016a211220024180016a41086a2113034020052f0100210602400240024002400240200a2f01062205410b490d00200f410041d8001099051a200241003a0019200220022f01183b0108200241b7016a200241276a41d900109a051a20014200370300201042003703002011420037030020124200370300201342003703002002420037038001419c0110282209450d03200941003602002009410036000f20094200370007200920022f01083b0005200941136a200241b7016a41d900109a051a20094194016a20012903003702002009418c016a201029030037020020094184016a2011290300370200200941fc006a2012290300370200200941f4006a2013290300370200200920022903800137026c200a41c8006a2802002114200a41c4006a2802002115200a410e6a2d00002116200941086a200a410f6a200a2f0106220341796a2205109a052117200941146a200a41cc006a2005410374109a052118200941ec006a200a4188016a2003417a6a2204410274109a052107200a41063b0106200920053b010602402004450d00410021052007210303402003280200220820053b010420082009360200200341046a21032004200541016a2205470d000b0b20064107490d0120172006417a6a22036a2017200641796a22056a220820092f010620056b109b051a2008200c3a0000201820034103746a201820054103746a220820092f010620056b410374109b051a2008200e3602002008200d360204200920092f010641016a22083b01062006410274220c20076a416c6a200720034102746a2204200841ffff0371220620036b410274109b051a2004200b36020020062003490d022009200c6a41d4006a2103034020032802002208200541016a22053b010420082009360200200341046a210320052006490d000c030b0b200a41086a2209200641016a22036a200920066a2209200520066b2208109b051a2009200c3a0000200a41146a220920034103746a200920064103746a22092008410374109b051a2009200e3602002009200d360204200a200541016a22053b01062006410274200a41ec006a22096a41086a200920034102746a2209200541ffff0371220820036b410274109b051a2009200b360200200620084f0d08200a2003417f6a22054102746a41f0006a2103034020032802002209200541016a22053b01042009200a360200200341046a210320052008490d000c090b0b200a41086a2203200641016a22056a200320066a2203200a2f0106220820066b2204109b051a2003200c3a0000200a41146a220320054103746a200320064103746a22032004410374109b051a2003200e3602002003200d360204200a200841016a22033b010620064102742207200a41ec006a22086a41086a200820054102746a2204200341ffff0371220820056b410274109b051a2004200b360200200620084f0d00200a20076a41f0006a2105034020052802002203200641016a22063b01042003200a360200200541046a210520082006470d000b0b200a28020022030d012009210b2014210d2015210e2016210c0c050b419c0141041037000b200a41046a21052003210a2016210c2015210e2014210d2009210b0c000b0b41ec0041041037000b41ec0041041037000b200241b7016a41016a410041d8001099051a2002411f6a220542003700002002420037011a200220022902183703082002200529000037000f200241276a200241b7016a41d900109a051a200241a8016a22034200370300200241a0016a2209420037030020024180016a41186a2208420037030020024190016a2206420037030020024180016a41086a220a42003703002002420037038001419c0110282205450d0120054100360200200520022903083702042005410b6a200229000f370000200541136a200241276a41d900109a051a20054194016a20032903003702002005418c016a200929030037020020054184016a2008290300370200200541fc006a2006290300370200200541f4006a200a290300370200200520022903800137026c20052000280200220336026c200020053602002000200028020441016a360204200341003b010420032005360200200520052f010622034103746a220941186a200d360200200941146a200e360200200520036a41086a200c3a0000200541ec006a200341016a22034102746a200b360200200520033b0106200b20033b0104200b20053602000b20024190026a24000f0b419c0141041037000b822701377f2001410c6a28020021022001280208210341002104024002400240200141106a28020022050d00410021064100210741002108410021094100210a4100210b4100210c4100210d4100210e410021050c010b410021044100210e4100210d4100210c4100210b4100210a4100210941002108410021074100210f4100211002400340200121112010210620032005417f6a220541306c6a220128002c2112200128002821132001280024211420012800202115200128001c2116200128001821172001280014211820012800102119200128000c211a2001280008211b2001280004211c41012110024002400240024002400240024020012d0000221d417e6a221e410e4d0d004101211f0c010b4101211f4101212041012121410121224101212341012124201c21010240024002400240024002400240024002400240024002400240024002400240024002400240201e0e0f00010203040506180717080917171a000b0240200f0d002006211020112101201c210f201b2125201a21260c180b02402026450d0020264104742110200f210103400240200141046a280200450d002001280200102a0b200141106a2101201041706a22100d000b0b4101211f410021102025450d11200f102a0c110b024020070d002006211020112101201c2107201b2127201a21280c170b02402028450d00202841286c21102007210103400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101201041586a22100d000b0b4100211f410121102027450d0f2007102a0c0f0b2029450d0d2008450d0d2008102a0c0d0b202a450d0b2009450d0b2009102a0c0b0b202b450d09200a450d09200a102a0c090b0240200b0d002006211020112101201c210b201b212c201a212d0c130b0240202d450d00200b202d4104746a2121200b21200340024020202802082210450d0020202802002101201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041106a21010240202041046a280200450d002020280200102a0b2001212020012021470d000b0b4100212041012110202c450d07200b102a0c070b0240200c0d002006211020112101201c210c201b212e201a212f0c120b0240202f450d00202f41146c2110200c210103400240200141046a280200450d002001280200102a0b200141146a21012010416c6a22100d000b0b4100212141012110202e450d05200c102a0c050b0240200d0d002006211020112101201c210d201b2130201a21310c110b02402031450d00200d2031411c6c6a2121200d21200340024020202802042201450d0002402020410c6a2802002210450d00201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041086a280200450d002020280204102a0b2020411c6a21010240202041146a280200450d002020280210102a0b2001212020012021470d000b0b41002122410121102030450d03200d102a0c030b0240200e0d002006211020112101201c210e201b2132201a21330c100b02402033450d00200e203341186c6a2121200e212003400240202041046a280200450d002020280200102a0b0240202041146a2802002210450d00202028020c2101201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041186a21010240202041106a280200450d00202028020c102a0b2001212020012021470d000b0b41002123410121102032450d01200e102a0c010b024020040d002006211020112101201a2134201b2135201c21040c0f0b02402034450d0020042034411c6c6a2121200421200340024020202802042201450d0002402020410c6a2802002210450d00201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041086a280200450d002020280204102a0b2020411c6a21010240202041146a280200450d002020280210102a0b2001212020012021470d000b0b410021244101211002402035450d002004102a0b201c2104201b2135201a21344101211f410121204101212141012122410121230c0d0b201a2133201b2132201c210e4101211f4101212041012121410121220c0b0b201a2131201b2130201c210d4101211f4101212041012121410121230c0a0b201a212f201b212e201c210c4101211f410121200c080b201a212d201b212c201c210b4101211f0c060b2006211020112101201c210a201b212b201a21360c090b2006211020112101201c2109201b212a201a21370c080b2006211020112101201c2108201b2129201a21380c070b201a2128201b2127201c21070c010b201a2126201b2125201c210f0b410121200b410121210b41012122410121230b410121240b024002400240201e410b4b0d000240024002400240024002400240024002400240201e0e0c000102030405060a070a0809000b2010450d0b0240201a450d00201a4104742110201c210103400240200141046a280200450d002001280200102a0b200141106a2101201041706a22100d000b0b201b450d0b0c0a0b201f450d0a0240201a450d00201a41286c2110201c210103400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101201041586a22100d000b0b201b0d090c0a0b41000d09201b0d080c090b41000d08201b0d070c080b41000d07201b0d060c070b2020450d060240201a450d00201c201a4104746a211e201c21200340024020202802082210450d0020202802002101201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041106a21010240202041046a280200450d002020280200102a0b200121202001201e470d000b0b201b0d050c060b2021450d050240201a450d00201a41146c2110201c210103400240200141046a280200450d002001280200102a0b200141146a21012010416c6a22100d000b0b201b0d040c050b2022450d040240201a450d00201c201a411c6c6a211e201c21200340024020202802042201450d0002402020410c6a2802002210450d00201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041086a280200450d002020280204102a0b2020411c6a21010240202041146a280200450d002020280210102a0b200121202001201e470d000b0b201b0d030c040b2023450d030240201a450d00201c201a41186c6a211e201c212003400240202041046a280200450d002020280200102a0b0240202041146a2802002210450d00202028020c2101201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041186a21010240202041106a280200450d00202028020c102a0b200121202001201e470d000b0b201b0d020c030b2024450d020240201a450d00201c201a411c6c6a211e201c21200340024020202802042201450d0002402020410c6a2802002210450d00201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041086a280200450d002020280204102a0b2020411c6a21010240202041146a280200450d002020280210102a0b200121202001201e470d000b0b201b0d010c020b0240201d410e4b0d00200621102011210102400240024002400240024002400240024002400240201d0e0f0001020304040405060e070e08090a000b201b0d0b0c0c0b0240201b450d00201c102a0b2018450d0b2019102a0c0b0b0240201a450d00201a4104742110201c210103400240200141046a280200450d002001280200102a0b200141106a2101201041706a22100d000b0b201b0d090c0a0b201a450d00201a41286c2110201c210103400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101201041586a22100d000b0b201b0d070c080b0240201a450d00201c201a4104746a211e201c21200340024020202802082210450d0020202802002101201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041106a21010240202041046a280200450d002020280200102a0b200121202001201e470d000b0b201b0d060c070b0240201a450d00201a41146c2110201c210103400240200141046a280200450d002001280200102a0b200141146a21012010416c6a22100d000b0b201b0d050c060b0240201a450d00201c201a411c6c6a211e201c21200340024020202802042201450d0002402020410c6a2802002210450d00201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041086a280200450d002020280204102a0b2020411c6a21010240202041146a280200450d002020280210102a0b200121202001201e470d000b0b201b0d040c050b0240201a450d00201c201a41186c6a211e201c212003400240202041046a280200450d002020280200102a0b0240202041146a2802002210450d00202028020c2101201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041186a21010240202041106a280200450d00202028020c102a0b200121202001201e470d000b0b201b0d030c040b0240201a450d00201c201a411c6c6a211e201c21200340024020202802042201450d0002402020410c6a2802002210450d00201041047421100340024020012d00004109470d000240200141046a221f280200222428020441ffffffff0371450d002024280200102a201f28020021240b2024102a0b200141106a2101201041706a22100d000b0b202041086a280200450d002020280204102a0b2020411c6a21010240202041146a280200450d002020280210102a0b200121202001201e470d000b0b201b0d020c030b0240201c450d00201b450d00201c102a0b02402018450d0002402016450d002016410c6c2110201821010340024020012802002224450d00200141046a280200450d002024102a0b2001410c6a2101201041746a22100d000b0b2017450d002018102a0b2014450d0202402012450d00201420124104746a211c2014212003402020221f41106a21200240201f2802042201450d000240201f410c6a2802002210450d002010410c6c21100340024020012802002224450d00200141046a280200450d002024102a0b2001410c6a2101201041746a22100d000b0b201f41086a280200450d00201f280204102a0b2020201c470d000b0b2013450d022014102a0c020b0240201b450d00201c102a0b02402018450d002017450d002018102a0b2014450d012015102a0c010b201c102a0b20062110201121010b20050d000b4100210520012111201021060b200f0d010b4104210f41002125410021260b20002003360280012000200636025420002026360208200020253602042000200f36020020004188016a200536020020004184016a2002360200200041fc006a2034410020041b360200200041f8006a2035410020041b36020020002004410420041b360274200041f0006a20334100200e1b360200200041ec006a20324100200e1b3602002000200e4104200e1b360268200041e4006a20314100200d1b360200200041e0006a20304100200d1b3602002000200d4104200d1b36025c200041d8006a2011360200200041d0006a202f4100200c1b360200200041cc006a202e4100200c1b3602002000200c4104200c1b360248200041c4006a202d4100200b1b360200200041c0006a202c4100200b1b3602002000200b4104200b1b36023c200041386a20364100200a1b360200200041346a202b4100200a1b3602002000200a4104200a1b3602302000412c6a2037410020091b360200200041286a202a410020091b36020020002009410420091b360224200041206a2038410020081b3602002000411c6a2029410020081b36020020002008410420081b360218200041146a2028410020071b360200200041106a2027410020071b36020020002007410420071b36020c0bb10a010e7f230041106b2202240002400240024002400240024020012802004101470d00200141106a2d000021032001410c6a2802002104200141086a280200210520012f0112210620012d0011210720012802042108200241086a200010fa0320022802082201200228020c22094104746a210a4100210b20094104490d01200341ff0171210c02400340024020012d000c200c470d0020012802082004470d000240200128020022092008460d002004450d002004210d2008210e034020092d0000200e2d0000470d02200941016a2109200e41016a210e200d417f6a220d0d000b0b200741ff0171220941044720012d000d220e410446220d460d00200e2009460d0520094104460d05200d0d050b02400240024002402001411c6a2d0000200c470d00200141186a2802002004470d000240200128021022092008460d002004450d002004210d2008210e034020092d0000200e2d0000470d02200941016a2109200e41016a210e200d417f6a220d0d000b0b200741ff0171220941044720012d001d220e410446220d460d00200e2009460d0120094104460d01200d0d010b2001412c6a2d0000200c470d02200141286a2802002004470d02200128022022092008460d012004450d012004210d2008210e034020092d0000200e2d0000470d03200941016a2109200e41016a210e200d417f6a220d450d020c000b0b200b410172210b0c060b200741ff0171220941044720012d002d220e410446220d460d00200e2009460d0220094104460d02200d0d020b024002402001413c6a2d0000200c470d00200141386a2802002004470d000240200128023022092008460d002004450d002004210d2008210e034020092d0000200e2d0000470d02200941016a2109200e41016a210e200d417f6a220d0d000b0b200741ff0171220941044720012d003d220e410446220d460d00200e2009460d0120094104460d01200d0d010b200b41046a210b200a200141c0006a22016b41304d0d040c010b0b200b410372210b0c030b200b410272210b0c020b2001280204210b0c030b2001200a460d0102400240200741ff0171220f4104460d00200341ff0171210c0c010b200341ff0171210c0340024020012d000c200c470d0020012802082004470d000240200128020022092008460d002004450d002004210d2008210e034020092d0000200e2d0000470d02200941016a2109200e41016a210e200d417f6a220d0d000b0b20012d000d4104460d030b200b41016a210b200141106a2201200a470d000c030b0b0340024020012d000c200c470d0020012802082004470d000240200128020022092008460d002004450d002004210d2008210e034020092d0000200e2d0000470d02200941016a2109200e41016a210e200d417f6a220d0d000b0b20012d000d2209200f470d0020094104470d020b200b41016a210b200141106a2201200a460d020c000b0b2005450d012008102a0c010b024020002802082201200041046a280200470d0002400240200141016a22092001490d002001410174220e2009200e20094b1b220941ffffffff00712009470d002009410474220e41004e0d010b1031000b0240024020010d00200e102821010c010b20002802002001410474200e102c21010b2001450d0220002001360200200041046a2009360200200028020821010b200028020020014104746a220120063b010e200120073a000d200120033a000c2001200436020820012005360204200120083602002000200028020841016a3602082002200010fa032002280204417f6a210b0b200241106a2400200b0f0b200e41041037000bf722032d7f017e017f230041306b22022400200241043602002001280204210320012802002104410121050240024002400240024002400240024002400240024002400240024002400240200128020822060d0041002107410121080c010b413010282207450d012007200636000c200720033600082007200436000420022007360200200741023a000041002108410121070b200141106a2802002109200128020c210a02400240200141146a280200220b0d002007210c0c010b2007410174220d200741016a220c200d200c4b1b220c41306c210e0240024020070d00200e1028210d0c010b2002280200200741306c200e102c210d0b200d450d022002200d360200200d200741306c6a220d41033a0000200d20022f002d3b0001200d200b36000c200d2009360008200d200a360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a290200370200200741016a2107410021050b2001411c6a280200210f200128021821104100211102400240200141206a28020022120d00200c210e410021130c010b024002402007200c460d00200c210e0c010b41000d0e41000d0e200c410174220d200c41016a220e200d200e4b1b220ead42307ea722144100480d0e02400240200c0d0020141028210d0c010b2002280200200c41306c2014102c210d0b200d450d042002200d3602000b2002280200200741306c6a220d41043a0000200d20022f002d3b0001200d201236000c200d200f360008200d2010360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a29020037020041012113200741016a21070b200141286a280200211420012802242115024002402001412c6a28020022120d00200e210c0c010b024002402007200e460d00200e210c0c010b41000d0e41000d0e200e410174220d200e41016a220c200d200c4b1b220cad42307ea722114100480d0e02400240200e0d0020111028210d0c010b2002280200200e41306c2011102c210d0b200d450d052002200d3602000b2002280200200741306c6a220d41053a0000200d20022f002d3b0001200d201236000c200d2014360008200d2015360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a29020037020041012111200741016a21070b200141346a28020021162001280230211702400240200141386a280200220e0d00410021180c010b02402007200c470d0041000d0e41000d0e200c410174220d200c41016a2212200d20124b1b2212ad42307ea722194100480d0e02400240200c0d0020191028210d0c010b2002280200200c41306c2019102c210d0b200d450d062002200d3602002012210c0b2002280200200741306c6a220d41063a0000200d20022f002d3b0001200d200e36000c200d2016360008200d2017360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a29020037020041012118200741016a21070b200141c0006a280200211a200128023c211b4101211902400240200141c4006a280200221c0d00200c210e4101211d0c010b024002402007200c460d00200c210e0c010b41000d0e41000d0e200c410174220d200c41016a220e200d200e4b1b220ead42307ea722124100480d0e02400240200c0d0020121028210d0c010b2002280200200c41306c2012102c210d0b200d450d072002200d3602000b2002280200200741306c6a220d41073a0000200d20022f002d3b0001200d201c36000c200d201a360008200d201b360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a290200370200200741016a21074100211d0b200141cc006a280200211e2001280248211f02400240200141d0006a28020022200d00200e21120c010b024002402007200e460d00200e21120c010b41000d0e41000d0e200e410174220d200e41016a220c200d200c4b1b2212ad42307ea7220c4100480d0e02400240200e0d00200c1028210d0c010b2002280200200e41306c200c102c210d0b200d450d082002200d3602000b2002280200200741306c6a220d41083a0000200d20022f002d3b0001200d202036000c200d201e360008200d201f360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a200241046a41086a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a290200370200200741016a2107410021190b410121210240024020012802544101460d002012210c0c010b200141d8006a280200210e0240024020072012460d002012210c0c010b41000d0e41000d0e2012410174220d201241016a220c200d200c4b1b220cad42307ea722224100480d0e0240024020120d0020221028210d0c010b2002280200201241306c2022102c210d0b200d450d092002200d3602000b2002280200200741306c6a220d41093a0000200d20022f002d3b0001200d200e360204200d2002290204370208200d41036a2002412f6a2d00003a0000200d41106a2002410c6a290200370200200d41186a200241046a41106a290200370200200d41206a200241046a41186a290200370200200d41286a200241046a41206a290200370200200741016a21070b200141e0006a2802002123200128025c212402400240200141e4006a28020022250d00200c210e0c010b024002402007200c460d00200c210e0c010b41000d0e41000d0e200c410174220d200c41016a220e200d200e4b1b220ead42307ea722124100480d0e02400240200c0d0020121028210d0c010b2002280200200c41306c2012102c210d0b200d450d0a2002200d3602000b2002280200200741306c6a220d410a3a0000200d20022f002d3b0001200d202536000c200d2023360008200d2024360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a290200370200200741016a2107410021210b200141ec006a2802002126200128026821274101212202400240200141f0006a28020022280d00200e2112410121290c010b024002402007200e460d00200e21120c010b41000d0e41000d0e200e410174220d200e41016a220c200d200c4b1b2212ad42307ea7220c4100480d0e02400240200e0d00200c1028210d0c010b2002280200200e41306c200c102c210d0b200d450d0b2002200d3602000b2002280200200741306c6a220d410c3a0000200d20022f002d3b0001200d202836000c200d2026360008200d2027360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a290200370200200741016a2107410021290b200141f8006a280200212a2001280274212b02400240200141fc006a280200222c0d002012210c0c010b0240024020072012460d002012210c0c010b41000d0e41000d0e2012410174220d201241016a220c200d200c4b1b220cad42307ea7220e4100480d0e0240024020120d00200e1028210d0c010b2002280200201241306c200e102c210d0b200d450d0c2002200d3602000b2002280200200741306c6a220d410d3a0000200d20022f002d3b0001200d202c36000c200d202a360008200d202b360004200d2002290204370210200d41036a2002412f6a2d00003a0000200d41186a2002410c6a290200370200200d41206a200241146a290200370200200d41286a200241046a41186a290200370200200741016a2107410021220b20014184016a2802002112200128028001210d02400240200c20076b20014188016a28020041306c222d41306d220e490d00200228020021010c010b2007200e6a22012007490d0d200c410174222e2001202e20014b1b222ead42307e222f422088a70d0d202fa722304100480d0d02400240200c0d002030102821010c010b2002280200200c41306c2030102c21010b2001450d0c20022001360200202e210c0b2001200741306c6a200d202d109a051a2007200e6a210702402012450d00200d102a0b2000200136020820004280c2cdeb16370200200041106a20073602002000410c6a200c3602002022450d0d0240202c450d00202b202c411c6c6a210e202b21000340024020002802042201450d0002402000410c6a2802002207450d00200741047421070340024020012d00004109470d000240200141046a220c280200220d28020441ffffffff0371450d00200d280200102a200c280200210d0b200d102a0b200141106a2101200741706a22070d000b0b200041086a280200450d002000280204102a0b2000411c6a21010240200041146a280200450d002000280210102a0b200121002001200e470d000b0b202a450d0d202b102a0c0d0b413041041037000b200e41041037000b201441041037000b201141041037000b201941041037000b201241041037000b200c41041037000b202241041037000b201241041037000b200c41041037000b200e41041037000b203041041037000b1031000b02402029450d0002402028450d002027202841186c6a210e2027210003400240200041046a280200450d002000280200102a0b0240200041146a2802002207450d00200028020c2101200741047421070340024020012d00004109470d000240200141046a220c280200220d28020441ffffffff0371450d00200d280200102a200c280200210d0b200d102a0b200141106a2101200741706a22070d000b0b200041186a21010240200041106a280200450d00200028020c102a0b200121002001200e470d000b0b2026450d002027102a0b02402021450d0002402025450d0020242025411c6c6a210e202421000340024020002802042201450d0002402000410c6a2802002207450d00200741047421070340024020012d00004109470d000240200141046a220c280200220d28020441ffffffff0371450d00200d280200102a200c280200210d0b200d102a0b200141106a2101200741706a22070d000b0b200041086a280200450d002000280204102a0b2000411c6a21010240200041146a280200450d002000280210102a0b200121002001200e470d000b0b2023450d002024102a0b02402019450d0002402020450d00202041146c2107201f210103400240200141046a280200450d002001280200102a0b200141146a21012007416c6a22070d000b0b201e450d00201f102a0b0240201d450d000240201c450d00201b201c4104746a210e201b21000340024020002802082207450d0020002802002101200741047421070340024020012d00004109470d000240200141046a220c280200220d28020441ffffffff0371450d00200d280200102a200c280200210d0b200d102a0b200141106a2101200741706a22070d000b0b200041106a21010240200041046a280200450d002000280200102a0b200121002001200e470d000b0b201a450d00201b102a0b02402016410047201841017371450d002017102a0b02402014410047201141017371450d002015102a0b0240200f410047201341017371450d002010102a0b02402005450d000240200b450d00200b41286c2107200a210103400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101200741586a22070d000b0b2009450d00200a102a0b02402008450d0002402006450d00200641047421072004210103400240200141046a280200450d002001280200102a0b200141106a2101200741706a22070d000b0b2003450d002004102a0b200241306a24000bee0203037f017e027f410121020240024002400240200041086a2802002203417f6a220420034f0d00200420034b0d00200028020020044104746a220329020421052003200141016aad3702042005a721012005422088a721030240200041086a28020022024101460d002002450d0220002802002002417e6a4104746a22022802042001470d002002200228020820036a36020841000f0b410021022003450d000240200041146a2802002204200041106a280200470d00200441016a22062004490d04200441017422072006200720064b1b220641ffffffff01712006470d04200641037422074100480d040240024020040d002007102821040c010b200028020c20044103742007102c21040b2004450d032000200436020c200041106a2006360200200028021421040b200028020c20044103746a22042003360204200420013602002000200028021441016a3602140b20020f0b41ede3c500413f1050000b200741041037000b1031000b8a1302147f027e23004180026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d002000200110de042003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00200b200b417f6a220d2000200b4103746a280200220e2000200d4103746a280200220f4922101b2211200b41016a2212200d200b20101b200020124103746a280200220b200f200e20101b220d49220f1b200b200d200f1b200020114103746a2802004922131b210b200c200c417f6a220d2000200c4103746a28020022112000200d4103746a280200221249220e1b2214200c4101722206200d200c200e1b200020064103746a280200220c20122011200e1b220d4922111b200c200d20111b200020144103746a2802004922141b210c200a200a417f6a22122000200a4103746a2802002206200020124103746a280200221549220d1b2216200a41016a22172012200a200d1b200020174103746a280200220a20152006200d1b22064922121b200a200620121b200020164103746a2802004922061b210a41024101200d1b200d20121b20066a200e6a20116a20146a20106a200f6a20136a210d0b200d2000200c4103746a280200220e2000200a4103746a280200220f4922106a2000200b4103746a280200220d200f200e20101b221149220f6a210e200d2011200f1b2000200c200a20101b220d4103746a280200490d01200b200a200c20101b200f1b210d0c020b2000200110df040c0f0b200e41016a220e410c490d0002402001410176220b450d00200020014103746a41786a210a2000210c0340200c2902002118200c200a290200370200200a2018370200200c41086a210c200a41786a210a200b417f6a220b0d000b0b2001200d417f736a210d4101210a0c010b200e45210a0b0240200a452009724101710d002000200110e0040d0d0b2002450d02200d20014f0d01024020022802002000200d4103746a220a2802004f0d0020002108200121070c040b200029020021182000200a290200370200200a2018370200200041786a210f200041086a211120002902002218a721104100210c2001210b03400240200c200b417f6a220d4f0d002011200c4103746a210a0340200a28020020104b0d01200a41086a210a200d200c41016a220c470d000b200d210c0b200f200b4103746a210a02400340200c200b417f6a220b4f0d01200a280200210d200a41786a220e210a200d20104b0d000b2011200c4103746a220a2902002119200a200e41086a220d290200370200200d2019370200200c41016a210c0c010b0b2000201837020002402001200c41016a220a490d002000200a4103746a21002001200a6b220141154f0d010c0c0b0b200a20011044000b41b8e9c500200d20011034000b2007450d010b200d20074f0d012008290200211820082008200d4103746a220a290200370200200a2018370200200841086a210e20082902002219a72111410021142007417f6a2210450d02200e210a0340200a28020020114f0d03200a41086a210a2010201441016a2214470d000b201021140c020b4198e9c500410041001034000b41a8e9c500200d20071034000b200820074103746a210c2010210b02400340200c210d200b220a20144d22060d01200a417f6a210b200d41786a220c28020020114f0d000b0b0240200a2014490d002010200a490d0241800121054100210b410021014100210c4100210f4180012109200e20144103746a2215211003400240200d20106b220a4187104b22130d00200a410376220a41807f6a200a2001200b49200f200c49220e7222001b210a02402000450d002009200a200e1b2109200a2005200e1b21050c010b200a200a41017622096b21050b0240200f200c470d00024020090d002004220c210f0c010b4100210a2004220f210c2010210e0340200c200a3a0000200c200e28020020114f6a210c200e41086a210e2009200a41016a220a470d000b0b02402001200b470d00024020050d0020044180016a220b21010c010b200d41786a210a4100210e20044180016a2201210b0340200b200e3a0000200b200a2802002011496a210b200a41786a210a2005200e41016a220e470d000b0b0240200b20016b220a200c200f6b220e200e200a4b1b2212450d002010200f2d00004103746a220a2902002118200a200d20012d0000417f734103746a290200370200024020124101460d004100210a0340200d2001200a6a220e2d0000417f734103746a2010200f200a6a41016a22002d00004103746a290200370200201020002d00004103746a200d200e41016a2d0000417f734103746a290200370200200a41026a210e200a41016a2200210a200e2012490d000b200120006a2101200f20006a210f0b200d20012d0000417f734103746a2018370200200141016a2101200f41016a210f0b200d20054103746b200d2001200b461b210d201020094103746a2010200f200c461b211020130d000b02400240200f200c4f0d00200d210a03402010200c417f6a220c2d00004103746a220b2902002118200b200a41786a220a290200370200200a2018370200200f200c490d000c020b0b2010210a2001200b4f0d000340200a2902002118200a200d200b417f6a220b2d0000417f734103746a220c290200370200200c2018370200200a41086a210a2001200b490d000b0b200820193702002007200a20156b41037620146a22014d0d032008200820014103746a220a290200370200200a2019370200200720016b220c450d04200c20012001200c4b1b210b2007410376210d200a41086a2100024002402001200c417f6a220c490d002000200c200a2003108004200821000c010b2008200120022003108004200a2102200c21010b200b200d4f2105200141154f0d010c050b0b2014200a1044000b200a2010103c000b41a8e9c500200120071034000b41dc83c6001032000b20014102490d00200041786a21104100210e4101210b0340200b410374210c200b417f6a210a200b41016a210b02402000200c6a220d2802002000200a4103746a220f2802004f0d00200d2902002118200d200f2902003702000240200a450d00200e210c2010210a200d41706a2802002018a7220d4d0d00024002400340200a41086a200a290200370200200c4101460d01200c417f6a210c200a41786a220a280200200d4b0d000c020b0b4100210c0b2000200c4103746a210f0b200f20183702000b200e41016a210e201041086a2110200b2001470d000b0b20044180026a24000be00402097f017e230041306b22022400200241106a2203200141246a290200370300200241086a22042001411c6a29020037030020022001290214370300200241186a41106a2205200141106a280200360200200241186a41086a2206200141086a290200370300200220012902003703182000200241186a10fd0321070240024002400240200041206a28020022082000411c6a280200470d00200841016a22092008490d032008410174220a2009200a20094b1b220941ffffffff03712009470d032009410274220a4100480d030240024020080d00200a102821080c010b20002802182008410274200a102c21080b2008450d01200020083602182000411c6a2009360200200028022021080b200028021820084102746a20073602002000200028022041016a3602202005200329030037030020062004290300370300200220022903003703180240200041f0006a22032802002208200041ec006a280200470d00200841016a22042008490d03200841017422052004200520044b1b2204ad42187e220b422088a70d03200ba722054100480d030240024020080d002005102821080c010b2000280268200841186c2005102c21080b2008450d0220002008360268200041ec006a2004360200200041f0006a28020021080b2000280268200841186c6a22082002290318370200200841106a200241186a41106a290300370200200841086a200241186a41086a29030037020020032003280200220841016a360200024020012d002c450d0020004101360254200041d8006a20083602000b200241306a24000f0b200a41041037000b200541041037000b1031000bb20c01067f0240024020002d00002201410e4b0d00024002400240024002400240024002400240024002400240024020010e0f0001020304050607080e090e0a0b0c000b200041086a280200450d0d200041046a280200102a0f0b0240200041086a280200450d00200041046a280200102a0b200041146a280200450d0c200041106a280200102a0f0b02402000410c6a2802002202450d00200041046a28020021012002410474210203400240200141046a280200450d002001280200102a0b200141106a2101200241706a22020d000b0b200041086a280200450d0b2000280204102a0f0b02402000410c6a2802002202450d00200041046a2802002101200241286c210203400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101200241586a22020d000b0b200041086a280200450d0a2000280204102a0f0b200041086a280200450d09200041046a280200102a0f0b200041086a280200450d08200041046a280200102a0f0b200041086a280200450d07200041046a280200102a0f0b02402000410c6a2802002201450d00200041046a280200220320014104746a21040340024020032802082202450d0020032802002101200241047421020340024020012d00004109470d000240200141046a2205280200220628020441ffffffff0371450d002006280200102a200528020021060b2006102a0b200141106a2101200241706a22020d000b0b200341106a21010240200341046a280200450d002003280200102a0b2001210320012004470d000b0b200041086a280200450d062000280204102a0f0b02402000410c6a2802002202450d00200041046a2802002101200241146c210203400240200141046a280200450d002001280200102a0b200141146a21012002416c6a22020d000b0b200041086a280200450d052000280204102a0f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a21040340024020032802042201450d0002402003410c6a2802002202450d00200241047421020340024020012d00004109470d000240200141046a2205280200220628020441ffffffff0371450d002006280200102a200528020021060b2006102a0b200141106a2101200241706a22020d000b0b200341086a280200450d002003280204102a0b2003411c6a21010240200341146a280200450d002003280210102a0b2001210320012004470d000b0b200041086a280200450d042000280204102a0f0b02402000410c6a2802002201450d00200041046a2802002203200141186c6a210403400240200341046a280200450d002003280200102a0b0240200341146a2802002202450d00200328020c2101200241047421020340024020012d00004109470d000240200141046a2205280200220628020441ffffffff0371450d002006280200102a200528020021060b2006102a0b200141106a2101200241706a22020d000b0b200341186a21010240200341106a280200450d00200328020c102a0b2001210320012004470d000b0b200041086a280200450d032000280204102a0f0b200041046a220110f904200041086a280200450d022001280200102a0f0b0240200041046a2802002201450d00200041086a280200450d002001102a0b0240200041146a2802002201450d0002402000411c6a2802002202450d002002410c6c21020340024020012802002206450d00200141046a280200450d002006102a0b2001410c6a2101200241746a22020d000b0b200041186a280200450d002000280214102a0b200041246a2802002203450d0102402000412c6a2802002201450d00200320014104746a210403402003220541106a2103024020052802042201450d0002402005410c6a2802002202450d002002410c6c21020340024020012802002206450d00200141046a280200450d002006102a0b2001410c6a2101200241746a22020d000b0b200541086a280200450d002005280204102a0b20032004470d000b0b200041286a280200450d012000280224102a0c010b0240200041086a280200450d00200041046a280200102a0b0240200041146a2802002201450d00200041186a280200450d002001102a0b200041246a280200450d00200041206a280200102a0f0b0bff7f05077f017e277f037e0f7f23002203210420034180096b4160712203240002400240024002400240024002400240024002400240411010282205450d00200541063a0000412010282206450d01200641063a001020064100360204200620032f00f0053b00012006412d3a0000200641036a200341f2056a2d00003a0000024020052d00004109470d0002402005280204220728020441ffffffff0371450d002007280200102a200528020421070b2007102a0b2005102a200141106a28020041306c2105200128020841546a210702400340024020050d00411010282207450d0520074180023b010c200742828080802037020420072006360200200720032f01d0033b010e0240200128021022052001410c6a280200470d00200541016a22082005490d0e200541017422092008200920084b1b2208ad42307e220a422088a70d0e200aa722094100480d0e0240024020050d002009102821050c010b2001280208200541306c2009102c21050b2005450d07200120053602082001410c6a2008360200200128021021050b2001280208200541306c6a220520032f00e0043b0001200541073a0000200542818080801037000820052007360004200520032902f005370210200541036a200341e2046a2d00003a0000200541186a200341f8056a290200370200200541206a20034180066a290200370200200541286a200341f0056a41186a2902003702002001200128021041016a220b3602104100210c0c020b200541506a21052007412c6a2108200741306a2209210720082d00004107470d000b200320032f01d0033b01f0050240200941086a22072802002205200941046a280200470d00200541016a22082005490d0c2005410174220d2008200d20084b1b220841ffffffff00712008470d0c2008410474220d4100480d0c0240024020050d00200d102821050c010b20092802002005410474200d102c21050b2005450d0620092005360200200941046a2008360200200941086a28020021050b200928020020054104746a22054180023b010c200542828080802037020420052006360200200520032f01f0053b010e2007200728020041016a360200200341c0006a200910fa032003280244417f6a210c2001280210210b0b200b41306c21052001280208220e41546a210702400340410021082005450d01200541506a21052007412c6a2109200741306a2206210720092d00004103470d000b200641086a2802002205450d00200541286c2107200628020041186a2105410021080340200820052d0000456a2108200541286a2105200741586a22070d000b0b200b41306c2105200e41546a210702400340410021092005450d01200541506a21052007412c6a2106200741306a220d210720062d00004103470d000b200d41086a2802002205450d00200541286c2107200d28020041186a2105410021090340200920052d0000456a2109200541286a2105200741586a22070d000b0b200b41306c2105200e415c6a2107024003404100210f024020050d00410021050c020b200541506a2105200741246a2106200741306a220d210720062d00004104470d000b200d28020021050b200341003602e0040240200520096a220b0d0041042110410021110c080b02402008450d00200342003703f005410021050c060b200341f0056a4100200110d60420032802f405210520032802f0054101470d05200341f8056a290300210a024020032802e0042207450d0020032802e404450d002007102a0b2003200a3702e404200320053602e00441002111410421104100210f0c060b411041081037000b412041081037000b411041041037000b200941041037000b200d41041037000b0240024002400240410410282210450d0020102005360200200b4102490d02024020084102490d00200342003703f0054100210d0c020b200341f0056a4101200110d60420032802f405210d20032802f0054101470d01200341f8056a290300210a024020032802e004450d0020032802e404450d0020032802e004102a0b2003200a3702e4042003200d3602e0040c020b410441041037000b410221064104210741012109410121110340200941016a210502400240024020092011470d0020062005200620054b1b221141ffffffff03712011470d0a2011410274220e4100480d0a20102007200e102c2210450d010b201020076a200d36020002402005200b4f0d000240200820054d0d00200342003703f0054100210d0c030b200341f0056a2005200110d60420032802f405210d20032802f0054101470d0220032903f805210a024020032802e004450d0020032802e404450d0020032802e004102a0b200941016a210f2003200a3702e4042003200d3602e0040c050b200941016a210f0c040b200e41041037000b200641026a2106200741046a2107200521090c000b0b4101210f410121110b20032802e00421050b2005450d0020032902e404210a02402011450d002010102a0b2000200536020420004101360200200041086a200a3702000c010b024020012802102205450d0020012802082212200541306c6a2113200341e0046a41146a2114200341e0076a211520034194066a2116200341a4066a2117200341b4066a2118200341c4066a2119200341d4066a211a200341e4066a211b200341f4066a211c20034184076a211d20034194076a211e200341a4076a211f200341b4076a2120200341c4076a2121200341d4076a212202400240024002400340024020122d0000410c470d00201228020c2205450d0020122802042206200541186c6a212303400240200641146a220e2802002205450d002006410c6a212441002109024002400340200920054f0d014101210502402024280200200941047422256a22072d0000410b470d002003200741046a22073602c00220072802002207200f4f0d03201020074102746a2802002208450d002003200c3602d407200341133a00d007200341d7003a00c007200320083602b4072003412d3a00b0072003200c3602a407200341123a00a00720032007360294072003410b3a009007200341063a008007200341003a00f00620034184083b01e006200341373a00d006200320023602c4062003412d3a00c0062003200c3602b406200341123a00b0062003200c3602a406200341133a00a006200341d6003a00900620032008360284062003412d3a0080062003200c3602f405200341123a00f005200e280200222620094d0d09200e2009360200200628020c2105200320153602f804200320243602f0042003200520256a220b41106a220d3602e8042003200941016a22273602e0042003202620276b22283602e40420032005202741047422296a222a3602ec042003200341f0056a3602f404200d21050240200b2d0000220841ac01460d004100210502400340200b20056a21070240200841ff01714109470d000240200741046a280200220828020441ffffffff0371450d002008280200102a0b2008102a0b2005450d012003200741206a3602e804200541106a2105200741106a2d0000220841ac01470d000b200b20056a41106a21050c010b200741106a21050b02402005202a460d0003402003200541106a22073602e80420052d0000220841ac01460d01024020084109470d000240200541046a280200220528020441ffffffff0371450d002005280200102a0b2005102a0b20072105200d2007470d000b0b02400240024002402028450d000240202720062802142205470d00200341f0056a21052015210b0c030b2025200541047422056b2108200628020c20056a2107200341f0056a21052015210d0340024002402005200d470d00410021050c010b2003200541106a3602f4040b200341d0036a200510d30420032d00d00341ac01460d04200720032903d003370300200741086a200341d0036a41086a2903003703002006200628021441016a3602142008450d02200741106a2107200841706a210820032802f804210d20032802f40421050c000b0b2024201410d7040c020b20032802f804210b20032802f40421050b0240200b20056b2207450d000240024020032802f004220d41046a222a280200222520266b20074104762208490d00200d28020021070c010b202620086a22072026490d12202541017422262007202620074b1b222641ffffffff00712026470d122026410474222b4100480d120240024020250d00202b102821070c010b200d2802002025410474202b102c21070b2007450d0d200d2007360200202a20263602000b2007202720086a22254104746a200720296a2028410474109b051a200320253602e0042025200d2802082207460d00200920086a410474200741047422076b2108200d28020020076a21070340024002402005200b470d00410021050c010b2003200541106a3602f4040b200341d0036a200510d30420032d00d00341ac01460d02200720032903d003370300200741086a200341d0036a41086a290300370300200d200d28020841016a3602082008450d01200741106a2107200841706a210820032802f804210b20032802f40421050c000b0b200341003602d803200342083703d003200341d0036a201410d70420032802d003222820032802d8032207410474220b6a210d20032802d40321292028210502402007450d000240024020032802f004222541046a222a280200220520032802e404222720032802e00422076a22266b200b4104752208490d00202528020021050c010b202620086a222b2026490d1220054101742226202b2026202b4b1b222641ffffffff00712026470d122026410474222b4100480d120240024020050d00202b102821050c010b20252802002005410474202b102c21050b2005450d0e20252005360200202a20263602000b2005200720086a220841047422266a200520074104746a2027410474109b051a200320083602e00420282105200820252802082207460d002025280200220520266a212a200520074104746a21082028210703400240200b0d00200d21050c020b200341d0036a41026a2205200741036a2d00003a0000200320072f00013b01d003024020072d0000222741ac01470d00200741106a21050c020b200741046a2802002126200741086a290300210a200820273a0000200841086a200a370300200841046a202636020020032f01d0032127200841036a20052d00003a0000200841016a20273b00002025202528020841016a360208200b41706a210b200741106a22052107200841106a2208202a470d000b0b02402005200d460d0003400240024020052d000022074109460d00200741ac01470d010c030b0240200541046a280200220728020441ffffffff0371450d002007280200102a0b2007102a0b200541106a2205200d470d000b0b2029450d002028102a0b024020032802e804220520032802ec04220d460d0003402003200541106a22073602e80420052d0000220841ac01460d01024020084109470d000240200541046a280200220528020441ffffffff0371450d002005280200102a0b2005102a0b20072105200d2007470d000b0b024020032802e4042205450d00024020032802e004220d20032802f004220b41086a22082802002207460d00200b280200220b20074104746a200b200d4104746a2005410474109b051a0b2008200520076a3602000b024020032d00f0054109470d00024020032802f405220528020441ffffffff0371450d002005280200102a20032802f40521050b2005102a0b024020032d0080064109470d000240200341f0056a41146a280200220528020441ffffffff0371450d002005280200102a20032802840621050b2005102a0b024020032d0090064109470d0002402016280200220528020441ffffffff0371450d002005280200102a20032802940621050b2005102a0b024020032d00a0064109470d0002402017280200220528020441ffffffff0371450d002005280200102a20032802a40621050b2005102a0b024020032d00b0064109470d0002402018280200220528020441ffffffff0371450d002005280200102a20032802b40621050b2005102a0b024020032d00c0064109470d0002402019280200220528020441ffffffff0371450d002005280200102a20032802c40621050b2005102a0b024020032d00d0064109470d000240201a280200220528020441ffffffff0371450d002005280200102a20032802d40621050b2005102a0b024020032d00e0064109470d000240201b280200220528020441ffffffff0371450d002005280200102a20032802e40621050b2005102a0b024020032d00f0064109470d000240201c280200220528020441ffffffff0371450d002005280200102a20032802f40621050b2005102a0b024020032d0080074109470d000240201d280200220528020441ffffffff0371450d002005280200102a20032802840721050b2005102a0b024020032d0090074109470d000240201e280200220528020441ffffffff0371450d002005280200102a20032802940721050b2005102a0b024020032d00a0074109470d000240201f280200220528020441ffffffff0371450d002005280200102a20032802a40721050b2005102a0b024020032d00b0074109470d0002402020280200220528020441ffffffff0371450d002005280200102a20032802b40721050b2005102a0b024020032d00c0074109470d0002402021280200220528020441ffffffff0371450d002005280200102a20032802c40721050b2005102a0b024020032d00d0074109470d0002402022280200220528020441ffffffff0371450d002005280200102a20032802d40721050b2005102a0b410f21050b200520096a2209200e2802002205490d000c030b0b41ace4c500200920051034000b2003410136028406200342013702f405200341bce4c5003602f0052003412c3602d4032003200341d0036a360280062003200341c0026a3602d003200341e0046a200341f0056a103320032802e00422050d040b200641186a22062023470d000b0b201241306a22122013470d000c050b0b20032902e404210a2000200536020420004101360200200041086a200a3702002011450d042010102a0c040b41e4e8c5001032000b202b41081037000b202b41081037000b200341c8006a41106a200141106a2802002220360200200341c8006a41086a200141086a290200220a37030020032001290200370348202041306c2105200aa7221241546a210702400340024020050d00410021080c020b200541506a21052007412c6a2108200741306a2209210720082d00004108470d000b200341386a200910fa0320032802382108200328023c21050b2005410020081b210d202041306c2105201241546a21072008410420081b210802400340024020050d00410021090c020b200541506a21052007412c6a2109200741306a2206210720092d0000410a470d000b200341306a200610fa0320032802302109200328023421050b2005410020091b210b202041306c2105201241546a21072009410420091b211702400340024020050d004100211c0c020b200541506a21052007412c6a2109200741306a2206210720092d00004109470d000b200628020021074101211c0b20034200370274200341f8b9c0003602702017200b411c6c6a211f2008200d41146c6a210d200341e0046a410272221b41266a2121201b41186a2122201b41086a212b4104211641002124410021264100211e4100211d410021140240024002400240410041ff01710e03000102000b410021050c020b410221050c010b410121050b03400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e03000104040b0240201441ff01710e03020300020b201e4101470d04410021050c0b0b201c450d0f4100211c410221284100212a200721050c1d0b034002400240024002400240200d200822056b413c4b0d002005200d470d01200521080c020b200528020c0d03200541146a2108200541106a28020021050c1f0b200541106a21090340200528020c450d02200941146a2109200541146a2205200d470d000b200d21080b201e4101470d07410021050c0a0b200941046a2108200928020021050c1c0b200541206a280200450d1a200541346a280200450d19200541d0006a2108200541c8006a280200450d180c000b0b0340024002400240200d200822056b413c4b0d00410121142005200d470d01200521080c2b0b200528020c0d01200541146a2108200541106a28020021050c180b200541106a210902400340200528020c450d01200941146a2109200541146a2205200d470d000b200d21080c2a0b200941046a2108200928020021050c170b200541206a280200450d15200541346a280200450d14200541d0006a2108200541c8006a280200450d130c000b0b024002400240201441ff01710e03010200010b201e4101470d03410021050c080b034002400240024002400240200d200822056b413c4b0d002005200d470d01200521080c020b200528020c0d03200541146a2108200541106a28020021050c160b200541106a21090340200528020c450d02200941146a2109200541146a2205200d470d000b200d21080b201e4101470d07410021050c080b200941046a2108200928020021050c130b200541206a280200450d11200541346a280200450d10200541d0006a2108200541c8006a280200450d0f0c000b0b0340024002400240200d200822056b413c4b0d002005200d460d10200541106a21090340200528020c450d02200941146a2109200541146a2205200d470d000c110b0b200528020c0d01200541146a2108200541106a28020021050c0e0b200941046a2108200928020021050c0d0b200541206a280200450d0b200541346a280200450d0a200541d0006a2108200541c8006a280200450d090c000b0b410121050c060b410121050c040b410121050c020b410121050b0340024002400240024020050e020001010b2029201d470d01410121050c030b2017201f460d0a200341206a201710cd0420032802202229450d0a2017411c6a2117202920032802244102746a211d0c010b2029450d09202928020021054101211e41022114202941046a2129410121280c160b410021050c000b0b0340024002400240024020050e020001010b2029201d470d014101211e2029211d410121050c030b410221142017201f460d22200341106a201710cd042017411c6a211720032802102205450d23200520032802144102746a211d200521290c010b202941046a2109024020290d00410221144101211e200921290c230b2029280200210541002128410221144101211e200921290c150b410021050c000b0b0340024002400240024020050e020001010b2029201d470d01410121050c030b2017201f460d08200341286a201710cd0420032802282229450d082017411c6a21172029200328022c4102746a211d0c010b2029450d07202928020021054101211e41022114202941046a2129410121280c140b410021050c000b0b0340024002400240024020050e020001010b2029201d470d014101211e2029211d410121050c030b410221142017201f460d20200341186a201710cd042017411c6a211720032802182205450d212005200328021c4102746a211d200521290c010b202941046a2109024020290d00410221144101211e200921290c210b2029280200210541002128410221144101211e200921290c130b410021050c000b0b200541cc006a28020021050c020b2005413c6a2108200541386a28020021050c010b200541286a2108200541246a28020021050b41012114410121280c0d0b200341e0006a41086a200341f0006a41086a280200360200200320032903703703602003280258220d41306c21052003280250220b41546a210702400340410021082005450d01200541506a21052007412c6a2109200741306a2206210720092d00004103470d000b200641086a2802002205450d00200541286c2107200628020041186a2105410021080340200820052d0000456a2108200541286a2105200741586a22070d000b0b200d41306c2105200b415c6a210702400340024020050d00410021050c020b200541506a2105200741246a2109200741306a2206210720092d00004104470d000b200628020021050b200341f0056a41106a2228200341c8006a41106a280200360200200341f0056a41086a200341c8006a41086a290300370300200320032903483703f005200341b0016a200341f0056a10fc0302402026450d00201620264102746a212a200520086a2125200341f0056a41e0016a210f200341f0056a41d0016a2115200341f0056a41c0016a2129200341f0056a41b0016a2114200341f0056a41a0016a2117200341f0056a4190016a2118200341f0056a4180016a2119200341f0056a41f0006a211a200341f0056a41e0006a211b200341f0056a41d0006a211c200341f0056a41c0006a211d200341f0056a41306a211e200341f0056a41206a211f200341e7046a212020034184066a212120034194066a2122200341b4066a212b200341c4066a2123200341d4066a2112200341e4066a2101200341f4066a211320034184076a212c20034194076a212d200341a4076a212e200341b4076a212f200341c4076a2130200341d4076a21312016212703402027220541046a212720052802002106200341e0006a21052003280264210b03402005280200220d41086a2107200d2f0106220e4102742105417f210802400340024020050d00200e21080c020b20072802002109200841016a21082005417c6a2105200741046a21070240417f2009200647200920064b1b41016a0e03020001020b0b200d41346a20084105746a220e2802182107200e28021c21052003200c3602d407200341133a00d007200341d7003a00c007200320053602b4072003412d3a00b0072003200c3602a407200341123a00a00720032007360294072003410b3a009007200341063a008007200341003a00f00620034184083b01e006200341373a00d006200320023602c4062003412d3a00c0062003200c3602b406200341123a00b0062003200c3602a406200341133a00a006200341d6003a00900620032005360284062003412d3a0080062003200c3602f405200341123a00f005200e280208220d41106a220541ffffffff00712005470d1220054104742207417f4c0d12200e41086a21260240024002400240024020070d00410821060c010b200710282206450d012026280200210d0b0240200d0d00410021080c030b41002109410021070340024020072005470d00200541016a22082005490d262005410174220b2008200b20084b1b220841ffffffff00712008470d262008410474220b4100480d260240024020050d00200b102821060c010b20062005410474200b102c21060b2006450d03200821050b200620096a2208410f3a0000200841046a2007360200200841016a20032f01d0033b0000200841036a200341d0036a41026a2d00003a0000200941106a2109200741016a22082107200d2008460d030c000b0b200741081037000b200b41081037000b02400240024002400240024002400240200520086b410e4d0d00200521090c010b2008410f6a22072008490d28200541017422092007200920074b1b220941ffffffff00712009470d28200941047422074100480d280240024020050d002007102821060c010b200620054104742007102c21060b2006450d010b200341e0046a200341f0056a10d904200620084104746a220520032903e004370300200541086a200341e0046a41086a2207290300370300200341e0046a202810d904200541186a2007290300370300200520032903e004370310200341e0046a201f10d904200541286a2007290300370300200541206a20032903e004370300200341e0046a201e10d904200541386a2007290300370300200541306a20032903e004370300200341e0046a201d10d904200541c8006a2007290300370300200541c0006a20032903e004370300200341e0046a201c10d904200541d8006a2007290300370300200541d0006a20032903e004370300200341e0046a201b10d904200541e8006a2007290300370300200541e0006a20032903e004370300200341e0046a201a10d904200541f8006a2007290300370300200541f0006a20032903e004370300200341e0046a201910d90420054188016a200729030037030020054180016a20032903e004370300200341e0046a201810d90420054198016a200729030037030020054190016a20032903e004370300200341e0046a201710d904200541a8016a2007290300370300200541a0016a20032903e004370300200341e0046a201410d904200541b8016a2007290300370300200541b0016a20032903e004370300200341e0046a202910d904200541c8016a2007290300370300200541c0016a20032903e004370300200341e0046a201510d904200541d8016a2007290300370300200541d0016a20032903e004370300200341e0046a200f10d904200541e8016a2007290300370300200541e0016a20032903e004370300024002402008410f6a22052009460d002009210d200521090c010b200941016a22052009490d28200941017422072005200720054b1b220d41ffffffff0071200d470d28200d41047422054100480d280240024020090d002005102821060c010b200620094104742005102c21060b2006450d020b200620094104746a220541063a0000200520032900e004370001200541086a2020290000370000200341e0046a200341b0016a418c01109a051a411010282207450d02200741063a0000200341d0036a200341e0046a418c01109a051a20262802002205417f4c0d18200e28020021090240024020050d004101210b410120092005109a05220920092005109a051a2005ad2132410021050c010b20051028220b450d04200b20092005109a05210920051028220b450d05200b20092005109a051a2009102a2005ad21320b200341e0046a200341d0036a418c01109a051a200e31000d2133200341d0036a200341e0046a418c01109a051a200341e0046a200341d0036a418c01109a051a200341c0026a200341e0046a418c01109a051a411010282209450d05200841106a2108200a428080808080804083220a2032842033422886844280808080800c842132200941063a00002009102a200341d0036a200341c0026a418c01109a051a200341e0046a200341d0036a418c01109a051a024020072d00004109470d0002402007280204220928020441ffffffff0371450d002009280200102a200728020421090b2009102a0b2007102a200341c0026a200341e0046a418c01109a051a200341e0046a200341c0026a418c01109a051a200341003602fc03200320083602f8032003200d3602f403200320063602f003200341003602ec03200342043702e403200320323702dc03200320053602d8032003200b3602d403200341013602d003200341e0046a200341d0036a108104200341b0016a200341e0046a418c01109a051a200e4101360210200e2025360214024020032d00f0054109470d00024020032802f405220528020441ffffffff0371450d002005280200102a20032802f40521050b2005102a0b024020032d0080064109470d0002402021280200220528020441ffffffff0371450d002005280200102a20032802840621050b2005102a0b024020032d0090064109470d0002402022280200220528020441ffffffff0371450d002005280200102a20032802940621050b2005102a0b024020032d00a0064109470d000240200341f0056a41346a280200220528020441ffffffff0371450d002005280200102a20032802a40621050b2005102a0b024020032d00b0064109470d000240202b280200220528020441ffffffff0371450d002005280200102a20032802b40621050b2005102a0b024020032d00c0064109470d0002402023280200220528020441ffffffff0371450d002005280200102a20032802c40621050b2005102a0b024020032d00d0064109470d0002402012280200220528020441ffffffff0371450d002005280200102a20032802d40621050b2005102a0b024020032d00e0064109470d0002402001280200220528020441ffffffff0371450d002005280200102a20032802e40621050b2005102a0b024020032d00f0064109470d0002402013280200220528020441ffffffff0371450d002005280200102a20032802f40621050b2005102a0b024020032d0080074109470d000240202c280200220528020441ffffffff0371450d002005280200102a20032802840721050b2005102a0b024020032d0090074109470d000240202d280200220528020441ffffffff0371450d002005280200102a20032802940721050b2005102a0b024020032d00a0074109470d000240202e280200220528020441ffffffff0371450d002005280200102a20032802a40721050b2005102a0b024020032d00b0074109470d000240202f280200220528020441ffffffff0371450d002005280200102a20032802b40721050b2005102a0b024020032d00c0074109470d0002402030280200220528020441ffffffff0371450d002005280200102a20032802c40721050b2005102a0b024020032d00d0074109470d0002402031280200220528020441ffffffff0371450d002005280200102a20032802d40721050b2005102a0b200a4280808080808c0184210a202541016a21252027202a470d080c090b200741081037000b200541081037000b411041081037000b200541011037000b200541011037000b411041081037000b0240200b450d00200b417f6a210b200d20084102746a4194036a21050c010b0b0b4198ebc5004180011050000b02402024450d002016102a0b200341f0056a200341b0016a418c01109a051a200341e0046a200341f0056a10fe030240200341e0046a41106a2802002205450d0020032802e8042228200541306c6a212a0340024020282d000041786a220541024b0d0002400240024020050e03000102000b202828020c2205450d0220282802042208200541146c6a210c03400240200828020c0d002008280210210d200341e0006a21052003280264210e03402005280200220b41086a2107200b2f010622244102742105417f210902400340024020050d00202421090c020b20072802002106200941016a21092005417c6a2105200741046a21070240417f2006200d472006200d4b1b41016a0e03020001020b0b0240200b41346a20094105746a2205280210450d00200820052802143602100c030b4198ecc50041351050000b200e450d01200e417f6a210e200b20094102746a4194036a21050c000b0b200841146a2208200c470d000c030b0b20282802042106200341e0006a21052003280264210b03402005280200220d41086a2107200d2f0106220e4102742105417f210802400340024020050d00200e21080c020b20072802002109200841016a21082005417c6a2105200741046a21070240417f2009200647200920064b1b41016a0e03020001020b0b0240200d41346a20084105746a2205280210450d00202820052802143602040c040b4198ecc50041351050000b200b450d02200b417f6a210b200d20084102746a4194036a21050c000b0b202828020c2205450d00202828020422272005411c6c6a21260340024020272802182205450d002027280210220e20054102746a21250340200e220c41046a210e200c2802002106200341e0006a21052003280264210b03402005280200220d41086a2107200d2f010622244102742105417f2108024002400340024020050d00202421080c020b20072802002109200841016a21082005417c6a2105200741046a21070240417f2009200647200920064b1b41016a0e03020001020b0b0240200d41346a20084105746a2205280210450d00200c20052802143602000c020b4198ecc50041351050000b200b450d00200b417f6a210b200d20084102746a4194036a21050c010b0b200e2025470d000b0b2027411c6a22272026470d000b0b202841306a2228202a470d000b0b200341ec046a290200210a20032802e004210520032902e404213220032802602003280264200328026810da04200041106a200a370200200041086a203237020020002005360204200041003602002011450d1c2010102a200424000f0b200541cc006a28020021050c020b2005413c6a2108200541386a28020021050c010b200541286a2108200541246a28020021050b41012128410021140c080b200541cc006a28020021050c020b2005413c6a2108200541386a28020021050c010b200541286a2108200541246a28020021050b41002128410121140c040b200541cc006a28020021050c020b2005413c6a2108200541386a28020021050c010b200541286a2108200541246a28020021050b41002114410021280b2007212a0b2003200536027c02402005200f490d002003410136028406200342023702f40520034188ebc5003602f005200341013602d4032003200341d0036a360280062003200341fc006a3602d003200341e0046a200341f0056a103320032902e404220a422088a7210820032802e0042125200aa7211a0c0a0b201020054102746a2802002207450d050240024020262024460d0020242115202621240c010b202441016a22092024490d10202441017422062009200620094b1b221541ffffffff03712015470d10201541027422094100480d100240024020240d002009102821160c010b201620244102742009102c21160b2016450d020b201620244102746a2005360200200341f0056a200328027c220b200341c8006a10db0420032802f805211a20032802f4052125024020032802f00522194101470d0020032802fc052108201521240c0a0b20252802082205417f4c0d002025280200210920252d000c210602400240024020050d004100210e410121240c010b2005210e200510282224450d010b202420092005109a05210920032005360288012003200e360284012003200936028001200320063a008c01200320252d000d3a008d0120034100360290012003200328027c360298012003200736029c010240024002402003280270220741f8b9c000460d00200328027421270c010b20214200370100201b41206a420037010020224200370100201b41106a4200370100202b4200370100201b4200370100200341f0056a410041e0021099051a41940310282207450d014100212720074100360200200720032903e0043702042007410c6a200341e0046a41086a290300370200200741146a200341e0046a41106a2903003702002007411c6a200341e0046a41186a290300370200200741246a200341e0046a41206a2903003702002007412c6a200341e0046a41286a290300370200200741346a200341f0056a41e002109a051a20034100360274200320073602700b202641016a2126034020072f0106221841027421244100210541142106417f210902400340024020242005470d00201821090c020b200720056a210e200941016a2109200641206a2106200541046a21050240417f200e41086a280200220e200b47200e200b4b1b41016a0e03020001020b0b200720066a2205290200210a2005200329038001370200200541186a200329039801370200200541106a220729020021322007200329039001370200200541086a200329038801370200203242ffffffff0f83420285500d08200a42808080807083500d08200aa7102a0c080b02402027450d002027417f6a2127200720094102746a4194036a28020021070c010b0b2003200328027841016a360278200329039801210a20032903900121322003290388012133200329038001213420072f01062206410b490d0420214200370100201b41206a2235420037010020224200370100201b41106a22364200370100202b4200370100201b4200370100200341f0056a410041e0021099051a024041940310282205450d0020054100360200200520032903e0043702042005410c6a200341e0046a41086a222c290300370200200541146a200341e0046a41106a222d2903003702002005411c6a200341e0046a41186a222e290300370200200541246a200341e0046a41206a22372903003702002005412c6a200341e0046a41286a2238290300370200200541346a200341f0056a41e002109a05210e200341f0056a41086a2227200741fc016a290200370300200341f0056a41106a221820074184026a290200370300200341f0056a41186a22232007418c026a290200370300200320072902f4013703f00520072802202139200541086a200741246a20072f010641796a2206410274109a052124200e20074194026a2006410574109a05210e200741063b0106200520063b0106202e2023290300370300202d2018290300370300202c2027290300370300200320032903f0053703e0040240024020094107490d0020242009417a6a22134102746a2024200941796a22014102746a2209200641ffff037120016b410274109b051a2009200b360200200e20134105746a200e20014105746a2209200541066a22062f010020016b410574109b051a200941186a200a37020020092032370210200920333702082009203437020020062f0100210e0c010b200741086a2206200941016a22244102746a200620094102746a2201200741066a22062f0100220e20096b2213410274109b051a2001200b360200200741346a220b20244105746a200b20094105746a22092013410574109b051a200941186a200a3702002009203237021020092033370208200920343702000b2006200e41016a3b0100200341d0036a41186a222f202e290300220a370300200341d0036a41106a2230202d2903002232370300200341d0036a41086a2231202c2903002233370300200341b0016a41186a223a200a370300200341b0016a41106a223b2032370300200341b0016a41086a223c2033370300200320032903e004220a3703d0032003200a3703b00102402007280200220e0d00200521090c070b20072f010421012005213d0340200341c0026a41186a223e203a290300370300200341c0026a41106a223f203b290300370300200341c0026a41086a2240203c290300370300200320032903b0013703c002200141ffff0371210b02400240024002400240200e2f01062205410b490d0020214200370100203542003701002022420037010020364200370100202b4200370100201b42003701002031202c2903003703002030202d290300370300202f202e290300370300200341d0036a41206a22052037290300370300200341d0036a41286a22072038290300370300200320032903e0043703d003200341f0056a41004190031099051a41c40310282209450d0320094100360200200920032903d0033702042009410c6a2031290300370200200941146a20302903003702002009411c6a202f290300370200200941246a20052903003702002009412c6a2007290300370200200941346a200341f0056a419003109a052107200e41206a28020021412023200e418c026a2902003703002018200e4184026a2902003703002027200e41fc016a2902003703002003200e41f4016a2902003703f005200941086a200e41246a200e2f0106220641796a2205410274109a0521422007200e4194026a2005410574109a05214320094194036a200e41b0036a2006417a6a2224410274109a052113200e41063b0106200920053b010602402024450d00410021052013210703402007280200220620053b010420062009360200200741046a21072024200541016a2205470d000b0b202e2023290300220a370300202d20182903002232370300202c20272903002233370300200320032903f00522343703e0042023200a3703002018203237030020272033370300200320343703f005200141ffff037122074107490d012042200b417a6a220641027422246a2042200b41796a22054102746a220720092f010620056b410274109b051a20072039360200204320064105746a204320054105746a220720092f010620056b410574109b051a200741186a203e290300370200200741106a203f290300370200200741086a2040290300370200200720032903c002370200200920092f010641016a22073b0106200b410274220120136a416c6a201320246a2224200741ffff0371220b20066b410274109b051a2024203d360200200b2006490d02200920016a41fc026a2107034020072802002206200541016a22053b010420062009360200200741046a21072005200b490d000c030b0b200e41086a2207200b41016a220941027422066a2007200b41027422246a22072005200b6b2227410274109b051a20072039360200200e41346a220720094105746a2007200b4105746a22072027410574109b051a200741186a203e290300370200200741106a203f290300370200200741086a2040290300370200200720032903c002370200200e200541016a22053b01062024200e4194036a22076a41086a200720066a2207200541ffff0371220620096b410274109b051a2007203d360200200b20064f0d0c200e2009417f6a22054102746a4198036a2107034020072802002209200541016a22053b01042009200e360200200741046a210720052006490d000c0d0b0b200e41086a2205200b41016a222441027422066a2005200b41027422016a2205200e2f01062213200b6b2242410274109b051a20052039360200200e41346a220520244105746a2005200b4105746a22052042410574109b051a200541186a203e290300370200200541106a203f290300370200200541086a2040290300370200200520032903c002370200200e201341016a22053b01062001200e4194036a22136a41086a201320066a2213200541ffff0371220620246b410274109b051a2013203d360200200720064f0d00200e20016a4198036a2105034020052802002207200b41016a220b3b01042007200e360200200541046a21052006200b470d000b0b203a2023290300370300203b2018290300370300203c2027290300370300200320032903f0053703b001200e28020022050d01204121390c090b41c40341041037000b200e2f010421012005210e204121392009213d0c000b0b41940341041037000b41940341041037000b200541011037000b1036000b200941041037000b200741086a2205200941016a220e4102746a200520094102746a2205200620096b2224410274109b051a2005200b360200200741346a2205200e4105746a200520094105746a22052024410574109b051a200541186a200a3702002005203237021020052033370208200520343702002007200641016a3b01060c010b20214200370100203542003701002022420037010020364200370100202b4200370100201b42003701002031202c2903003703002030202d290300370300202f202e290300370300200341d0036a41206a22072037290300370300200341d0036a41286a22062038290300370300200320032903e0043703d003200341f0056a41004190031099051a41c40310282205450d0220054100360200200520032903d0033702042005410c6a2031290300370200200541146a20302903003702002005411c6a202f290300370200200541246a20072903003702002005412c6a2006290300370200200541346a200341f0056a419003109a05210b20052003280270220736029403200320053602702003200328027441016a36027420072005360200200741003b0104200b20052f010622064105746a220720032903b001370200200741186a203a290300370200200741106a203b290300370200200741086a203c290300370200200520064102746a41086a203936020020054194036a200641016a22074102746a2009360200200520073b0106200920073b0104200920053602000b02402019450d00201a450d002025102a0b201521240b202a2107202841ff01710e03010205010b41c40341041037000b410021050c040b410221050c030b20032802702003280274200328027810da0402402024450d002016102a0b02402020450d00202041306c2107201221050340200510dc04200541306a2105200741506a22070d000b0b0240200341d4006a280200450d002012102a0b2000202536020420004101360200200041086a2008ad422086201aad843702002011450d042010102a200424000f0b201f21170b410121050c000b0b024020012802102205450d0020012802082103200541306c21050340200310dc04200341306a2103200541506a22050d000b0b2001410c6a280200450d002001280208102a0b200424000f0b1031000bfc8c0204117f017e0b7f017e230041e0006b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e100100021817161514130d0b0c09080706010b200141186a2802002104200141146a2802002105200141106a28020021062001410c6a2802002107200141086a2802002108200141046a28020021090240200241046a280200200241086a280200220a460d002002280200210b0c1e0b200a41016a220b200a490d1a200a410174220c200b200c200b4b1b220c4100480d1a02400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d042002200b360200200241046a200c360200200241086a280200210a0c1d0b2001410c6a280200210b200141086a2802002105200141046a280200210420012d0001210d02400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d1a200a4101742206200c2006200c4b1b22064100480d1a02400240200a0d0020061028210c0c010b2002280200200a2006102c210c0b200c450d032002200c360200200241046a2006360200200241086a280200210a0b200241086a2206200a41016a360200200c200a6a200d3a000002400240200241046a280200220c2006280200220a6b200b490d002002280200210c0c010b200a200b6a220d200a490d1a200c410174220a200d200a200d4b1b220a4100480d1a02400240200c0d00200a1028210c0c010b2002280200200c200a102c210c0b200c450d022002200c360200200241046a200a360200200241086a280200210a0b200241086a200a200b6a360200200c200a6a2004200b109a051a4100210b4101210d024020050d004101210c0c270b2004102a4101210c0c260b2001410c6a2802002106200141086a280200210e200141046a280200210f024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d1a200a410174220c200b200c200b4b1b220c4100480d1a02400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41013a0000200f20064104746a21104100210c4100210b41002105410121042006210a024003400240200b2005470d00200c200b41016a220d200c200d4b1b22054100480d1c02400240200c0d002005102821040c010b2004200b2005102c21040b2004450d020b2004200b6a200a41807f72200a41ff0071200a410776220d1b3a0000200c41026a210c200b41016a210b200d210a200d0d000b024020060d00200f21080c190b200f210a02400340200a41106a2108200a2d000d22114105460d1a200a2d000c210c200a2802082109200a2802042112200a28020021130240024002400240024002402005200b470d00200b41016a220a200b490d22200b410174220d200a200d200a4b1b22054100480d2202400240200b0d002005102821040c010b2004200b2005102c21040b2004450d010b2004200b6a200c3a0000200b41016a210a200b410174220b41046a2107200b41026a210c2009210b0340200721060240200a2005470d00200a41016a220d200a490d23200c200d200c200d4b1b22054100480d2302400240200a0d002005102821040c010b2004200a2005102c21040b2004450d030b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200641026a2107200c41026a210c200a41016a210a200d210b200d0d000b0240024020090d00200a210b0c010b4100210c0340200a200c6a210b41fc00210d02400240024002402013200c6a2d00000e050200010305020b41fe00210d0c020b41fd00210d0c010b41ff00210d0b0240200b2005470d00200b41016a2205200b490d2420062005200620054b1b22054100480d2402400240200b0d002005102821040c010b2004200b2005102c21040b2004450d050b2004200a6a200c6a200d3a0000200641026a21062009200c41016a220c470d000b200a200c6a210b0b20120d030c040b200541011037000b200541011037000b200541011037000b2013102a0b4100210a0240024020114104460d0002402005200b470d00200b41016a220a200b490d1f200b410174220c200a200c200a4b1b22054100480d1f02400240200b0d002005102821040c010b2004200b2005102c21040b2004450d020b2004200b6a41013a0000200b41016a210b201141077141ff0073210a0b02402005200b470d00200b41016a220c200b490d1e200b410174220d200c200d200c4b1b22054100480d1e02400240200b0d002005102821040c010b2004200b2005102c21040b2004450d030b2004200b6a200a3a0000200b41016a210b2008210a20082010470d010c1c0b0b200541011037000b200541011037000b200541011037000b200c41011037000b200a41011037000b200641011037000b200c41011037000b200141286a2802002113200141246a280200210f200141206a28020021082001411c6a2802002107200141186a2802002112200141146a28020021092001410c6a2902002114200141086a2802002110200141046a28020021110240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d27200a410174220c200b200c200b4b1b220c4100480d2702400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41003a0000200341dc006a410036020020034201370254200320023602502014422088a7210d4100210a4100210b2014a72206210c034002400240200a200b460d002003280254210a0c010b200a41016a2204200a490d28200a41017422052004200520044b1b22044100480d2802400240200a0d0020041028210a0c010b2003280254200a2004102c210a0b200a450d03200320043602582003200a3602540b2003200b41016a36025c200a200b6a200c41807f72200c41ff0071200c41077622041b3a00002003280258210a200328025c210b2004210c20040d000b02400240200a200b6b2006490d00200328025421040c010b200b20066a220c200b490d27200a4101742204200c2004200c4b1b220c4100480d2702400240200a0d00200c102821040c010b2003280254200a200c102c21040b2004450d032003200c36025820032004360254200c210a0b2003200b20066a220c36025c2004200b6a20112006109a051a02402010450d002011102a0b034002400240200a200c460d002003280254210a0c010b200a41016a220b200a490d28200a4101742204200b2004200b4b1b220b4100480d2802400240200a0d00200b1028210a0c010b2003280254200a200b102c210a0b200a450d052003200b3602582003200a3602540b2003200c41016a36025c200a200c6a200d41807f72200d41ff0071200d410776220b1b3a00000240200b450d002003280258210a200328025c210c200b210d0c010b0b4101211102402009450d002007210b0340024002402003280258200328025c220a460d002003280254210c0c010b200a41016a220c200a490d29200a410174220d200c200d200c4b1b220d4100480d2902400240200a0d00200d1028210c0c010b2003280254200a200d102c210c0b200c450d072003200d3602582003200c3602540b2003200a41016a36025c200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002402003280258220b200328025c220a6b2007490d002003280254210b0c010b200a20076a220c200a490d28200b410174220d200c200d200c4b1b220c4100480d2802400240200b0d00200c1028210b0c010b2003280254200b200c102c210b0b200b450d072003200c3602582003200b3602540b2003200a20076a36025c200b200a6a20092007109a051a410021112012450d002009102a0b200820134104746a21062013210b0340024002402003280258200328025c220a460d002003280254210c0c010b200a41016a220c200a490d28200a410174220d200c200d200c4b1b220d4100480d2802400240200a0d00200d1028210c0c010b2003280254200a200d102c210c0b200c450d082003200d3602582003200c3602540b2003200a41016a36025c200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b2008210402402013450d00411021072008210403402004220b41106a2104200b280200220c4108460d01200b410c6a2802002102200b41086a280200210a200b280204210b024002400240024002400240024002400240200c0e080001020304050607000b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d31200c4101742205200d2005200d4b1b22054100480d3102400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d12200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41003a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d32200c4101742205200d2005200d4b1b22054100480d3202400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d14200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d32200b410174220d200c200d200c4b1b220d4100480d3202400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d152003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000c080b0b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d30200c4101742205200d2005200d4b1b22054100480d3002400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d14200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41013a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d31200c4101742205200d2005200d4b1b22054100480d3102400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d16200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d31200b410174220d200c200d200c4b1b220d4100480d3102400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d172003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000c070b0b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2f200c4101742205200d2005200d4b1b22054100480d2f02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d16200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41023a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d30200c4101742205200d2005200d4b1b22054100480d3002400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d18200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d30200b410174220d200c200d200c4b1b220d4100480d3002400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d192003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000c060b0b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2e200c4101742205200d2005200d4b1b22054100480d2e02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d18200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41033a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2f200c4101742205200d2005200d4b1b22054100480d2f02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d1a200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d2f200b410174220d200c200d200c4b1b220d4100480d2f02400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d1b2003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000b20032002200341d0006a10eb0420032d0000220a411f460d0420032f000120032d000341107472210d0c280b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2d200c4101742205200d2005200d4b1b22054100480d2d02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d1a200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41043a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2e200c4101742205200d2005200d4b1b22054100480d2e02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d1c200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d2e200b410174220d200c200d200c4b1b220d4100480d2e02400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d1d2003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000b20032002200341d0006a10eb0420032d0000220a411f460d0320032f000120032d000341107472210d0c270b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2c200c4101742205200d2005200d4b1b22054100480d2c02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d1c200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41053a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2d200c4101742205200d2005200d4b1b22054100480d2d02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d1e200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d2d200b410174220d200c200d200c4b1b220d4100480d2d02400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d1f2003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000b20032002200341d0006a10eb0420032d0000220a411f460d0220032f000120032d000341107472210d0c260b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2b200c4101742205200d2005200d4b1b22054100480d2b02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d1e200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41063a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2c200c4101742205200d2005200d4b1b22054100480d2c02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d20200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d2c200b410174220d200c200d200c4b1b220d4100480d2c02400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d212003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000c020b0b024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2a200c4101742205200d2005200d4b1b22054100480d2a02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d20200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a41073a00000340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2b200c4101742205200d2005200d4b1b22054100480d2b02400240200c0d0020051028210d0c010b2003280254200c2005102c210d0b200d450d22200320053602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200b41807f72200b41ff0071200b410776220c1b3a0000200c210b200c0d000b0340024002402003280258200328025c220b460d002003280254210c0c010b200b41016a220c200b490d2b200b410174220d200c200d200c4b1b220d4100480d2b02400240200b0d00200d1028210c0c010b2003280254200b200d102c210c0b200c450d232003200d3602582003200c360254200328025c210b0b2003200b41016a36025c200c200b6a200a41807f72200a41ff0071200a410776220b1b3a0000200b210a200b0d000b0b200741106a210720042006470d000b200621040b0240034020062004460d012004280200210a200441106a2104200a4108470d000b0b0240200f450d002008102a0b20032802582108200328025421022003280250220441086a210d200441046a2105200328025c2207210b0340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d28200a4101742206200c2006200c4b1b22064100480d2802400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d212004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d27200b410174220a200c200a200c4b1b220a4100480d2702400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d212004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021104101210d2009450d222011450d222012450d222009102a0c220b200c41011037000b200441011037000b200c41011037000b200b41011037000b200d41011037000b200c41011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200541011037000b200541011037000b200d41011037000b200641011037000b200a41011037000b20032903082114200328020421042013410474210c02400340200c2007460d01200820076a210b200741106a2107200b2802004108470d000b0b0240200f450d002008102a0b02402003280258450d002003280254102a0b02402009450d002011450d002012450d002009102a0b200a411f470d17410021104101210d0b4101210b4101210c410121044101210641012105410121074101210241012112410121084101210941012113410121110c3a0b2001412c6a280200210e200141286a2802002115200141246a2802002111200141206a28020021162001411c6a2802002117200141186a2802002118200141146a28020021102001410c6a2902002114200141086a2802002119200141046a28020021120240024002400240024002400240024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d14200a410174220c200b200c200b4b1b220c4100480d1402400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b4101210d200241086a200a41016a36020041002109200b200a6a41003a0000024041041028220f450d00200f41eec2b5ab063600000240024002400240024020120d00410021044100211a0c010b410121074100210a410021062014a72209210b034002400240200a2006460d00200a21082006210c0c010b200a41016a220c200a490d1a200a410174220d200c200d200c4b1b22084100480d1a02400240200a0d002008102821070c010b2007200a2008102c21070b02402007450d00200a210c2008210a0c010b200841011037000b2007200c6a200b41807f72200b41ff0071200b410776220d1b3a0000200c41016a2106200d210b200d0d000b02400240024002400240200820066b20094f0d00200620096a220a2006490d1d2008410174220b200a200b200a4b1b220a4100480d1d0240024020080d00200a102821070c010b20072008200a102c21070b2007450d01200a21080b200720066a20122009109a051a02402019450d002012102a0b41011028220d450d07200d41003a0000410221054101210a41012104200620096a2213210b03400240200a2004470d002005200a41016a2204200520044b1b22044100480d1e200d200a2004102c220d450d080b200d200a6a200b41807f72200b41ff0071200b41077622061b3a0000200541026a2105200a41016a210a2006210b20060d000b2004200a6b20134f0d03200a20136a220b200a490d1c20044101742205200b2005200b4b1b220b4100480d1c20040d01200b1028210d0c020b200a41011037000b200d2004200b102c210d0b200d450d02200b21040b200d200a6a20072013109a051a4101211a2009200c6a200a6a41016a21092008450d002007102a0b0240024002400240024020100d004101211b0c010b4100211b20034100360240200342013703382003410c6a2017360200200341086a201836020020032010360204200320144220883e0200200341d0006a2003200341386a10f104024020032d00502213411f460d0020032f005120032d0053411074722108200341d0006a41086a290300211420032802542116200328023c0d140c150b024020042009470d00200941016a220a2009490d1c2009410174220b200a200b200a4b1b22044100480d1c0240024020090d0020041028210d0c010b200d20092004102c210d0b200d450d040b200d20096a41013a0000200941016a210a200941017441026a210c20032802402206210b03400240200a2004470d00200a41016a2204200a490d1d200c2004200c20044b1b22044100480d1d02400240200a0d0020041028210d0c010b200d200a2004102c210d0b200d450d040b200d200a6a200b41807f72200b41ff0071200b41077622051b3a0000200c41026a210c200a41016a210a2005210b20050d000b2003280238210b02402004200a6b20064f0d00200a20066a220c200a490d1c20044101742205200c2005200c4b1b220c4100480d1c0240024020040d00200c1028210d0c010b200d2004200c102c210d0b200d450d02200c21040b200d200a6a200b2006109a051a0240200328023c450d00200b102a0b2006200a6a21094100211b0b024020110d00410021050c0e0b2003410036024020034201370338410121064100210c4100210a2016210b024003400240200a200c470d00200c41016a2205200c490d1d200c41017422072005200720054b1b22054100480d1d02400240200c0d002005102821060c010b2006200c2005102c21060b2006450d022003200536023c200320063602382005210c0b2003200a41016a22073602402006200a6a200b41807f72200b41ff0071200b41077622051b3a00002007210a2005210b20050d000b2011200e4104746a21080240200e0d00201121050c0c0b201121052016450d0b200841706a211c4100210a2011211d0340201d210502400340200541046a28020022130d01200a41016a210a2008200541106a2205470d000c0f0b0b200541106a211d200a41016a211e2016417f6a2116200541086a29020021142005280200211f200328023c210c2003280240210b02400240034002400240200b200c460d00200328023821060c010b200c41016a2206200c490d20200c41017422072006200720064b1b22074100480d2002400240200c0d002007102821060c010b2003280238200c2007102c21060b2006450d022003200736023c200320063602382007210c0b2003200b41016a22073602402006200b6a200a41807f72200a41ff0071200a41077622061b3a00002007210b2006210a20060d000b20032014370308200320133602042003201f360200200341d0006a2003200341386a10f10420032d00502213411f460d010c0c0b200741011037000b201c2005460d0b201e210a20160d000c0b0b0b200541011037000b200c41011037000b200441011037000b200441011037000b200b41011037000b200441011037000b410141011037000b410441011037000b200c41011037000b20032d0053211d20032f0051211f20032802542116200329035821140240200841706a2005460d00200541106a210503402005220a41106a21050240200a2802042206450d00200a28020821070240200a410c6a280200220a450d00200a410c6c210b2006210a03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b2007450d002006102a0b20052008470d000b0b02402015450d002011102a0b2013411f460d03201f201d41107472210841012105200328023c450d0b2003280238102a0c0b0b200541106a21050b20052008460d0003402005220a41106a21050240200a2802042206450d00200a28020821070240200a410c6a280200220a450d00200a410c6c210b2006210a03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b2007450d002006102a0b20052008470d000b0b2015450d002011102a0b024020042009470d00200941016a220a2009490d0e2009410174220b200a200b200a4b1b22044100480d0e0240024020090d0020041028210d0c010b200d20092004102c210d0b200d450d020b200d20096a41023a0000200941016a210a200941017441026a210c20032802402206210b03400240200a2004470d00200a41016a2204200a490d0f200c2004200c20044b1b22044100480d0f02400240200a0d0020041028210d0c010b200d200a2004102c210d0b200d450d040b200d200a6a200b41807f72200b41ff0071200b41077622051b3a0000200c41026a210c200a41016a210a2005210b20050d000b2003280238210b02402004200a6b20064f0d00200a20066a220c200a490d0e20044101742205200c2005200c4b1b220c4100480d0e0240024020040d00200c1028210d0c010b200d2004200c102c210d0b200d450d04200c21040b200d200a6a200b2006109a051a0240200328023c450d00200b102a0b2006200a6a2109410121050b201a201245720d032019450d032012102a0c030b200441011037000b200441011037000b200c41011037000b02402010450d00201b4101730d0002402017450d002017410c6c210b2010210a03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b2018450d002010102a0b2011452005720d030240200e450d002011200e4104746a21072011210603402006220541106a210602402005280204220a450d0002402005410c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b200541086a280200450d002005280204102a0b20062007470d000b0b2015450d032011102a0c030b2003280238102a0b410021050b0240201a201245720d002019450d002012102a0b02402010450d00201b4101730d0002402017450d002017410c6c210b2010210a03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b2018450d002010102a0b02402005201145720d000240200e450d002011200e4104746a21072011210603402006220541106a210602402005280204220a450d0002402005410c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b200541086a280200450d002005280204102a0b20062007470d000b0b2015450d002011102a0b2013411f460d002008410874201372210a02402004450d00200d102a0b2000200a360200200041086a2014370200200041046a2016360200200f102a0c010b200341146a2009360200200341106a20043602002003200d36020c20034284808080c0003702042003200f360200200341d0006a2003200210f504200320032900513703382003200341d0006a41086a29000037003f20032d0050220a411f460d012000200a3a000020002003290338370001200041086a200329003f3700000b410021084101210d4101210c4101210b4101210441012105410121064101210741012102410121090c1f0b410021114101210d4101210b4101210c4101210441012106410121054101210741012102410121124101210841012109410121130c380b2001410c6a2802002105200141086a2802002107200141046a28020021060240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d04200a410174220c200b200c200b4b1b220c4100480d0402400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a410b3a0000200341c4006a41003602002003420137023c2003200236023820062005411c6c6a21114100210a4100210b2005210c0240034002400240200a200b460d00200328023c210a0c010b200a41016a220d200a490d06200a4101742204200d2004200d4b1b220d4100480d0602400240200a0d00200d1028210a0c010b200328023c200a200d102c210a0b200a450d022003200d3602402003200a36023c0b2003200b41016a360244200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280240210a2003280244210b200c210c0c010b0b2003201136025c2003200636025820032007360254200320063602502005450d02034020032006220a411c6a2206360258200a2802102207450d03200a410c6a2802002102200a41086a2802002108200a2802042105200a41146a2902002114200a280200210b024002400240024003400240024020032802402003280244220a460d00200328023c210c0c010b200a41016a220c200a490d0b200a410174220d200c200d200c4b1b220d4100480d0b02400240200a0d00200d1028210c0c010b200328023c200a200d102c210c0b200c450d022003200d3602402003200c36023c2003280244210a0b2003200a41016a360244200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002400240024020050d00410121130c010b200320023602302003200836022c200320053602282003200341286a200341386a10e80420032d0000220a411f470d01410021130b2014a721092014422088a72204210b03400240024020032802402003280244220a460d00200328023c210c0c010b200a41016a220c200a490d0d200a410174220d200c200d200c4b1b220d4100480d0d02400240200a0d00200d1028210c0c010b200328023c200a200d102c210c0b200c450d052003200d3602402003200c36023c2003280244210a0b2003200a41016a360244200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002402003280240220b2003280244220a6b2004490d00200328023c210b0c010b200a20046a220c200a490d0c200b410174220a200c200a200c4b1b220a4100480d0c02400240200b0d00200a1028210b0c010b200328023c200b200a102c210b0b200b450d052003200a3602402003200b36023c2003280244210a0b2003200a20046a360244200b200a6a20072004109a051a02402009450d002007102a0b2005450d0520130d010c050b20032d0003411074210b20032f0001210c200329030821202003280204210d02402014a7450d002007102a0b200c200b72210b200341d0006a10f60402402003280240450d00200328023c102a0b2000200b3b00012000200a3a0000200041036a200b4110763a0000200041086a2020370000200041046a200d360000410021024101210d4101210c4101210b410121044101210541012106410121070c250b02402002450d002002410474210b2005210a03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b2008450d032005102a0c030b200d41011037000b200d41011037000b200a41011037000b20062011470d000c030b0b200d41011037000b200c41011037000b200341d0006a10f60420032802402108200328023c21022003280238220441086a210d200441046a210520032802442207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d05200a4101742206200c2006200c4b1b22064100480d0502400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d04200b410174220a200c200a200c4b1b220a4100480d0402400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021134101210d4101210b4101210c4101210441012106410121054101210741012102410121124101210841012109410121110c390b200641011037000b200a41011037000b2001410c6a2802002106200141086a2802002107200141046a280200210d0240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d14200a410174220c200b200c200b4b1b220c4100480d1402400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a410a3a0000200341246a41003602002003420137021c20032002360218200d200641186c6a210f4100210a4100210b2006210c0240034002400240200a200b460d00200328021c210a0c010b200a41016a2204200a490d16200a41017422052004200520044b1b22044100480d1602400240200a0d0020041028210a0c010b200328021c200a2004102c210a0b200a450d02200320043602202003200a36021c0b2003200b41016a360224200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280220210a2003280224210b200c210c0c010b0b2003200f3602342003200d3602302003200736022c2003200d3602282006450d0220034101722102200341026a2107024003402003200d41186a2213360230200d2802002208450d04200d41146a2802002111200d41106a2802002110200d28020c2109200d280208210c200d28020421124100210b200341003602442003420137023c2008200c4103746a21062003200341186a3602384100210a02400240034002400240200b200a460d00200328023c210b0c010b200b41016a220a200b490d1a200b410174220d200a200d200a4b1b220a4100480d1a02400240200b0d00200a1028210b0c010b200328023c200b200a102c210b0b200b450d022003200a3602402003200b36023c2003280244210a0b2003200a41016a360244200b200a6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280240210b2003280244210a200c210c0c010b0b024020062008470d00200821040c020b2008210a0340200a41086a2104200a2902002214422088a7220a41ff01714104460d02200a41187441187521052014a7210b02400240024003400240024020032802402003280244220a460d00200328023c210c0c010b200a41016a220c200a490d0d200a410174220d200c200d200c4b1b220d4100480d0d02400240200a0d00200d1028210c0c010b200328023c200a200d102c210c0b200c450d022003200d3602402003200c36023c2003280244210a0b2003200a41016a360244200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024020032802402003280244220a460d00200328023c210b0c030b200a41016a220b200a490d0b200a410174220c200b200c200b4b1b220c4100480d0b02400240200a0d00200c1028210b0c010b200328023c200a200c102c210b0b200b450d012003200c3602402003200b36023c2003280244210a0c020b200d41011037000b200c41011037000b2003200a41016a360244200b200a6a2005417f73220a413f7141c00072200a2005417f4a1b3a00002004210a20042006470d000b200621040c010b200a41011037000b0240034020062004460d0120042d0004210a200441086a2104200a4104470d000b0b02402012450d002008102a0b20092011410474220a6a210c0240024002400240024020110d002009210a0c010b200a41706a210d2009210a0340200a2d0000210b2007200a41036a2d00003a00002003200a41016a2f00003b01000240200b41ac01470d00200a41106a210a0c020b200341cc006a41026a20072d000022043a0000200320032f010022053b014c200a41046a2802002106200a41086a2903002114200220053b0000200241026a20043a00002003200b3a00002003201437030820032006360204200341d0006a2003200341386a10f004024020032d00502204411f46220b450d00200d41706a210d200a41106a220a200c470d010c030b0b20032d0053210520032f0051210620032802542108200329035821140240200d450d00200a41106a210a034002400240200a2d0000220d4109460d00200d41ac01470d010c030b0240200a41046a280200220d28020441ffffffff0371450d00200d280200102a0b200d102a0b200a41106a220a200c470d000b0b02402010450d002009102a0b02402003280240450d00200328023c102a0b200b0d022006200541107472210a200341286a10f70402402003280220450d00200328021c102a0b2000200a3b0001200020043a0000200041036a200a4110763a0000200041086a2014370000200041046a2008360000410021074101210d4101210c4101210b4101210441012105410121060c230b200a200c460d00034002400240200a2d0000220b4109460d00200b41ac01470d010c030b0240200a41046a280200220b28020441ffffffff0371450d00200b280200102a0b200b102a0b200a41106a220a200c470d000b0b02402010450d002009102a0b20032802402111200328023c21092003280238210c20032802442208210b034002400240200c41086a2205280200200c410c6a2204280200220a460d00200c280204210d0c010b200a41016a220d200a490d09200a4101742206200d2006200d4b1b22064100480d0902400240200a0d0020061028210d0c010b200c280204200a2006102c210d0b200d450d03200c200d360204200520063602002004280200210a0b2004200a41016a360200200d200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002402005280200220b2004280200220a6b2008490d00200c280204210b0c010b200a20086a220d200a490d08200b410174220a200d200a200d4b1b220a4100480d0802400240200b0d00200a1028210b0c010b200c280204200b200a102c210b0b200b450d04200c200b3602042005200a3602002004280200210a0b2004200a20086a360200200b200a6a20092008109a051a2011450d002009102a0b2013210d2013200f470d010c050b0b200641011037000b200a41011037000b200441011037000b200c41011037000b200341286a10f70420032802202108200328021c21022003280218220441086a210d200441046a210520032802242207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d04200a4101742206200c2006200c4b1b22064100480d0402400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d03200b410174220a200c200a200c4b1b220a4100480d0302400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021094101210d4101210b4101210c410121044101210641012105410121074101210241012112410121080c280b200641011037000b200a41011037000b1031000b2001410c6a2802002105200141086a2802002106200141046a28020021080240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d12200a410174220c200b200c200b4b1b220c4100480d1202400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41093a0000200341c4006a41003602002003420137023c2003200236023820082005411c6c6a21124100210a4100210b2005210c0240034002400240200a200b460d00200328023c210a0c010b200a41016a220d200a490d14200a4101742204200d2004200d4b1b220d4100480d1402400240200a0d00200d1028210a0c010b200328023c200a200d102c210a0b200a450d022003200d3602402003200a36023c0b2003200b41016a360244200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280240210a2003280244210b200c210c0c010b0b2003201236025c2003200836025820032006360254200320083602502005450d02034020032008220a411c6a2208360258200a2802102206450d03200a410c6a2802002102200a41086a2802002109200a2802042107200a41146a2902002114200a280200210b024002400240024003400240024020032802402003280244220a460d00200328023c210c0c010b200a41016a220c200a490d19200a410174220d200c200d200c4b1b220d4100480d1902400240200a0d00200d1028210c0c010b200328023c200a200d102c210c0b200c450d022003200d3602402003200c36023c2003280244210a0b2003200a41016a360244200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002400240024020070d00410121110c010b200320023602302003200936022c200320073602282003200341286a200341386a10e80420032d0000220a411f470d01410021110b20062014422088a7220b4102746a21052014a7211303400240024020032802402003280244220a460d00200328023c210c0c010b200a41016a220c200a490d1b200a410174220d200c200d200c4b1b220d4100480d1b02400240200a0d00200d1028210c0c010b200328023c200a200d102c210c0b200c450d052003200d3602402003200c36023c2003280244210a0b2003200a41016a360244200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024020052006460d002006210403402004280200210b03400240024020032802402003280244220a460d00200328023c210c0c010b200a41016a220c200a490d1d200a410174220d200c200d200c4b1b220d4100480d1d02400240200a0d00200d1028210c0c010b200328023c200a200d102c210c0b200c450d082003200d3602402003200c36023c2003280244210a0b2003200a41016a360244200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b200441046a22042005470d000b0b02402013450d002006102a0b2007450d0520110d010c050b20032d0003411074210b20032f0001210c200329030821202003280204210d02402014a7450d002006102a0b200c200b72210b200341d0006a10f80402402003280240450d00200328023c102a0b2000200b3b00012000200a3a0000200041036a200b4110763a0000200041086a2020370000200041046a200d360000410021064101210d4101210c4101210b41012104410121050c200b02402002450d002002410474210b2007210a03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b2009450d032007102a0c030b200d41011037000b200d41011037000b200d41011037000b20082012470d000c030b0b200d41011037000b200c41011037000b200341d0006a10f80420032802402108200328023c21022003280238220441086a210d200441046a210520032802442207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d13200a4101742206200c2006200c4b1b22064100480d1302400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d12200b410174220a200c200a200c4b1b220a4100480d1202400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021084101210d4101210b4101210c4101210441012106410121054101210741012102410121120c250b200641011037000b200a41011037000b200141046a280200210a024002400240024002400240200241046a280200200241086a280200220b460d002002280200210c0c010b200b41016a220c200b490d13200b410174220d200c200d200c4b1b220d4100480d1302400240200b0d00200d1028210c0c010b2002280200200b200d102c210c0b200c450d012002200c360200200241046a200d360200200241086a280200210b0b200241086a200b41016a360200200c200b6a410c3a00004100210c4100210b410021064101210503400240200b2006470d00200c200b41016a220d200c200d4b1b22064100480d1402400240200c0d002006102821050c010b2005200b2006102c21050b2005450d030b2005200b6a200a41807f72200a41ff0071200a410776220d1b3a0000200c41026a210c200b41016a210b200d210a200d0d000b200b417f6a2109200241086a2104200241046a2107200b210c03400240024020072802002004280200220a460d002002280200210d0c010b200a41016a220d200a490d14200a4101742208200d2008200d4b1b22084100480d1402400240200a0d0020081028210d0c010b2002280200200a2008102c210d0b200d450d042002200d360200200720083602002004280200210a0b2004200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200241046a280200220c200241086a280200220a6b20094d0d002002280200210c0c010b200a200b6a220d200a490d13200c410174220a200d200a200d4b1b220a4100480d1302400240200c0d00200a1028210c0c010b2002280200200c200a102c210c0b200c450d042002200c360200200241046a200a360200200241086a280200210a0b200241086a200a200b6a360200200c200a6a2005200b109a051a4101210d2006450d052005102a0c050b200d41011037000b200641011037000b200841011037000b200a41011037000b200141046a280200210a02400240200241046a280200200241086a280200220b460d002002280200210c0c010b200b41016a220c200b490d0e200b410174220d200c200d200c4b1b220d4100480d0e02400240200b0d00200d1028210c0c010b2002280200200b200d102c210c0b200c450d022002200c360200200241046a200d360200200241086a280200210b0b200241086a200b41016a360200200c200b6a41083a00004100210c4100210b410021064101210503400240200b2006470d00200c200b41016a220d200c200d4b1b22064100480d0f02400240200c0d002006102821050c010b2005200b2006102c21050b2005450d040b2005200b6a200a41807f72200a41ff0071200a410776220d1b3a0000200c41026a210c200b41016a210b200d210a200d0d000b200b417f6a2109200241086a2104200241046a2107200b210c03400240024020072802002004280200220a460d002002280200210d0c010b200a41016a220d200a490d0f200a4101742208200d2008200d4b1b22084100480d0f02400240200a0d0020081028210d0c010b2002280200200a2008102c210d0b200d450d052002200d360200200720083602002004280200210a0b2004200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200241046a280200220c200241086a280200220a6b20094d0d002002280200210c0c010b200a200b6a220d200a490d0e200c410174220a200d200a200d4b1b220a4100480d0e02400240200c0d00200a1028210c0c010b2002280200200c200a102c210c0b200c450d052002200c360200200241046a200a360200200241086a280200210a0b200241086a200a200b6a360200200c200a6a2005200b109a051a4101210d2006450d002005102a0b4101210b4101210c0c190b200d41011037000b200641011037000b200841011037000b200a41011037000b2001410c6a2802002106200141086a280200210f200141046a28020021100240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d10200a410174220c200b200c200b4b1b220c4100480d1002400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41073a00002010200641146c6a2112410021044100210a4100210c4101210b2006210d03400240200a200c470d002004200a41016a220c2004200c4b1b220c4100480d110240024020040d00200c1028210b0c010b200b200a200c102c210b0b200b450d030b200b200a6a200d41807f72200d41ff0071200d41077622051b3a0000200441026a2104200a41016a210a2005210d20050d000b024020060d00201021080c070b201021040340200441146a2108200428020c22134104460d072004280204211120042802002109200a4101742105200441106a280200210d20042802082207210403400240200a200c470d00200a41016a220c200a490d122005200c2005200c4b1b220c4100480d1202400240200a0d00200c1028210b0c010b200b200a200c102c210b0b200b450d050b200b200a6a200441807f72200441ff0071200441077622061b3a0000200541026a2105200a41016a210a2006210420060d000b02400240200c200a6b2007490d00200c21040c010b200a20076a2204200a490d11200c41017422052004200520044b1b22044100480d1102400240200c0d0020041028210b0c010b200b200c2004102c210b0b200b450d050b200b200a6a20092007109a051a200720046b200a6a210c02402011450d002009102a0b02400240200c450d002004210c0c010b200441016a220c2004490d1120044101742205200c2005200c4b1b220c4100480d110240024020040d00200c1028210b0c010b200b2004200c102c210b0b200b450d060b200b20076a200a6a20133a00002007200a6a41016a210a03400240200a200c470d00200a41016a220c200a490d12200a4101742204200c2004200c4b1b220c4100480d1202400240200a0d00200c1028210b0c010b200b200a200c102c210b0b200b450d080b200b200a6a200d41807f72200d41ff0071200d41077622041b3a0000200a41016a210a2004210d20040d000b2008210420082012470d000c080b0b200c41011037000b200c41011037000b200c41011037000b200441011037000b200c41011037000b200c41011037000b20082012460d0003402008410c6a2802004104460d010240200841046a280200450d002008280200102a0b200841146a22082012470d000b0b0240200f450d002010102a0b200241086a2106200241046a2107200a210402400240024003400240024020072802002006280200220d460d00200228020021050c010b200d41016a2205200d490d0c200d41017422082005200820054b1b22084100480d0c02400240200d0d002008102821050c010b2002280200200d2008102c21050b2005450d0220022005360200200720083602002006280200210d0b2006200d41016a3602002005200d6a200441807f72200441ff00712004410776220d1b3a0000200d2104200d0d000b02400240200241046a2802002204200241086a280200220d6b200a490d00200228020021040c010b200d200a6a2205200d490d0b2004410174220d2005200d20054b1b220d4100480d0b0240024020040d00200d102821040c010b20022802002004200d102c21040b2004450d0220022004360200200241046a200d360200200241086a280200210d0b200241086a200d200a6a3602002004200d6a200b200a109a051a410021124101210d200c450d02200b102a0c020b200841011037000b200d41011037000b4101210b4101210c41012104410121064101210541012107410121020c1a0b2001410c6a2802002105200141086a2802002112200141046a2802002108024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d0e200a410174220c200b200c200b4b1b220c4100480d0e02400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41063a0000200341dc006a41003602002003420137025420032002360250200820054104746a21134100210a4100210b2005210c034002400240200a200b460d002003280254210a0c010b200a41016a220d200a490d0f200a4101742204200d2004200d4b1b220d4100480d0f02400240200a0d00200d1028210a0c010b2003280254200a200d102c210a0b200a450d032003200d3602582003200a3602540b2003200b41016a36025c200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280258210a200328025c210b200c210c0c010b0b200821042005450d05200541047421114100210c034002402008200c6a220b410d6a2d000022044102470d00200b41106a21040c070b200b2802002105200b41086a2802002106200b41046a2802002107200b410c6a2d00002102024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d0f200a4101742209200d2009200d4b1b22094100480d0f02400240200a0d0020091028210d0c010b2003280254200a2009102c210d0b200d450d04200320093602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200241ff00733a0000024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d0f200a4101742202200d2002200d4b1b22024100480d0f02400240200a0d0020021028210d0c010b2003280254200a2002102c210d0b200d450d05200320023602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a20043a0000200320063602402003200736023c200320053602382003200341386a200341d0006a10e80420032d00002205411f470d052011200c41106a220c470d000c070b0b200c41011037000b200d41011037000b200941011037000b200241011037000b20032d0003210220032f0001210920032802042111200329030821140240200b41106a2013460d00200b41106a210403402004410d6a2d00004102460d01200428020421072004280200210602402004280208220a450d00200a410474210b2006210a03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441106a210402402007450d002006102a0b20042013470d000b0b2002411074210a02402012450d002008102a0b2009200a72210a02402003280258450d002003280254102a0b2000200a3b0001200020053a0000200041036a200a4110763a0000200041086a2014370000200041046a2011360000410021054101210d4101210c4101210b410121040c0f0b20042013460d0003402004410d6a2d00004102460d01200428020421062004280200210502402004280208220a450d00200a410474210b2005210a03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441106a210402402006450d002005102a0b20042013470d000b0b02402012450d002008102a0b20032802582108200328025421022003280250220441086a210d200441046a2105200328025c2207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d0a200a4101742206200c2006200c4b1b22064100480d0a02400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d09200b410174220a200c200a200c4b1b220a4100480d0902400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021024101210d4101210b4101210c410121044101210641012105410121070c1a0b200641011037000b200a41011037000b2001410c6a2802002107200141086a2802002108200141046a280200210602400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d09200a410174220c200b200c200b4b1b220c4100480d0902400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41053a0000200341d0006a410c6a4100360200200342013702542003200236025020062007410c6c6a2102410121044100210c4100210a2007210b03400240200a200c470d00200c41016a220d200c490d0a200c4101742205200d2005200d4b1b220d4100480d0a02400240200c0d00200d102821040c010b2004200c200d102c21040b2004450d04200d210c0b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200a41016a210a200d210b200d0d000b2003200c3602582003200a36025c200320043602542006210a2007450d012007410c6c210d4100210b0340024002402006200b6a220a41046a280200220c4102460d002003200a280200200c200a41086a280200200341d0006a10f20420032d00002204411f460d0120032f000120032d00034110747221052003290308211420032802042107200a410c6a210c200d200b6b41746a210a02400340200a450d01200a41746a210a200c280204210b200c410c6a210c200b4102470d000b0b02402008450d002006102a0b02402003280258450d002003280254102a0b200020053b0001200020043a0000200041036a20054110763a0000200041086a2014370000200041046a2007360000410021044101210d4101210c4101210b0c110b200a410c6a210a0c030b200d200b410c6a220b470d000b2002210a0c010b200c41011037000b200a410020076b410c6c6a210b024003402006200b460d01200b410c6a210b200a280204210c200a410c6a210a200c4102470d000b0b02402008450d002006102a0b20032802582108200328025421022003280250220441086a210d200441046a2105200328025c2207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d0a200a4101742206200c2006200c4b1b22064100480d0a02400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d09200b410174220a200c200a200c4b1b220a4100480d0902400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021074101210d4101210b4101210c4101210441012106410121050c190b200641011037000b200a41011037000b200d41011037000b2001410c6a2802002109200141086a2802002113200141046a2802002106024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d09200a410174220c200b200c200b4b1b220c4100480d0902400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41043a0000200341d0006a410c6a4100360200200342013702542003200236025020062009410c6c6a2111410121044100210c4100210a2009210b03400240200a200c470d00200c41016a220d200c490d0a200c4101742205200d2005200d4b1b220d4100480d0a02400240200c0d00200d102821040c010b2004200c200d102c21040b2004450d05200d210c0b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200a41016a210a200d210b200d0d000b2003200c3602582003200a36025c200320043602542006210a2009450d022009410c6c21084100210c03400240024002402006200c6a220b41046a28020022044102460d00200b2802002105200b41086a28020021072003280258200328025c220a460d012003280254210d0c020b200b410c6a210a0c050b200a41016a220d200a490d0a200a4101742202200d2002200d4b1b22024100480d0a02400240200a0d0020021028210d0c010b2003280254200a2002102c210d0b200d450d03200320023602582003200d3602540b2003200a41016a36025c200d200a6a41f0003a00002003200520042007200341d0006a10f204024020032d0000220d411f460d0020032f000120032d00034110747221042003290308211420032802042105200b410c6a210b2008200c6b41746a210a02400340200a450d01200a41746a210a200b280204210c200b410c6a210b200c4102470d000b0b02402013450d002006102a0b02402003280258450d002003280254102a0b200020043b00012000200d3a0000200041036a20044110763a0000200041086a2014370000200041046a20053600004100210b4101210d4101210c0c0f0b2008200c410c6a220c470d000b2011210a0c020b200c41011037000b200241011037000b200a410020096b410c6c6a210b024003402006200b460d01200b410c6a210b200a280204210c200a410c6a210a200c4102470d000b0b02402013450d002006102a0b20032802582108200328025421022003280250220441086a210d200441046a2105200328025c2207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d09200a4101742206200c2006200c4b1b22064100480d0902400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d08200b410174220a200c200a200c4b1b220a4100480d0802400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021054101210d4101210b4101210c41012104410121060c170b200641011037000b200a41011037000b200d41011037000b2001410c6a2802002106200141086a2802002109200141046a280200210802400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d0a200a410174220c200b200c200b4b1b220c4100480d0a02400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41033a0000200820064102746a21074100210c4100210a41002105410121042006210b03400240200a2005470d00200c200a41016a220d200c200d4b1b22054100480d0b02400240200c0d002005102821040c010b2004200a2005102c21040b2004450d030b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200c41026a210c200a41016a210a200d210b200d0d000b02402006450d00200821060340200a410174210c2006280200210b03400240200a2005470d00200a41016a220d200a490d0d200c200d200c200d4b1b22054100480d0d02400240200a0d002005102821040c010b2004200a2005102c21040b2004450d060b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200c41026a210c200a41016a210a200d210b200d0d000b200641046a22062007470d000b0b02402009450d002008102a0b200241086a2106200241046a2107200a210c03400240024020072802002006280200220b460d002002280200210d0c010b200b41016a220d200b490d0b200b4101742208200d2008200d4b1b22084100480d0b02400240200b0d0020081028210d0c010b2002280200200b2008102c210d0b200d450d052002200d360200200720083602002006280200210b0b2006200b41016a360200200d200b6a200c41807f72200c41ff0071200c410776220b1b3a0000200b210c200b0d000b02400240200241046a280200220c200241086a280200220b6b200a490d002002280200210c0c010b200b200a6a220d200b490d0a200c410174220b200d200b200d4b1b220b4100480d0a02400240200c0d00200b1028210c0c010b2002280200200c200b102c210c0b200c450d052002200c360200200241046a200b360200200241086a280200210b0b200241086a200b200a6a360200200c200b6a2004200a109a051a410021064101210d2005450d052004102a0c050b200c41011037000b200541011037000b200541011037000b200841011037000b200b41011037000b4101210b4101210c410121040c120b2001410c6a2802002106200141086a2802002117200141046a280200210e0240024002400240024002400240024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d14200a410174220c200b200c200b4b1b220c4100480d1402400240200a0d00200c1028210b0c010b2002280200200a200c102c210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41023a0000200341dc006a41003602002003420137025420032002360250200e200641286c6a21094100210a4100210b2006210c034002400240200a200b460d002003280254210a0c010b200a41016a220d200a490d15200a4101742204200d2004200d4b1b220d4100480d1502400240200a0d00200d1028210a0c010b2003280254200a200d102c210a0b200a450d032003200d3602582003200a3602540b2003200b41016a36025c200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280258210a200328025c210b200c210c0c010b0b200e21052006450d0f200e210503402005220a41286a2105200a2d001822134104460d10200a41206a2900002114200a411c6a2800002104200a411a6a2d0000210f200a41196a2c00002110200a41146a2802002106200a41106a2802002111200a28020c2102200a2802042112200a2802002108200a2802082207210b0340024002402003280258200328025c220a460d002003280254210c0c010b200a41016a220c200a490d16200a410174220d200c200d200c4b1b220d4100480d1602400240200a0d00200d1028210c0c010b2003280254200a200d102c210c0b200c450d052003200d3602582003200c360254200328025c210a0b2003200a41016a36025c200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002402003280258220b200328025c220a6b2007490d002003280254210b0c010b200a20076a220c200a490d15200b410174220a200c200a200c4b1b220a4100480d1502400240200b0d00200a1028210b0c010b2003280254200b200a102c210b0b200b450d052003200a3602582003200b360254200328025c210a0b2003200a20076a36025c200b200a6a20082007109a051a02402012450d002008102a0b2006210b0340024002402003280258200328025c220a460d002003280254210c0c010b200a41016a220c200a490d16200a410174220d200c200d200c4b1b220d4100480d1602400240200a0d00200d1028210c0c010b2003280254200a200d102c210c0b200c450d072003200d3602582003200c360254200328025c210a0b2003200a41016a36025c200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002402003280258220b200328025c220a6b2006490d002003280254210b0c010b200a20066a220c200a490d15200b410174220a200c200a200c4b1b220a4100480d1502400240200b0d00200a1028210b0c010b2003280254200b200a102c210b0b200b450d072003200a3602582003200b360254200328025c210a0b2003200a20066a36025c200b200a6a20022006109a051a02402011450d002002102a0b0240024002400240024020130e0400010203000b024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d19200a410174220c200b200c200b4b1b220c4100480d1902400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d0c2003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a41003a00000340024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d1a200a410174220c200b200c200b4b1b220c4100480d1a02400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d0e2003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a200441807f72200441ff00712004410776220a1b3a0000200a2104200a0d000c040b0b024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d18200a410174220c200b200c200b4b1b220c4100480d1802400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d0d2003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a41013a0000024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d18200a410174220c200b200c200b4b1b220c4100480d1802400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d0e2003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a41f0003a0000200320042014a72014422088a7200341d0006a10f20420032d0000220a411f460d0220032f000120032d000341107472210d0c120b024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d17200a410174220c200b200c200b4b1b220c4100480d1702400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d0e2003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a41023a0000200320042014a72014422088a7200341d0006a10f20420032d0000220a411f460d0120032f000120032d000341107472210d0c110b024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d16200a410174220c200b200c200b4b1b220c4100480d1602400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d0e2003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a41033a0000024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d16200a410174220c200b200c200b4b1b220c4100480d1602400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d0f2003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a2010417f73220a413f7141c00072200a2010417f4a1b3a0000024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d16200a410174220c200b200c200b4b1b220c4100480d1602400240200a0d00200c1028210b0c010b2003280254200a200c102c210b0b200b450d102003200c3602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a200f41ff01714100473a00000b20052009470d000c110b0b200c41011037000b200d41011037000b200d41011037000b200a41011037000b200d41011037000b200a41011037000b200c41011037000b200c41011037000b200c41011037000b200c41011037000b200c41011037000b200c41011037000b200c41011037000b200c41011037000b2003290308211420032802042104024020052009460d000340200541186a2d00004104460d01200541106a280200210b2005410c6a280200210c0240200541046a280200450d002005280200102a0b0240200b450d00200c102a0b200541286a22052009470d000b0b02402017450d00200e102a0b02402003280258450d002003280254102a0b2000200d3b00012000200a3a0000200041036a200d4110763a0000200041086a2014370000200041046a20043600004100210c4101210d0c080b20052009460d000340200541186a2d00004104460d01200541106a280200210a2005410c6a280200210b0240200541046a280200450d002005280200102a0b0240200a450d00200b102a0b200541286a22052009470d000b0b02402017450d00200e102a0b20032802582108200328025421022003280250220441086a210d200441046a2105200328025c2207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d06200a4101742206200c2006200c4b1b22064100480d0602400240200a0d0020061028210c0c010b2004280200200a2006102c210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d05200b410174220a200c200a200c4b1b220a4100480d0502400240200b0d00200a1028210b0c010b2004280200200b200a102c210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109a051a02402008450d002002102a0b410021044101210d4101210b4101210c0c120b200641011037000b200a41011037000b20082010460d0003402008410d6a2d00004105460d010240200841046a280200450d002008280200102a0b200841106a22082010470d000b0b0240200e450d00200f102a0b200241086a2106200241046a2107200b210c0240024003400240024020072802002006280200220a460d002002280200210d0c010b200a41016a220d200a490d04200a4101742208200d2008200d4b1b22084100480d0402400240200a0d0020081028210d0c010b2002280200200a2008102c210d0b200d450d022002200d360200200720083602002006280200210a0b2006200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200241046a280200220c200241086a280200220a6b200b490d002002280200210c0c010b200a200b6a220d200a490d03200c410174220a200d200a200d4b1b220a4100480d0302400240200c0d00200a1028210c0c010b2002280200200c200a102c210c0b200c450d022002200c360200200241046a200a360200200241086a280200210a0b200241086a200a200b6a360200200c200a6a2004200b109a051a4100210c4101210d2005450d032004102a0c030b200841011037000b200a41011037000b1031000b4101210b0c0b0b2000200d3b00012000200a3a0000200041036a200d4110763a0000200041086a2014370000200041046a2004360000410021094101210d4101210c4101210b4101210441012105410121064101210741012102410121080c080b4101210c200241086a200a41016a3602004100210d200b200a6a41003a0000200341146a2004360200200341106a20053602002003200636020c200320073602082003200836020420032009360200200341d0006a2003200210f504200320032900513703382003200341d0006a41086a29000037003f20032d0050220a411f460d082000200a3a000020002003290338370001200041086a200329003f3700000b4101210b0b410121040b410121050b410121060b410121070b410121020b41012108410121090b20012d0000220a410f4b0d18200a0e100a0b0c0d0e0f101112181318141516170a0b4101210b4100210d4101210c0b410121040b410121060b410121050b410121070b410121020b410121120b410121080b410121090b41012113410121110c0f0b200141086a280200450d10200141046a280200102a0c100b200d450d0f0240200141086a280200450d00200141046a280200102a0b200141146a280200450d0f200141106a280200102a0c0f0b02402001410c6a280200220b450d00200141046a280200210a200b410474210b03400240200a41046a280200450d00200a280200102a0b200a41106a210a200b41706a220b0d000b0b200141086a280200450d0e2001280204102a0c0e0b200c450d0d02402001410c6a280200220b450d00200141046a280200210a200b41286c210b03400240200a41046a280200450d00200a280200102a0b0240200a41106a280200450d00200a410c6a280200102a0b200a41286a210a200b41586a220b0d000b0b200141086a280200450d0d2001280204102a0c0d0b200141086a280200450d0c200141046a280200102a0c0c0b200b450d0b200141086a280200450d0b200141046a280200102a0c0b0b2004450d0a200141086a280200450d0a200141046a280200102a0c0a0b2005450d0902402001410c6a280200220a450d00200141046a2802002204200a4104746a2105034002402004280208220b450d002004280200210a200b410474210b03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441106a210a0240200441046a280200450d002004280200102a0b200a2104200a2005470d000b0b200141086a280200450d092001280204102a0c090b02402001410c6a280200220b450d00200141046a280200210a200b41146c210b03400240200a41046a280200450d00200a280200102a0b200a41146a210a200b416c6a220b0d000b0b200141086a280200450d082001280204102a0c080b2006450d0702402001410c6a280200220a450d00200141046a2802002204200a411c6c6a2105034002402004280204220a450d0002402004410c6a280200220b450d00200b410474210b03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441086a280200450d002004280204102a0b2004411c6a210a0240200441146a280200450d002004280210102a0b200a2104200a2005470d000b0b200141086a280200450d072001280204102a0c070b2007450d0602402001410c6a280200220a450d00200141046a2802002204200a41186c6a210503400240200441046a280200450d002004280200102a0b0240200441146a280200220b450d00200428020c210a200b410474210b03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441186a210a0240200441106a280200450d00200428020c102a0b200a2104200a2005470d000b0b200141086a280200450d062001280204102a0c060b2002450d05200141046a220a10f904200141086a280200450d05200a280200102a0c050b2008450d040240200141046a280200220a450d00200141086a280200450d00200a102a0b0240200141146a280200220a450d0002402001411c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b200141186a280200450d002001280214102a0b200141246a2802002204450d0402402001412c6a280200220a450d002004200a4104746a210503402004220d41106a21040240200d280204220a450d000240200d410c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b200d41086a280200450d00200d280204102a0b20042005470d000b0b200141286a280200450d042001280224102a0c040b2009450d030240200141086a280200450d00200141046a280200102a0b0240200141146a280200220a450d00200141186a280200450d00200a102a0b200141246a280200450d03200141206a280200102a0c030b20011082040c020b410121100b2000411f3a0000024020012d0000220a410f4b0d0002400240024002400240024002400240024002400240024002400240200a0e100001020304050607080e090e0a0b0c0d000b200b450d0e200141086a280200450d0e200141046a280200102a0c0e0b200d450d0d0240200141086a280200450d00200141046a280200102a0b200141146a280200450d0d200141106a280200102a0c0d0b200c450d0c02402001410c6a280200220b450d00200141046a280200210a200b410474210b03400240200a41046a280200450d00200a280200102a0b200a41106a210a200b41706a220b0d000b0b200141086a280200450d0c2001280204102a0c0c0b2004450d0b02402001410c6a280200220b450d00200141046a280200210a200b41286c210b03400240200a41046a280200450d00200a280200102a0b0240200a41106a280200450d00200a410c6a280200102a0b200a41286a210a200b41586a220b0d000b0b200141086a280200450d0b2001280204102a0c0b0b2006450d0a200141086a280200450d0a200141046a280200102a0c0a0b2005450d09200141086a280200450d09200141046a280200102a0c090b2007450d08200141086a280200450d08200141046a280200102a0c080b2002450d0702402001410c6a280200220a450d00200141046a2802002204200a4104746a2105034002402004280208220b450d002004280200210a200b410474210b03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441106a210a0240200441046a280200450d002004280200102a0b200a2104200a2005470d000b0b200141086a280200450d072001280204102a0c070b2012450d0602402001410c6a280200220b450d00200141046a280200210a200b41146c210b03400240200a41046a280200450d00200a280200102a0b200a41146a210a200b416c6a220b0d000b0b200141086a280200450d062001280204102a0c060b2008450d0502402001410c6a280200220a450d00200141046a2802002204200a411c6c6a2105034002402004280204220a450d0002402004410c6a280200220b450d00200b410474210b03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441086a280200450d002004280204102a0b2004411c6a210a0240200441146a280200450d002004280210102a0b200a2104200a2005470d000b0b200141086a280200450d052001280204102a0c050b2009450d0402402001410c6a280200220a450d00200141046a2802002204200a41186c6a210503400240200441046a280200450d002004280200102a0b0240200441146a280200220b450d00200428020c210a200b410474210b03400240200a2d00004109470d000240200a41046a220d280200220c28020441ffffffff0371450d00200c280200102a200d280200210c0b200c102a0b200a41106a210a200b41706a220b0d000b0b200441186a210a0240200441106a280200450d00200428020c102a0b200a2104200a2005470d000b0b200141086a280200450d042001280204102a0c040b2013450d03200141046a220a10f904200141086a280200450d03200a280200102a0c030b2011450d020240200141046a280200220a450d00200141086a280200450d00200a102a0b0240200141146a280200220a450d0002402001411c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b200141186a280200450d002001280214102a0b200141246a2802002204450d0202402001412c6a280200220a450d002004200a4104746a210503402004220d41106a21040240200d280204220a450d000240200d410c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c102a0b200a410c6a210a200b41746a220b0d000b0b200d41086a280200450d00200d280204102a0b20042005470d000b0b200141286a280200450d022001280224102a0c020b2010450d010240200141086a280200450d00200141046a280200102a0b0240200141146a280200220a450d00200141186a280200450d00200a102a0b200141246a280200450d01200141206a280200102a0c010b20011082040b200341e0006a24000bb309010a7f230041b0016b2202240041002103024020012802102204450d0020012802082205200128020c460d00200128021421062001200541246a360208200241c4006a41026a2207200541036a2d00003a0000200241286a41086a2208200541106a290000370300200241286a41106a2209200541186a290000370300200241286a41186a220a200541206a280000360200200220052f00013b01442002200541086a29000037032820052d0000220b4102460d00200541046a280000210520012004417f6a360210200241086a41026a20072d00003a000020024190016a41086a200829030037030020024190016a41106a200929030037030020024190016a41186a200a280200360200200220022f01443b01082002200229032837039001024002400240200b4101460d002002418c016a41026a200241086a41026a2d00003a0000200241f0006a41086a20024190016a41086a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41186a20024190016a41186a2d00003a0000200220022f01083b018c0120022002290390013703700c010b200241c8006a200541067610fe01200228024821040240024020022802502005413f7122014b0d00410021010c010b2002418c016a41026a200420014105746a220141026a2d00003a0000200241f8006a2001410f6a29000037030020024180016a200141176a29000037030020024188016a2001411f6a2d00003a0000200220012f00003b018c012002200129000737037020012800032105410121010b0240200228024c450d002004102a0b20010d00410121010c010b200241ec006a41026a2002418c016a41026a2d00003a000020024190016a41086a200241f0006a41086a29030037030020024190016a41106a200241f0006a41106a29030037030020024190016a41186a200241f0006a41186a2d00003a0000200220022f018c013b016c2002200229037037039001410021010b200241e8006a41026a2204200241ec006a41026a2d00003a0000200241c8006a41086a220720024190016a41086a290300370300200241c8006a41106a220820024190016a41106a290300370300200241c8006a41186a220920024190016a41186a2d00003a0000200220022f016c3b016820022002290390013703480240024020010d002002418c016a41026a20042d00003a0000200241f0006a41086a2007290300370300200241f0006a41106a2008290300370300200241f0006a41186a20092d00003a0000200220022f01683b018c0120022002290348370370410121010c010b200641013a0000410021010b200241246a41026a22042002418c016a41026a2d00003a0000200241086a41086a2207200241f0006a41086a290300370300200241086a41106a2208200241f0006a41106a290300370300200241086a41186a2209200241f0006a41186a2d00003a0000200220022f018c013b0124200220022903703703082001450d00200020022f01243b0001200041046a2005360000200041086a2002290308370000200041036a20042d00003a0000200041106a2007290300370000200041186a2008290300370000200041206a20092d00003a0000410121030b200020033a0000200241b0016a24000bd50505067f017e047f017e027f23004180026b22022400024002400240024002402000280200220320002802044f0d00200028020c2104200141086a2105200241a0016a4102722106024003402000200341016a360200200241186a20002802082802002207109b0220022d00184101460d0120022900192108200241086a2007106c20022802080d012007280204200228020c2203490d012003417f4c0d0302400240024020030d00410121090c010b2003102e2209450d0820072802042003490d01200920072802002003109a051a2007280204220a2003490d062007200a20036b3602042007200728020020036a3602000b20022008370310024002402001280200220b41f8b9c000460d002001280204210c0c010b2006410041da001099051a200241186a41004184011099051a41e4011028220b450d074100210c200b4100360200200b41046a200241a0016a41dc00109a051a200b41e0006a200241186a418401109a051a200141003602042001200b3602000b2003ad220d422086200d84210d024002400340200b41086a2107200b2f0106220e41037421034100210a024003402003450d01200241106a20074108109c05220f450d03200341786a2103200a41016a210a200741086a2107200f417f4a0d000b200a417f6a210e0b0240200c450d00200c417f6a210c200b200e4102746a41e4016a280200210b0c010b0b2002200837022c200220053602282002200e360224200220013602202002200b36021c200241003602182002200d3702a401200220093602a001200241186a200241a0016a10bb020c010b200b200a410c6c6a220341e4006a2207280200210a2007200d370200200341e0006a22072802002103200720093602002003450d00200a450d002003102a0b200028020022032000280204490d010c030b0b2009102a0b200441013a00000b20024180026a24000f0b1036000b2003200a1044000b41e40141041037000b200341011037000bfd0e03047f027e087f230041206b2202240002400240024002400240024002400240024002400240024002400240024041a20210282203450d00200241a20236020420022003360200200341003b0000200241023602080240024020012903684202520d00024020022802044102470d00200228020041024104102c2203450d0420024104360204200220033602000b200228020041033a00022002200228020841016a3602080c010b024020022802044102470d00200228020041024104102c2203450d0420024104360204200220033602000b20022802004183013a00022002200228020841016a3602082001200210a60120022002360210200141246a200241106a10fa020240024020012903684201510d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d12200341017422052004200520044b1b22054100480d120240024020030d002005102821040c010b200228020020032005102c21040b2004450d072002200536020420022004360200200228020821030b2002200341016a360208200420036a41003a00000c010b200141f8006a29030020012903702206420c882207420120074201561b8021070240024020022802042204200228020822036b4102490d00200228020021040c010b200341026a22052003490d11200441017422032005200320054b1b22034100480d110240024020040d002003102821040c010b200228020020042003102c21040b2004450d072002200336020420022004360200200228020821030b2002200341026a360208200420036a2007a741047420067aa7417f6a22034101200341014b1b2203410f2003410f491b723b00000b20014190016a200210a001200220014180016a360210200241106a200210a3010b20014198016a200210eb012002280208210120024100360218200242013703102001417e6a200241106a10b4012002280208220341014d0d052002280218210520022802142108200228021021092002410036020820022802002101024002402003417e6a220a450d004102210b2005450d0d200120092d00003a00004101210c2002200228020841016a36020820054101460d0d200920056a210d200120092d00013a00012002200228020841016a3602084102210b200941026a21042005417e6a220e0d014100210e0c0b0b0240024002402002280204220320054f0d00200341017422042005200420054b1b22044100480d120240024020030d002004102821010c010b200120032004102c21010b2001450d0a20022004360204200220013602002002280208210b0c010b4100210b2005450d010b2001200b6a220320092d00003a0000024020054101470d00200b41016a210b0c010b2005417f6a2104200941016a2101200341016a21030340200320012d00003a0000200341016a2103200141016a21012004417f6a22040d000b200b20056a210b0b2002200b3602084102210b0c0b0b024002402002280204220120036b200e490d00200228020021010c010b2003200e6a220b2003490d0f20014101742203200b2003200b4b1b22034100480d0f0240024020010d002003102821010c010b200228020020012003102c21010b2001450d0820022003360204200220013602000b200120056a200141026a200a109b051a0240200520022802082201460d00200520016b210b2005417e6a2103200228020020016a210c410021010340024020032001470d002005210b0c0d0b200c20016a20042d00003a00002002200228020841016a360208200441016a2104200b200141016a2201470d000b200d20046b220e0d004100210e4101210c0c090b200e4100480d0e200e1028220c0d08200e41011037000b41a20241011037000b410441011037000b410441011037000b200541011037000b200341011037000b41e4e8c5001032000b200441011037000b200341011037000b2005210b0b0240200d2004460d00200c20042d00003a00004101210f02400240200441016a2201200d470d00200c41016a21050c010b200c41016a21032009200520046b6a21040340200320012d00003a0000200341016a2103200d200141016a2201470d000b2004450d01200c20046a21052004210f0b0240024020022802042201200a200b6a22036b200f490d00200228020021010c010b2003200f6a22042003490d06200141017422032004200320044b1b22034100480d060240024020010d002003102821010c010b200228020020012003102c21010b2001450d0520022003360204200220013602000b2001200b200f6a220d6a2001200b6a200a109b051a0240200d20022802082201460d00200228020020016a2103200b200f6a20016b2104200c2101034020052001460d01200320012d00003a00002002200228020841016a360208200141016a2101200341016a21032004417f6a22040d000b0b200d210b0b200e450d00200c102a0b200a450d010b0240200b20022802082201460d002002280200220320016a2003200b6a200a109b051a0b2002200a20016a3602080b02402008450d002009102a0b20002002290300370200200041086a200241086a280200360200200241206a24000f0b200341011037000b1031000b130020004103360204200041889fc4003602000b340020004196a6c40036020420004100360200200041146a4101360200200041106a419ca6c400360200200041086a42043702000b4001017f230041206b22022400200241186a4200370300200241106a4200370300200241086a42003703002002420037030020002002108b04200241206a24000bde0301017f024002400240024002400240410110282202450d00200220012d00003a0000200241014102102c2202450d01200220012d00013a0001200241024104102c2202450d02200220012d00023a0002200220012d00033a0003200241044108102c2202450d03200220012d00043a0004200220012d00053a0005200220012d00063a0006200220012d00073a0007200241084110102c2202450d04200220012d00083a0008200220012d00093a0009200220012d000a3a000a200220012d000b3a000b200220012d000c3a000c200220012d000d3a000d200220012d000e3a000e200220012d000f3a000f200241104120102c2202450d05200220012d00103a0010200220012d00113a0011200220012d00123a0012200220012d00133a0013200220012d00143a0014200220012d00153a0015200220012d00163a0016200220012d00173a0017200220012d00183a0018200220012d00193a0019200220012d001a3a001a200220012d001b3a001b200220012d001c3a001c200220012d001d3a001d200220012d001e3a001e200220012d001f3a001f200042a08080808004370204200020023602000f0b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000bb31102077f027e230041106b2202240020024100360208200242013703004104200210b4010240024002400240024002400240024002400240024002400240024002400240024020022802042203200228020822046b4104490d00200441046a2105200228020021030c010b200441046a22052004490d0f200341017422062005200620054b1b22064100480d0f0240024020030d002006102821030c010b200228020020032006102c21030b2003450d0120022006360204200220033602000b20022005360208200320046a41eede91ab06360000410e200210b4010240024020022802042203200228020822066b410e490d002006410e6a2104200228020021050c010b2006410e6a22042006490d0f200341017422052004200520044b1b22074100480d0f0240024020030d002007102821050c010b200228020020032007102c21050b2005450d022002200736020420022005360200200721030b20022004360208200520066a220641002900e4c740370000200641066a41002900eac7403700000240200320046b41034b0d00200441046a22062004490d0f200341017422072006200720064b1b22064100480d0f0240024020030d002006102821050c010b200520032006102c21050b2005450d0320022006360204200220053602000b2002200441046a360208200520046a410a3600000240024020022802042205200228020822046b4104490d00200228020021050c010b200441046a22032004490d0f200541017422062003200620034b1b22034100480d0f0240024020050d002003102821050c010b200228020020052003102c21050b2005450d0420022003360204200220053602000b2002200441046a360208200520046a41a3013600000240024020022802042205200228020822046b4104490d00200228020021050c010b200441046a22032004490d0f200541017422062003200620034b1b22034100480d0f0240024020050d002003102821050c010b200228020020052003102c21050b2005450d0520022003360204200220053602000b2002200441046a360208200520046a41a301360000410b200210b40141f4c7c0002104034002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0720022006360204200220033602000b2002200541016a360208200320056a20042d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0820022006360204200220033602000b2002200541016a360208200320056a200441016a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0920022006360204200220033602000b2002200541016a360208200320056a200441026a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0a20022006360204200220033602000b2002200541016a360208200320056a200441036a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0b20022006360204200220033602000b2002200541016a360208200320056a200441046a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0c20022006360204200220033602000b2002200541016a360208200320056a200441056a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0d20022006360204200220033602000b2002200541016a360208200320056a200441066a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d10200541017422062003200620034b1b22064100480d100240024020050d002006102821030c010b200228020020052006102c21030b2003450d0e20022006360204200220033602000b2002200541016a360208200320056a200441076a2d00003a0000200441086a28020021060240024020022802042203200228020822056b4104490d00200228020021030c010b200541046a22072005490d10200341017422082007200820074b1b22074100480d100240024020030d002007102821030c010b200228020020032007102c21030b2003450d0f20022007360204200220033602000b2002200541046a360208200320056a20063600002004410c6a220441f8c8c000470d000b200235020821092002350200210a200241106a2400200a2009422086840f0b200641011037000b200741011037000b200641011037000b200341011037000b200341011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200741011037000b1031000b961b04057f017e037f017e230041800a6b22022400024002402001450d00200220003602180c010b200241013602180b2002200136021c200241e0076a200241186a107f024020022802e4072203450d00200241e0076a410c6a280200210120022802e807210420022802e0072100200241b0046a200241e0076a41106a41e000109a051a200241e0076a200241186a1079024020022802e007450d0020024180036a41086a2205200241e0076a41086a280200360200200220022903e00737038003200241e0076a200241b0046a41e000109a051a200241306a200241e0076a41e000109a051a200241206a41086a22062005280200360200200220022903800337032020024190016a410c6a200136020020024190016a41086a20043602002002200336029401200220003602900120024190016a41106a200241306a41e000109a05210120024188026a2006280200360200200220022903203703800220024190016a10c703024002402002280290012200450d00200241e0076a2000417f6a10f701200241e0076a20014120109c050d000240024020024188026a28020022030d004100210341042104410021010c010b024002402003ad420c7e2207422088a70d002007a722014100480d0020022802800221002001102822040d01200141041037000b1031000b200341a0026c210520034105742106200421010340200241e0076a2000108704200141086a200241e0076a41086a280200360200200120022903e0073702002001410c6a2101200041a0026a2100200541e07d6a22050d000b200641606a41057641016a21010b200220013602b804200220033602b404200220043602b004200241e0076a200241b0046a108e040240200241e0016a2201200241e0076a4120109c05450d004190fac500410e100b200141201019200241e0076a412010190b02402001200241e0076a4120109c050d0020024184026a28020021082002280280022109200228028802210520024190026a20024190016a41f000109a051a2009200541a0026c6a2100200228029002210a20092101024002402005450d00200241b0046a41f0006a21042009210102400340200241f8066a200141e800109a051a200141e8006a290300210720024180036a200141f0006a41b001109a051a20074203510d01200241b0046a200241f8066a41e800109a051a2002200737039805200420024180036a41b001109a051a200241e0076a200241b0046a10870420022802e8072105024020022802e407450d0020022802e007102a0b200241e0076a200241b0046a41a002109a051a200241003602e006200241d0066a200241e0076a2005200241e0066a10d00320022d00d0064101460d03024020022d00dc0622054102460d0020023100de06210720023100dd06210b20022802d806210620022802d406210341f19ec600410d100b02402005450d00200b100c0b2007100c2003450d0020032006100b0b200141a0026a22012000470d000b200021010c010b200141a0026a21010b20012000460d03200241f8086a2105200241e0076a41f0006a2103034020024180036a200141e800109a051a200141e8006a2903002107200241e0076a200141f0006a41b001109a051a20074203510d04200241f8066a20024180036a41e800109a051a200241b0046a200241e0076a41b001109a051a200241e0076a200241f8066a41e800109a051a200220073703c8082003200241b0046a41b001109a051a2005106a200141a0026a22012000470d000c040b0b200241106a20022f00d10620022d00d3064110747210d30320022903102107200241ec076a42c4808080d01b370200200241323602f407200241b8b9c3003602e807200220073703e007200241e0076a1032000b41a0b9c3001032000b4188b9c3001032000b02402008450d002009102a0b200241086a10e403200228020c210120022802082100200241e0076a41086a22054200370300200242003703e00741f99fc6004115200241e0076a1008200241b0046a41086a2005290300370300200220022903e0073703b00420022001410020001b3602e007200241b0046a4110200241e0076a41041007200a109e03200241e0076a10b203200220024190026a410c6a28020022033602f00620022802940221062002200241e0076a410c6a28020022013602f406024020032001470d0002402003450d0020022802e407210941002105034002400240024002400240024002400240200620056a22012d00002204200920056a22002d0000470d000240024002400240024020040e050001020304000b20012000460d09200141016a200041016a4120109c050d040c090b024020012000460d00200141016a280000200041016a280000470d040b200141106a2802002204200041106a280200470d03200141086a2802002208200041086a280200220a460d072008200a2004109c050d030c070b024020012000460d00200141016a280000200041016a280000470d030b200141106a2802002204200041106a280200470d02200141086a2802002208200041086a280200220a460d052008200a2004109c050d020c050b024020012000460d00200141016a280000200041016a280000470d020b200141106a2802002204200041106a280200470d01200141086a2802002208200041086a280200220a460d032008200a2004109c050d010c030b2001410c6a28020022042000410c6a280200470d00200141046a2802002208200041046a280200220a460d012008200a2004109c05450d010b41df86c2004114100b200241b0046a200110ec0120022802b004220420022802b8041019024020022802b404450d002004102a0b200241b0046a200010ec0120022802b004220420022802b8041019024020022802b404450d002004102a0b20012d000020002d00002204470d0520040e050403020100040b2001410c6a28020022042000410c6a280200470d04200141046a2802002201200041046a2802002200460d05200120002004109c050d040c050b024020012000460d00200141016a280000200041016a280000470d040b200141106a2802002204200041106a280200470d03200141086a2802002201200041086a2802002200460d04200120002004109c05450d040c030b024020012000460d00200141016a280000200041016a280000470d030b200141106a2802002204200041106a280200470d02200141086a2802002201200041086a2802002200460d03200120002004109c050d020c030b024020012000460d00200141016a280000200041016a280000470d020b200141106a2802002204200041106a280200470d01200141086a2802002201200041086a2802002200460d02200120002004109c050d010c020b20012000460d01200141016a200041016a4120109c05450d010b4194bac3001032000b200541246a21052003417f6a22030d000b0b024020024190026a41306a2201200241e0076a41306a22004120109c05450d004190fac500410e100b2001412010192000412010190b0240200120004120109c05450d0041acbac3001032000b024020022802ec072200450d0020022802e4072101200041246c210003400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b0240200241e8076a280200450d0020022802e407102a0b0240200228029c022200450d002002280294022101200041246c210003400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b024020024198026a280200450d00200228029402102a0b200241800a6a240042010f0b20024180036a41146a410836020020024180036a410c6a4125360200200241f8066a41146a4103360200200242033702fc06200241c8afc6003602f80620024125360284032002200241f0066a3602e0062002200241f4066a3602d006200242043703c004200242013702b404200241fcb9c3003602b004200220024180036a360288072002200241b0046a360290032002200241d0066a360288032002200241e0066a36028003200241f8066a4184bac300103e000b02402001450d00200141246c21002003210103400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b2004450d002003102a0b200241f4076a4102360200200241bc046a4104360200200242023702e407200241bca7c4003602e007200241043602b404200241b4a7c4003602b0042002410036028403200241b8aec600360280032002200241b0046a3602f007200220024180036a3602b804200241e0076a41cca7c400103e000b8d05030b7f017e037f230041206b220224002001280200220320012802082204410c6c6a21052001280204210602400240024020040d00410421074100210841012109410021014100210a200321040c010b41012109410021084100210441042107410021014100210a2003210b0240024003400240200b280200220c0d00200b410c6a21040c040b024002400240200820046b200b41046a290200220d422088a7220e490d002004200e6a210f0c010b2004200e6a220f2004490d0420084101742210200f2010200f4b1b22104100480d040240024020080d002010102821090c010b200920082010102c21090b2009450d01201021080b200920046a200c200e109a051a02400240200a2001460d0020012110200a21010c010b200141016a22042001490d04200141017422102004201020044b1b221041ffffffff03712010470d04201041027422044100480d040240024020010d002004102821070c010b200720014102742004102c21070b2007450d030b200720014102746a200e3602000240200da7450d00200c102a0b200a41016a210a200f210420102101200b410c6a220b2005470d010c050b0b201041011037000b200441041037000b1031000b024020042005460d0003402004280200220b450d010240200441046a280200450d00200b102a0b2004410c6a22042005470d000b0b200121100b02402006450d002003102a0b200241186a22014200370300200241106a22044200370300200241086a220b42003703002002420037030020092007200a20021023200041186a2001290300370000200041106a2004290300370000200041086a200b2903003700002000200229030037000002402010450d002007102a0b02402008450d002009102a0b200241206a24000ba10301027f23004180026b22022400024002402001450d00200220003602000c010b200241013602000b20022001360204200241f8006a2002107f0240200228027c450d00200241086a200241f8006a41f000109a051a200241086a10c7030240200241086a410c6a2802002200450d00200228020c2101200041246c210003400240024020012d0000220341034b0d0002400240024020030e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b0240200241106a280200450d00200228020c102a0b20024180026a240042010f0b200241f4016a41043602002002411c6a41023602002002420237020c200241bca7c400360208200241043602ec01200241c8a8c4003602e801200241003602fc01200241b8aec6003602f8012002200241e8016a3602182002200241f8016a3602f001200241086a41cca7c400103e000be328010b7f230041d0006b220224002002410036022820024201370320024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240410410282203450d0020024284808080c00037022420022003360220200341edcad18b0636000002400240200228022420022802282203460d00200228022021040c010b200341016a22042003490d1b200341017422052004200520044b1b22054100480d1b0240024020030d002005102821040c010b200228022020032005102c21040b2004450d0220022005360224200220043602200b2002200341016a360228200420036a41073a00004115200241206a10b40141accbc000210603402006280204210720062802082203200241206a10b4010240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1c200541017422042008200420084b1b22044100480d1c0240024020050d002004102821050c010b200228022020052004102c21050b2005450d042002200436022420022005360220200228022821040b2002200420036a360228200520046a20072003109a051a200228022421042002280228210302400240200628020c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e200341017422052004200520044b1b22054100480d1e0240024020030d002005102821040c010b200228022020032005102c21040b2004450d072002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d200341017422052004200520044b1b22054100480d1d0240024020030d002005102821040c010b200228022020032005102c21040b2004450d072002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628020c4101460d00200241306a20062802101103002002280234210720022802382203200241206a10b4010240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1e200541017422042008200420084b1b22044100480d1e0240024020050d002004102821050c010b200228022020052004102c21050b2005450d092002200436022420022005360220200228022821040b2002200420036a360228200520046a20072003109a051a200228024021050240200228023c4101460d0020052002280244200241206a1091040c020b200520022802482203200241206a10910402402003450d00200341d8006c21074100210403400240200520046a220341346a280200450d002003413c6a280200450d00200341386a280200102a0b0240200341c4006a280200450d00200341cc006a280200450d00200341c8006a280200102a0b2007200441d8006a2204470d000b0b2002280244450d012005102a0c010b2006280214210720062802182203200241206a10b4010240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1d200541017422042008200420084b1b22044100480d1d0240024020050d002004102821050c010b200228022020052004102c21050b2005450d092002200436022420022005360220200228022821040b2002200420036a360228200520046a20072003109a051a200628022021030240200628021c4101460d002003200641246a280200200241206a1091040c010b20032006280228200241206a1091040b200228022421042002280228210302400240200628022c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e200341017422052004200520044b1b22054100480d1e0240024020030d002005102821040c010b200228022020032005102c21040b2004450d0b2002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d200341017422052004200520044b1b22054100480d1d0240024020030d002005102821040c010b200228022020032005102c21040b2004450d0b2002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628022c4101460d00200241186a200628023011030020022802182104200228021c2203200241206a10b4012003450d012003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10b4010240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1f20074101742205200a2005200a4b1b22054100480d1f0240024020070d002005102821070c010b200228022020072005102c21070b2007450d0e2002200536022420022007360220200228022821050b2002200520046a360228200720056a20092004109a051a200341706a200241206a1092042003200241206a1093042003412c6a2103200841546a22080d000c020b0b2006280230210420062802382203200241206a10b4012003450d002003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10b4010240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1e20074101742205200a2005200a4b1b22054100480d1e0240024020070d002005102821070c010b200228022020072005102c21070b2007450d0e2002200536022420022007360220200228022821050b2002200520046a360228200720056a20092004109a051a200341706a200241206a1092042003200241206a1093042003412c6a2103200841546a22080d000b0b200228022421042002280228210302400240200628023c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e200341017422052004200520044b1b22054100480d1e0240024020030d002005102821040c010b200228022020032005102c21040b2004450d0f2002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d200341017422052004200520044b1b22054100480d1d0240024020030d002005102821040c010b200228022020032005102c21040b2004450d0f2002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628023c4101460d00200241106a20062802401103002002280210210420022802142203200241206a10b4012003450d012003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10b4010240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1f20074101742205200a2005200a4b1b22054100480d1f0240024020070d002005102821070c010b200228022020072005102c21070b2007450d122002200536022420022007360220200228022821050b2002200520046a360228200720056a20092004109a051a200341706a200241206a1093042003200241206a1093042003412c6a2103200841546a22080d000c020b0b2006280240210420062802482203200241206a10b4012003450d002003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10b4010240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1e20074101742205200a2005200a4b1b22054100480d1e0240024020070d002005102821070c010b200228022020072005102c21070b2007450d122002200536022420022007360220200228022821050b2002200520046a360228200720056a20092004109a051a200341706a200241206a1093042003200241206a1093042003412c6a2103200841546a22080d000b0b02400240200628024c4101460d00200241086a20062802501103002002280208210b200228020c2203200241206a10b4012003450d01200341386c210c410021070340200b20076a220341046a2802002109200341086a2802002204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a2005200a4b1b22054100480d1f0240024020080d002005102821080c010b200228022020082005102c21080b2008450d142002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a200341106a2802002109200341146a2802002204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a2005200a4b1b22054100480d1f0240024020080d002005102821080c010b200228022020082005102c21080b2008450d152002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a02400240200341186a2802004101460d00200241306a2003411c6a280200200341206a28020028020c1102002002280230210920022802382204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2120084101742205200a2005200a4b1b22054100480d210240024020080d002005102821080c010b200228022020082005102c21080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a2002280234450d012009102a0c010b2003411c6a2802002109200341246a2802002204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2020084101742205200a2005200a4b1b22054100480d200240024020080d002005102821080c010b200228022020082005102c21080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a0b200341286a200241206a109304200c200741386a2207470d000c020b0b2006280250210b20062802582203200241206a10b4012003450d00200341386c210c410021070340200b20076a220341046a2802002109200341086a2802002204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1e20084101742205200a2005200a4b1b22054100480d1e0240024020080d002005102821080c010b200228022020082005102c21080b2008450d172002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a200341106a2802002109200341146a2802002204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1e20084101742205200a2005200a4b1b22054100480d1e0240024020080d002005102821080c010b200228022020082005102c21080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a02400240200341186a2802004101460d00200241306a2003411c6a280200200341206a28020028020c1102002002280230210920022802382204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2020084101742205200a2005200a4b1b22054100480d200240024020080d002005102821080c010b200228022020082005102c21080b2008450d1b2002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a2002280234450d012009102a0c010b2003411c6a2802002109200341246a2802002204200241206a10b4010240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a2005200a4b1b22054100480d1f0240024020080d002005102821080c010b200228022020082005102c21080b2008450d1b2002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109a051a0b200341286a200241206a109304200c200741386a2207470d000b0b200641dc006a220641b8dac000470d000b2002280228220341046a2204417f4c0d1720022802242108200228022021070240024020040d00410121050c010b200410282205450d190b2002410036023820022004360234200220053602302003200241306a10b4010240024020022802342205200228023822046b2003490d00200228023021050c010b200420036a22092004490d1b2005410174220a2009200a20094b1b22094100480d1b0240024020050d002009102821050c010b200228023020052009102c21050b2005450d1a20022009360234200220053602300b200520046a20072003109a051a200420036a210302402008450d002007102a0b200241d0006a24002003ad4220862005ad840f0b410441011037000b200541011037000b200441011037000b200541011037000b200541011037000b200441011037000b200441011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b200541011037000b1036000b200441011037000b200941011037000b1031000b9c1d010a7f230041106b220324002001200210b401024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001450d00200141d8006c2104410021050340200020056a220641046a2802002107200641086a2802002208200210b40102400240200241046a2209280200220a200241086a2201280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d18200a410174220b200c200b200c4b1b220b4100480d1802400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d032002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a200641d4006a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1820084101742207200b2007200b4b1b22074100480d180240024020080d0020071028210b0c010b200228020020082007102c210b0b200b450d042002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a000002402006410c6a2d0000220841024b0d0002400240024020080e03000102000b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1b2008410174220a200b200a200b4b1b220a4100480d1b0240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d082002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41003a0000200641146a2802002107200641186a2802002208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1b200a410174220b200c200b200c4b1b220b4100480d1b02400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d092002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a0c020b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200a200b4b1b220a4100480d1a0240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d092002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41013a00002006410d6a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a20084101742207200b2007200b4b1b22074100480d1a0240024020080d0020071028210b0c010b200228020020082007102c210b0b200b450d0a2002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a0000200641146a2802002107200641186a2802002208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200b200c4b1b220b4100480d1a02400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d0b2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a200641206a2802002107200641246a2802002208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200b200c4b1b220b4100480d1a02400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d0c2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200a200b4b1b220a4100480d1a0240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d0d2002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a2006410e6a2d00003a00000c010b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d192008410174220a200b200a200b4b1b220a4100480d190240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d0d2002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41023a00002006410d6a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1920084101742207200b2007200b4b1b22074100480d190240024020080d0020071028210b0c010b200228020020082007102c210b0b200b450d0e2002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a0000200641146a2802002107200641186a2802002208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200b200c4b1b220b4100480d1902400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d0f2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a200641206a2802002107200641246a2802002208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200b200c4b1b220b4100480d1902400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d102002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a2006412c6a2802002107200641306a2802002208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200b200c4b1b220b4100480d1902400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d112002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a2006410e6a2d0000220841044b0d000240024002400240024020080e050001020304000b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1d2008410174220a200b200a200b4b1b220a4100480d1d0240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41003a00000c040b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1c2008410174220a200b200a200b4b1b220a4100480d1c0240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41013a00000c030b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1b2008410174220a200b200a200b4b1b220a4100480d1b0240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41023a00000c020b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200a200b4b1b220a4100480d1a0240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41033a00000c010b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d192008410174220a200b200a200b4b1b220a4100480d190240024020080d00200a1028210b0c010b20022802002008200a102c210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41043a00000b02400240200641346a2802004101460d002003200641386a2802002006413c6a28020028020c1102002003280200210720032802082208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200b200c4b1b220b4100480d1a02400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d182002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a2003280204450d012007102a0c010b200641386a2802002107200641c0006a2802002208200210b401024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200b200c4b1b220b4100480d1902400240200a0d00200b1028210a0c010b2002280200200a200b102c210a0b200a450d182002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109a051a0b200641c4006a20021093042004200541d8006a2205470d000b0b200341106a24000f0b200b41011037000b200741011037000b200a41011037000b200b41011037000b200a41011037000b200741011037000b200b41011037000b200b41011037000b200a41011037000b200a41011037000b200741011037000b200b41011037000b200b41011037000b200b41011037000b200a41011037000b200a41011037000b200a41011037000b200a41011037000b200a41011037000b200b41011037000b200b41011037000b1031000b840701087f20002802042102024002400240024002400240024020002802004101460d00200041086a2802002200200110b4012000450d01200041186c2103200241146a2100200141086a2102200141046a21040340200041706a2802002105200041746a2802002206200110b4010240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d08200741017422082009200820094b1b22084100480d080240024020070d002008102821070c010b200128020020072008102c21070b2007450d042001200736020020042008360200200228020021080b2002200820066a360200200720086a20052006109a051a2000417c6a280200210520002802002206200110b4010240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d08200741017422082009200820094b1b22084100480d080240024020070d002008102821070c010b200128020020072008102c21070b2007450d052001200736020020042008360200200228020021080b2002200820066a360200200720086a20052006109a051a200041186a2100200341686a22030d000c020b0b2000410c6a2802002200200110b4012000450d00200041186c2103200241146a2100200141086a2102200141046a21040340200041706a2802002105200041746a2802002206200110b4010240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d07200741017422082009200820094b1b22084100480d070240024020070d002008102821070c010b200128020020072008102c21070b2007450d052001200736020020042008360200200228020021080b2002200820066a360200200720086a20052006109a051a2000417c6a280200210520002802002206200110b4010240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d07200741017422082009200820094b1b22084100480d070240024020070d002008102821070c010b200128020020072008102c21070b2007450d062001200736020020042008360200200228020021080b2002200820066a360200200720086a20052006109a051a200041186a2100200341686a22030d000b0b0f0b200841011037000b200841011037000b200841011037000b200841011037000b1031000b840401087f200028020421020240024002400240024020002802004101460d00200041086a2802002200200110b40120004103742200450d01200220006a2103200141086a2104034020022802002105200241046a2802002200200110b40102400240200141046a22062802002207200428020022086b2000490d00200128020021070c010b200820006a22092008490d06200741017422082009200820094b1b22084100480d060240024020070d002008102821070c010b200128020020072008102c21070b2007450d042001200736020020062008360200200428020021080b2004200820006a360200200720086a20052000109a051a200241086a22022003470d000c020b0b2000410c6a2802002200200110b40120004103742200450d00200220006a2103200141086a2104034020022802002105200241046a2802002200200110b40102400240200141046a22062802002207200428020022086b2000490d00200128020021070c010b200820006a22092008490d05200741017422082009200820094b1b22084100480d050240024020070d002008102821070c010b200128020020072008102c21070b2007450d042001200736020020062008360200200428020021080b2004200820006a360200200720086a20052000109a051a200241086a22022003470d000b0b0f0b200841011037000b200841011037000b1031000bd10f02037f027e230041a0076b22022400024002402001450d00200220003602080c010b200241013602080b2002200136020c200241f0046a200241086a107a02400240024002400240024002400240024002400240024020022903d8054203510d00200241106a200241f0046a41a002109a051a200241c0026a200241106a41a002109a051a200241e0046a200241c0026a10870420022802e8042101200241f0046a200241c0026a41a002109a051a20024198076a20022802e804360200200220022903e00437039007200241b0026a200241f0046a200120024190076a10d0034101410220022d00b00241014622001b220310282201450d01200241003602f804200220033602f404200220013602f0040240024020000d00200241013602f804200141003a000020022802f404210020022802f80421010240200241bc026a2d000022034102470d000240024020002001460d0020022802f00421000c010b200141016a22002001490d0f200141017422032000200320004b1b22034100480d0f0240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d06200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a41003a00000c020b0240024020002001460d0020022802f00421000c010b200141016a22002001490d0e200141017422042000200420004b1b22044100480d0e0240024020010d002004102821000c010b20022802f00420012004102c21000b2000450d06200220043602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a41013a00000240024020034101460d000240024020022802f40420022802f8042201460d0020022802f00421000c010b200141016a22002001490d10200141017422032000200320004b1b22034100480d100240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d09200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a41003a00000c010b0240024020022802f40420022802f8042201460d0020022802f00421000c010b200141016a22002001490d0f200141017422032000200320004b1b22034100480d0f0240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d09200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a41013a00000240024020022802f40420022802f8042201460d0020022802f00421000c010b200141016a22002001490d0f200141017422032000200320004b1b22034100480d0f0240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d0a200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a20022d00bd023a00000b0240024020022802f40420022802f8042201460d0020022802f00421000c010b200141016a22002001490d0e200141017422032000200320004b1b22034100480d0e0240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d0a200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a20022d00be023a00000c010b200241013602f804200141013a000020022d00b102417e6a22014102200141ff01714102491b41ff0171220141024b0d0002400240024020010e03000102000b0240024020022802f40420022802f8042201460d0020022802f00421000c010b200141016a22002001490d0f200141017422032000200320004b1b22034100480d0f0240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d0c200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a41003a00000c020b0240024020022802f40420022802f8042201460d0020022802f00421000c010b200141016a22002001490d0e200141017422032000200320004b1b22034100480d0e0240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d0c200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a41013a00000c010b0240024020022802f40420022802f8042201460d0020022802f00421000c010b200141016a22002001490d0d200141017422032000200320004b1b22034100480d0d0240024020010d002003102821000c010b20022802f00420012003102c21000b2000450d0c200220033602f404200220003602f00420022802f80421010b2002200141016a3602f804200020016a41023a0000200241b0026a410172200241f0046a10c6030b20023502f804210520023502f0042106200241a0076a240020062005422086840f0b2002411c6a4104360200200241d4026a4102360200200242023702c402200241bca7c4003602c00220024104360214200241e0a8c400360210200241003602b402200241b8aec6003602b0022002200241106a3602d0022002200241b0026a360218200241c0026a41cca7c400103e000b200341011037000b200341011037000b200441011037000b200341011037000b200341011037000b200341011037000b200341011037000b200341011037000b200341011037000b200341011037000b1031000baf0d04067f017e057f017e230041c0016b22022400200241086a10e403200228020c21032002280208210420024180016a41086a22054200370300200242003703800141f99fc600411520024180016a1008200241106a41086a2005290300370300200220022903800137031020022003410020041b3602a001200241106a4110200241a0016a41041007109801109e0320054200370300200242003703800141f99fc600411520024180016a100820024190016a41086a20052903003703002002200229038001370390012002410036021020024190016a4110200241106a1006210502400240024002400240024020022802102203417f460d002005450d00200341034d0d05200528000021062005102a20060d010b41042107410021060c010b2006ad420c7e2208422088a70d012008a722054100480d01200510282207450d022007210341002104034002400240024002400240411410282205450d00200541106a41002800eaa046360000200541086a41002900e2a046370000200541002900daa046370000200541144128102c2205450d0120052004360014200241106a41186a22094200370300200241106a41106a220a4200370300200241106a41086a220b42003703002002420037031020054118200241106a1000200241a0016a41186a2009290300370300200241a0016a41106a200a290300370300200241a0016a41086a200b290300370300200220022903103703a0012005102a20024100360210200241a0016a4120200241106a1006210a2002280210220b417f460d03200a450d032002200b3602142002200a3602102002200241106a106c02400240024020022802000d002002280214220c20022802042209490d002009417f4c0d050240024020090d00410121050c010b2009102e2205450d0220052002280210220d2009109a051a2002200c20096b3602142002200d20096a3602100b20050d020b41c4d1c300413320024180016a419cd9c3001038000b200941011037000b2009ad2208422086210e0240200b450d00200a102a0b200e2008842108200241a0016a412010090c040b411441011037000b412841011037000b1036000b41012105420021080b20032005360200200341046a20083702002003410c6a21032006200441016a2204470d000b0b200220063602182002200636021420022007360210200241a0016a200241106a108e04200241106a41186a200241a0016a41186a290300370300200241106a41106a2205200241a0016a41106a290300370300200241106a41086a200241a0016a41086a290300370300200220022903a00137031020024180016a41086a22034200370300200242003703800141e6efc200411520024180016a100820024190016a41086a20032903003703002002200229038001370390012002411036028401200220024190016a36028001200241106a20024180016a10f002200241106a10b20320024100360298012002420137039001200220024190016a3602a0012005200241a0016a10c801200241106a20024190016a10a001200220024190016a3602a001200241c0006a200241a0016a10c801200220024190016a3602a001200241e0006a200241a0016a10c801200228021421042002411c6a280200220520024190016a10b401024002402005450d00200541246c210b0340200241a0016a200410ec0120022802a001210a02400240200228029401220920022802980122056b20022802a8012203490d0020022802900121090c010b200520036a22062005490d04200941017422052006200520064b1b22054100480d040240024020090d002005102821090c010b20022802900120092005102c21090b2009450d032002200536029401200220093602900120022802980121050b2002200520036a36029801200920056a200a2003109a051a024020022802a401450d00200a102a0b200441246a2104200b415c6a220b0d000b0b200235029801210820022802900121090240200228021c2203450d0020022802142105200341246c210303400240024020052d0000220441034b0d0002400240024020040e0404000102040b2005410c6a280200450d03200541086a280200102a0c030b2005410c6a280200450d02200541086a280200102a0c020b2005410c6a280200450d01200541086a280200102a0c010b200541086a280200450d00200541046a280200102a0b200541246a21052003415c6a22030d000b0b0240200241186a280200450d002002280214102a0b200241c0016a240020084220862009ad840f0b200541011037000b1031000b200541041037000b41c4d1c300413320024180016a419cd9c3001038000bee2605017f027e0d7f027e067f230041b0036b22022400024002402001450d00200220003602080c010b200241013602080b2002200136020c2002200241086a106c024020022802000d00200228020421012002200241086a36029801200241003a0090032002420037028402200241f8b9c000360280022002200136022420024100360220200220024190036a36022c200220024198016a360228200241206a20024180026a10860420022802800221012002290284022103024020022d009003450d0020012003a72003422088a710b0020c010b2001450d002002200337021420022001360210200241206a200241106a1097040240024002400240024002400240024002400240024020022802204101460d00200241206a41086a2201290300210342002104200142003703002002420037032041feb3c300410d200241206a100820024180026a41086a200129030037030020022002290320370380022002410036022020024180026a4110200241206a100621010240024020022802202200417f460d002001450d0020004108490d01200129000021042001102a0b024041a00210282205450d0020054102360298012005420237036820052003200442dc0b7c220420032004561b3703a001200241106a21012002280214210603402001280200220741086a210020072f010622084103742101410021090240024003402001450d0141bee6c20020004108109c05220a450d02200141786a2101200941016a2109200041086a2100200a417f4a0d000b2009417f6a21080b024020060d004101210b0c080b2006417f6a2106200720084102746a41e4016a21010c010b0b200220072009410c6c6a220141e8006a280200360284022002200141e0006a28020036028002200241206a20024180026a107e02402002280220220c0d004101210b0c060b2002280224210d200241206a41086a22012802002208450d0320014200370300200242003703204193cdc2004111200241206a100820024180026a41086a200129030037030020022002290320370380022002410036022020024180026a4110200241206a1006210102400240024020022802202200417f460d002001450d002002200036029c012002200136029801200241206a20024198016a107b20022802202206450d02200229022421032000450d012001102a0c010b42002103410421060b2003a7210b2006210020062101024002400240024002402003422088a7220e450d002006200e41c4006c6a21004100210902400340200620096a22012d0000210a200241206a200141016a41c300109a051a200a4102460d0120024180026a41186a200241206a41186a29000037030020024180026a41106a200241206a41106a29000037030020024180026a41086a200241206a41086a2900003703002002200229002037038002200a4101460d03200941c4006a2109200141c4006a2000470d000b200021010c010b200141c4006a21010b0240034020002001460d0120012d00002109200141c4006a210120094102470d000b0b410121074100210f0240200b0d00410021100c020b2006102a410021100c010b20024198016a41086a220a20024180026a41086a29030037030020024198016a41106a220f20024180026a41106a29030037030020024198016a41186a221120024180026a41186a290300370300200220022903800222033703f0022002200337039801412010282207450d022007200229039801370000200741186a2011290300370000200741106a200f290300370000200741086a200a2903003700004101210f024002400240200e41c4006c41bc7f6a2009470d00410121100c010b200141c4006a2d00002109200241206a200141c5006a41c300109a051a20014188016a210a024020094102470d0041012110200a21010c020b4101210f410121100340200a21010240034020024180026a41186a220a200241206a41186a29000037030020024180026a41106a220e200241206a41106a29000037030020024180026a41086a2211200241206a41086a2900003703002002200229002037038002200941ff01714101460d0120002001460d0320012d00002109200241206a200141016a41c300109a051a200141c4006a210120094102460d040c000b0b20024198016a41086a2011290300220337030020024198016a41106a200e290300220437030020024198016a41186a200a29030022123703002002200229038002221337039801200241f0026a41186a220a2012370300200241f0026a41106a220e2004370300200241f0026a41086a22112003370300200220133703f00202402010200f470d00200f41016a2209200f490d14200f41017422142009201420094b1b221041ffffff3f712010470d14201041057422094100480d1402400240200f0d002009102821070c010b2007200f4105742009102c21070b2007450d050b2007200f4105746a220920022903f002370000200941186a200a290300370000200941106a200e290300370000200941086a2011290300370000200f41016a210f20002001460d0120012d00002109200241206a200141016a41c300109a051a200141c4006a210a20094102470d000b200141c4006a21010c010b200021010b0240034020002001460d0120012d00002109200141c4006a210120094102470d000b0b200b450d002006102a0b200c200841f0006c6a210820024180026a41106a211520024180026a41086a21144200210341042116200c210a02400340200a2802042101200a2802002100200241206a200a41086a41e800109a051a200a41f0006a210a024020010d00200a2008460d0a0340200a2802042206450d0b200a41086a280200210b0240200a410c6a2802002201450d00200141246c21002006210103400240024020012d0000220941034b0d0002400240024020090e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b200a41f0006a210a0240200b450d002006102a0b200a2008470d000c0b0b0b20024198016a200241206a41e800109a051a20022001360284022002200036028002201420024198016a41e800109a051a109801210120024190036a20024180026a10f6010240024002400240200228028002417f6a220020014f0d00200241206a200010f701200241206a20154120109c050d00200228028002221741002001417b6a2200200020014b1b490d0020024190036a20076b220641606a210e200641406a2111200641a07f6a21182007200f41057422096a210b410021010240024002400340024002400240200b200720016a22006b41e0004b0d00200f4105742001470d01410021000c060b024020062001470d0020024190036a21000c060b200020024190036a4120109c05450d05200e2001470d0120024190036a21000c050b0340024020024190036a2000470d0020024190036a21000c060b200020024190036a4120109c05450d05200041206a2100200941606a22090d000b410021000c040b200041206a221920024190036a4120109c05450d02024020112001470d0020024190036a21000c040b200041c0006a221920024190036a4120109c05450d01024020182001470d0020024190036a21000c040b200941807f6a210920014180016a2101200041e0006a20024190036a4120109c050d000b200720016a41606a21000c020b201921000c010b201921000b200241206a201710f701200241206a20024190036a4120109c05210120000d0020010d010b0240200228028c022200450d002002280284022101200041246c210003400240024020012d0000220941034b0d0002400240024020090e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b200228028802450d01200228028402102a0c010b20024190036a20024180026a10f601200241206a20024180026a41f000109a051a0240024020034220882204a722012003a7460d00200121000c010b200141016a22092001490d142004a722004101742206200920092006491bad220342f0007e2204422088a70d142004a722094100480d140240024020010d002009102821160c010b2016200141f0006c2009102c21160b2016450d020b2016200041f0006c6a200241206a41f000109a051a200241206a41186a220920024190036a41186a290300370300200241206a41106a220620024190036a41106a290300370300200241206a41086a220b20024190036a41086a29030037030020022002290390033703200240200f2010470d00200f41016a2201200f490d14200f410174220e2001200e20014b1b221041ffffff3f712010470d14201041057422014100480d1402400240200f0d002001102821070c010b2007200f4105742001102c21070b2007450d040b200342ffffffff0f83200041016aad4220868421032007200f4105746a22012002290320370000200141186a2009290300370000200141106a2006290300370000200141086a200b290300370000200f41016a210f0b200a2008470d010c0a0b0b200941041037000b200141011037000b200941011037000b412041011037000b41c4d1c300413320024190036a419cd9c3001038000b41a00241081037000b41c4d1c300413320024190036a419cd9c3001038000b2002200229022437038002419db6c300412820024180026a419cb4c3001038000b4101210b200d450d01200c102a0c010b0240200d450d00200c102a0b02402010450d002007102a0b0240200342ffffffff0f560d004101210b2003a7450d012016102a0c010b024020160d004101210b0c010b200541a00241c004102c2205450d01200541a0026a20024180026a41e800109a051a2005420237038803200520033703c003200520163602bc03200541033602b80320052002290398013703900320054198036a200241a0016a290300370300200541a0036a200241a8016a290300370300200541a8036a200241b0016a290300370300200541b0036a200241b8016a290300370300200541c8036a200241206a41f800109a051a4102210b0b200241106a210120022802142106024003402001280200220741086a210020072f010622084103742101410021090240024003402001450d0141a7c5c20020004108109c05220a450d02200141786a2101200941016a2109200041086a2100200a417f4a0d000b2009417f6a21080b2006450d022006417f6a2106200720084102746a41e4016a21010c010b0b200741e0006a2009410c6c6a22012802084104490d002001280200280000210742002103200241206a41086a2201420037030020024200370320419194c1004115200241206a100820024180026a41086a200129030037030020022002290320370380022002410036022020024180026a4110200241206a100621000240024020022802202201417f460d002002200136029c012002200036029801200241206a20024198016a10820120022802202209450d04200229022421032001450d012000102a0c010b410421090b4100210002402003422088a72201417f6a220a20014b0d00200a20014f0d002009200a4102746a2201450d00200128020020074721000b02402003a7450d002009102a0b20000d030b200b210f0c030b41c00441081037000b41c4d1c300413320024190036a419cd9c3001038000b2005200b41a0026c2201200b4101742200200b41016a220f2000200f4b1b41a0026c2200102c2205450d01200520016a20024180026a41e800109a05220142023703682001200229039801370370200141f8006a200241a0016a29030037030020014180016a200241a8016a29030037030020014188016a200241b0016a29030037030020014190016a200241b8016a2903003703002001419c016a20073602002001410d36029801200141a8016a200241206a41f800109a051a0b20022802102002280214200228021810b00220024100360288022002420137038002200f20024180026a10b401200f41a0026c210b20022802840221062002280288022101200521090340200241206a20091087042002280220210802400240200620016b20022802282207490d00200120076a2100200228028002210a0c010b200120076a22002001490d042006410174220a2000200a20004b1b220e4100480d040240024020060d00200e1028210a0c010b2002280280022006200e102c210a0b200a450d032002200e360284022002200a36028002200e21060b2002200036028802200a20016a20082007109a051a02402002280224450d002008102a0b200941a0026a210920002101200b41e07d6a220b0d000b200f41a0026c210920054198016a210103402001106a200141a0026a2101200941e07d6a22090d000b2005102a200241b0036a24002000ad422086200aad840f0b200041081037000b200e41011037000b1031000b2002418c026a4104360200200241346a410236020020024202370224200241bca7c4003602202002410436028402200241f8a8c400360280022002410036029c01200241b8aec60036029801200220024180026a360230200220024198016a36028802200241206a41cca7c400103e000bf00101067f2001280204210202400240024003402001280200220341086a210420032f01062205410374210141002106024003402001450d0141ffa0c60020044108109c052207450d03200141786a2101200641016a2106200441086a21042007417f4a0d000b2006417f6a21050b02402002450d002002417f6a2102200320054102746a41e4016a21010c010b0b20004187a1c600360204200041086a41283602000c010b200341e0006a2006410c6c6a220128020841074b0d01200041afa1c600360204200041086a41293602000b200041013602000f0b200041086a2001280200290000370300200041003602000be92c06087f017e097f027e017f027e230041b0026b22022400024002402001450d00200220003602100c010b200241013602100b20022001360214200241c8006a200241106a107f02400240200228024c2203450d00200241d4006a280200210420022802502105200241c8006a200241106a1079200228024822060d0102402004450d00200441246c21002003210103400240024020012d0000220741034b0d0002400240024020070e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b2005450d002003102a0b200241dc016a4104360200200241dc006a41023602002002420237024c200241bca7c400360248200241043602d40120024194a9c4003602d0012002410036022c200241b8aec6003602282002200241d0016a3602582002200241286a3602d801200241c8006a41cca7c400103e000b200241d0006a2802002108200228024c2109200241086a200241106a106c0240024020022802080d00200228020c21012002200241106a360228200241003a0038200242003702d401200241f8b9c0003602d0012002200136024c200241003602482002200241386a3602542002200241286a360250200241c8006a200241d0016a10860420022802d001210120022902d401210a024020022d0038450d002001200aa7200a422088a710b0020c010b20010d010b200241dc016a4104360200200241dc006a41023602002002420237024c200241bca7c400360248200241043602d40120024194a9c4003602d0012002410036022c200241b8aec6003602282002200241d0016a3602582002200241286a3602d801200241c8006a41cca7c400103e000b2002200a37021c20022001360218200241013b01342002420037022c200241f8b9c000360228200241286a41086a210b024002400240024002402008450d002006200841a0026c6a210c200241d0016a410272210d2006210e024002400240024002400240024002400340200e41e8006a2903004202520d0902400240200e28029801410247220f0d00200e2903a001210a200241186a2101200228021c211002400240024002400240024002400240024002400240024002400240024002400240024003402001280200221141086a210020112f010622124103742101410021070240024003402001450d0141f7fcc50020004108109c052213450d02200141786a2101200741016a2107200041086a21002013417f4a0d000b2007417f6a21120b2010450d022010417f6a2110201120124102746a41e4016a21010c010b0b0240201141e0006a2007410c6c6a220128020841074b0d00201442808080807083422984210a41fffcc50021120c020b200a42b8178020012802002900002214510d0341c6e6c2002112413121100c020b201442808080807083421c84210a41a8fdc50021120b200aa721100b024002400240024020022d0035450d004131210141f7e6c20021000c010b2002280228200228022c200228023010b0022002420037022c200241f8b9c000360228200242e2c289abb68edbb7f400370338200241d0016a410272410041da001099051a200241c8006a41004184011099051a41e40110282213450d0420134100360200201341046a200241d0016a41dc00109a051a201341e0006a200241c8006a418401109a051a2002410036022c2002201336022820132f0106220e4103742111417f210041002101024002400340024020112001470d00200e21000c020b200241386a201320016a41086a4108109c052207450d02200141086a2101200041016a2100200741004e0d000b0b200242e2c289abb68edbb7f40037025c2002200b360258200220003602542002201336024c200241003602482002200241286a360250201041046a2200417f4c0d062000450d02200010282201450d07200241003602ac02200220013602d0012010413f4b0d03200120104102743a0000410121070c1b0b412d210141a8e7c20021000b2002200136024c2002200036024841d5e7c2004122200241c8006a41f8e7c2001038000b200241003602ac0241012100200241013602d001410110282201450d05200141033a0000200241013602ac02200220013602d001410521070c130b201041808001490d162010418080808004490d150c100b200f0d0e200e2903a0012115200241c8006a200241186a10970402400240024020022802484101470d002002350250210a200228024c21160c010b2002290350210a200241c8006a41086a220142003703002002420037034841feb3c300410d200241c8006a1008200241d0016a41086a2001290300370300200220022903483703d00120024100360248200241d0016a4110200241c8006a100621010240024020022802482200417f470d00420021170c010b024020010d00420021170c010b200041074d0d07200129000021172001102a0b02402015200a423c7c560d004100210f2015201742dc0b7c220a540d020c110b201842808080807083422584210a41f8b5c30021160b4101210f0b024020022d0035450d004131210141f7e6c20021000c080b0240200f450d002002280228200228022c200228023010b0022002420037022c200241f8b9c000360228200242f4d2b59bc7ae98b8303703380c060b20022802282111200242f4d2b59bc7ae98b830370338201141f8b9c000460d05200228022c21100c060b41e40141041037000b1036000b200041011037000b410141011037000b41c4d1c3004133200241c8006a419cd9c3001038000b200d410041da001099051a200241c8006a41004184011099051a41e40110282211450d034100211020114100360200201141046a200241d0016a41dc00109a051a201141e0006a200241c8006a418401109a051a2002410036022c200220113602280b0340201141086a210020112f010622124103742101410021070240024003402001450d01200241386a20004108109c052213450d02200141786a2101200741016a2107200041086a21002013417f4a0d000b2007417f6a21120b2010450d032010417f6a2110201120124102746a41e4016a28020021110c010b0b412d210141a8e7c20021000b2002200136024c2002200036024841d5e7c2004122200241c8006a41f8e7c2001038000b200242f4d2b59bc7ae98b83037025c2002200b360258200220123602542002201136024c200241003602482002200241286a360250200241003602d801200242013703d00141011028210102400240200f0d002001450d03200141003a000020024281808080103702d401200220013602d001200141014109102c2201450d042001200a3700012002428980808090013702d401200220013602d0010c010b2001450d04200141013a000020024281808080103702d401200220013602d001200aa72201200241d0016a10b4010240024020022802d401220720022802d80122006b2001490d0020022802d00121070c010b200020016a22132000490d14200741017422112013201120134b1b22134100480d140240024020070d002013102821070c010b20022802d00120072013102c21070b2007450d06200220133602d401200220073602d0010b2002200020016a3602d801200720006a20162001109a051a0b200241386a41086a200241d0016a41086a280200360200200220022903d001370338200241c8006a200241386a10bb022002200f3a0035200241003a0034200a2118200f450d05200241d0016a41086a200241286a41086a290300370300200220022903283703d0010c110b41e40141041037000b410141011037000b410941011037000b410141011037000b201341011037000b200e41a0026a220e200c470d010c0a0b0b200141033a0000200241013602ac022000417f6a41034b0d01200041017422074105200741054b1b22074100480d0a0b200120002007102c2201450d01200220013602d001200721000b20012010360001410521070c030b200741011037000b02400240200041034b0d00200041017422074104200741044b1b22074100480d08200120002007102c2201450d01200220013602d001200721000b20012010410274410272360000410421070c020b200741011037000b0240200041014b0d0020012000200041017422074102200741024b1b2207102c2201450d02200220013602d001200721000b41022107200120104102744101723b00000b200220073602ac0202400240200020076b2010490d00200021130c010b200720106a22132007490d05200041017422112013201120134b1b22134100480d05200120002013102c2201450d02200220013602d0010b2002200720106a3602ac02200120076a20122010109a051a2002201336023c200220022802d001360238200220022802ac02360240200241c8006a200241386a10bb0220024180023b0134200241d0016a41086a200241286a41086a290300370300200220022903283703d0010c030b200741011037000b201341011037000b200241d0016a41086a200b290300370300200220022903283703d0010b2002280218200228021c200228022010b00202402004450d00200441246c21002003210103400240024020012d0000220741034b0d0002400240024020070e0404000102040b2001410c6a280200450d03200141086a280200102a0c030b2001410c6a280200450d02200141086a280200102a0c020b2001410c6a280200450d01200141086a280200102a0c010b200141086a280200450d00200141046a280200102a0b200141246a21012000415c6a22000d000b0b02402005450d002003102a0b02402008450d00200841a0026c210020064198016a210103402001106a200141a0026a2101200041e07d6a22000d000b0b02402009450d002006102a0b2002410036025020024201370348410110282201450d022002410136024c20022002280250220041016a36025020022001360248200120006a20022d00dc013a000002400240200228024c20022802502201460d00200228024821000c010b200141016a22002001490d01200141017422072000200720004b1b22074100480d010240024020010d002007102821000c010b200228024820012007102c21000b2000450d022002200736024c20022000360248200228025021010b2002200141016a360250200020016a20022d00dd013a000020022802d801200241c8006a10b40120022802d00122072100024020022802d4012213450d002013210120072100034020002802e40121002001417f6a22010d000b0b0240024002400240024002400240024002400240024020022802d80122120d00410021010c010b200241d0016a210f41002113034002400240201320002f01064f0d0020002013410c6c6a41e0006a2111200020134103746a41086a2101201341016a21130c010b02400240200028020022010d00201542808080807083200fad84211541002107410021010c010b2000330104422086200fad842115410121070b201521142015210a02402015422088a7220020012f0106490d000340200a221442ffffffff0f83210a200741016a210720012f01042200200128020022012f01064f0d000b0b20012000410c6c6a2113200120004103746a2110200041027420016a41e8016a28020021002014a7210f02402007417f6a2201450d00034020002802e40121002001417f6a22010d000b0b201341e0006a2111201041086a2101410021130b02400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d032002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00003a000002400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d042002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00013a000002400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d052002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00023a000002400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d062002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00033a000002400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d072002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00043a000002400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d082002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00053a000002400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d092002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00063a000002400240200228024c20022802502207460d00200228024821100c010b200741016a22102007490d0c2007410174220e2010200e20104b1b220e4100480d0c0240024020070d00200e102821100c010b20022802482007200e102c21100b2010450d0a2002200e36024c20022010360248200228025021070b2002200741016a360250201020076a20012d00073a00002011280200211020112802082201200241c8006a10b40102400240200228024c2211200228025022076b2001490d00200228024821110c010b200720016a220e2007490d0c20114101742207200e2007200e4b1b22074100480d0c0240024020110d002007102821110c010b200228024820112007102c21110b2011450d0b2002200736024c20022011360248200228025021070b2002200720016a360250201120076a20102001109a051a2012417f6a22120d000b20022802d801210120022802d401211320022802d00121070b2002350248210a2002350250211420072013200110b002200241b0026a2400200a2014422086840f0b200e41011037000b200e41011037000b200e41011037000b200e41011037000b200e41011037000b200e41011037000b200e41011037000b200e41011037000b200741011037000b1031000b200741011037000b410141011037000b5702017f027e230041306b2202240020024101410010a80320024100360228200242013703202002200241206a36022c20022002412c6a10c8012002350228210320023502202104200241306a240020042003422086840bba48030b7f047e017f230041d00c6b22022400024002402001450d00200220003602100c010b200241013602100b20022001360214200241f0066a200241106a107a024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022903d8074203510d00200241186a200241f0066a41a002109a051a200241f0026a200241186a41a002109a051a200241f0066a200241f0026a10870420022802f8062103024020022802f406450d0020022802f006102a0b200241f0066a200241f0026a41a002109a051a20024190056a200241f0066a10d10341012100024020022d0090054101470d00200220022d0093053a00bb02200220022f0091053b00b902200241013a00b8020c180b200241f0066a20024190056a41086a41d801109a051a200241086a200241c0076a220410f301024002402002290390074202520d00200241b8026a41206a22014200370300200241b8026a41186a22004280808080c000370300200241013a00e002200242043703c8022002427f3703c002200242003703b80220024190056a41206a2203420037030020024190056a41186a22054280808080c000370300200241013a00b805200242043703a0052002427f370398052002420037039005200241c8096a200241b8026a20024190056a109b04200241b8026a41286a2206200241c8096a41286a2903003703002001200241c8096a41206a2903003703002000200241c8096a41186a290300370300200241b8026a41106a2207200241c8096a41106a290300370300200241b8026a41086a2208200241c8096a41086a290300370300200220022903c8093703b8022003420037030020054280808080c000370300200241013a00b805200242043703a0052002427f370398052002420037039005200241f8096a200241b8026a20024190056a109b042006200241f8096a41286a2903003703002001200241f8096a41206a2903003703002000200241f8096a41186a2903003703002007200241f8096a41106a2903003703002008200241f8096a41086a290300370300200220022903f8093703b8022003420037030020054280808080c000370300200241013a00b805200242043703a0052002427f370398052002420037039005200241a80a6a200241b8026a20024190056a109b042006200241a80a6a41286a2903003703002001200241a80a6a41206a2903003703002000200241a80a6a41186a2903003703002007200241a80a6a41106a2903003703002008200241a80a6a41086a290300370300200220022903a80a3703b8022003420037030020054280808080c000370300200241013a00b805200242043703a0052002427f370398052002420037039005200241d80a6a200241b8026a20024190056a109b042006200241d80a6a41286a2903003703002001200241d80a6a41206a2903003703002000200241d80a6a41186a2903003703002007200241d80a6a41106a2903003703002008200241d80a6a41086a290300370300200220022903d80a3703b8022003420037030020054280808080c000370300200241013a00b805200242043703a0052002427f370398052002420037039005200241880b6a200241b8026a20024190056a109b042006200241880b6a41286a2903003703002001200241880b6a41206a2903003703002000200241880b6a41186a2903003703002007200241880b6a41106a2903003703002008200241880b6a41086a290300370300200220022903880b3703b8022003420037030020054280808080c000370300200241013a00b805200242043703a0052002427f370398052002420037039005200241b80b6a200241b8026a20024190056a109b04200241980c6a41286a2203200241b80b6a41286a290300370300200241980c6a41206a2206200241b80b6a41206a290300370300200241980c6a41186a2205200241b80b6a41186a290300370300200241980c6a41106a2207200241b80b6a41106a290300370300200241980c6a41086a2208200241b80b6a41086a290300370300200220022903b80b3703980c2001420037030020004280808080c000370300200241013a00e002200242043703c8022002427f3703c002200242003703b802200241e80b6a200241980c6a200241b8026a109b042002419c056a2201200241e80b6a41086a290300370200200241a4056a2200200241e80b6a41106a290300370200200241ac056a2209200241e80b6a41186a290300370200200241b4056a220a200241e80b6a41206a290300370200200241bc056a220b200241e80b6a41286a290300370200200220022903e80b3702940520024198096a41286a220c200b29020037030020024198096a41206a220b200a29020037030020024198096a41186a220a200929020037030020024198096a41106a2209200029020037030020024198096a41086a220020012902003703002002200229029405370398092003200c2903003703002006200b2903003703002005200a290300370300200720092903003703002008200029030037030020022002290398093703980c418102210120022802c0074112460d010c170b20022d000c210b20022802082108200241b8026a41206a22014200370300200241b8026a41186a22004280808080c000370300200241013a00e002200242043703c8022002427f3703c002200242003703b80220024190056a41206a2205420037030020024190056a41186a22064280808080c000370300200241013a00b805200242043703a0052002427f37039805200242003703900520024198096a200241b8026a20024190056a109b04200241b8026a41286a220720024198096a41286a290300370300200120024198096a41206a290300370300200020024198096a41186a290300370300200241b8026a41106a220920024198096a41106a290300370300200241b8026a41086a220a20024198096a41086a29030037030020022002290398093703b8022005420037030020064280808080c000370300200241013a00b805200242043703a0052002427f370398052002420037039005200241c8096a200241b8026a20024190056a109b042007200241c8096a41286a2903003703002001200241c8096a41206a2903003703002000200241c8096a41186a2903003703002009200241c8096a41106a290300370300200a200241c8096a41086a290300370300200220022903c8093703b802200241b80b6a41086a22014200370300200242003703b80b41d9efc200410d200241b80b6a1008200241880b6a41086a2001290300370300200220022903b80b3703880b410021002002410036029005200241880b6a411020024190056a1006210102402002280290052205417f460d002001450d0020054104490d03200128000021002001102a0b2000ad210d427f210e02402002290390074201520d00200229039807220e4200510d04200d200241a0076a290300220f200f200d541b2210200e7c2010200f7d200e827d210e0b20024190056a41206a420037030020024190056a41186a4280808080c000370300200241bc056a2002419b0c6a280000360000200241013a00b805200242043703a0052002420037039005200220022800980c3600b90520024200200e200d7d220d200d200e561b37039805200241f8096a200241b8026a20024190056a109b04200241980c6a41286a200241f8096a41286a290300370300200241980c6a41206a200241f8096a41206a290300370300200241980c6a41186a200241f8096a41186a290300370300200241980c6a41106a200241f8096a41106a290300370300200241980c6a41086a200241f8096a41086a290300370300200220022903f8093703980c20022802b8072100411310282201450d04200141002900cef0423700002001410f6a41002800ddf042360000200141086a41002900d6f04237000020024293808080b0023702bc0b200220013602b80b200241f0066a200241b80b6a108f0120022802c00b210120022802b80b2105200241b8026a41186a22064200370300200241b8026a41106a22074200370300200241b8026a41086a22094200370300200242003703b80220052001200241b8026a1000200241e80b6a41186a2006290300370300200241e80b6a41106a2007290300370300200241e80b6a41086a2009290300370300200220022903b8023703e80b024020022802bc0b450d0020022802b80b102a0b200241003602b802200241e80b6a4120200241b8026a100621010240024020022802b8022205417f460d002001450d00024020054104490d00200128000021092001102a200920004d0d02200220022800880b3602900920022002418b0b6a28000036009309200241003a00bb0220024180063b00b902200241013a00b80220022802a80c21030240200241b00c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b0240200241ac0c6a280200450d002003102a0b20022802b40c21030240200241bc0c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b200241b80c6a280200450d1a2003102a0c1a0b41c4d1c3004133200241c80c6a419cd9c3001038000b410021090b410c10282205450d05410410282201450d06200242043702bc02200220013602b802200241f0066a200241b8026a108f010240024020022802bc02220620022802c00222016b4104490d0020022802b80221070c010b200141046a22072001490d1a200641017422012007200120074b1b22014100480d1a0240024020060d002001102821070c010b20022802b80220062001102c21070b2007450d08200220013602bc02200220073602b80220022802c00221010b410421062002200141046a3602c002200720016a2000360000200241e80b6a41086a20022802c0022201360200200220022903b802220e3703e80b200541086a20013602002005200e370200410021010240200920004f0d00410c10282206450d09410410282201450d0a200242043702bc02200220013602b802200241f0066a200241b8026a108f010240024020022802bc02220720022802c00222016b4104490d0020022802b80221070c010b200141046a22092001490d1b200741017422012009200120094b1b22014100480d1b0240024020070d002001102821070c010b20022802b80220072001102c21070b2007450d0c200220013602bc02200220073602b80220022802c00221010b2002200141046a3602c002200720016a2000417f6a360000200241e80b6a41086a20022802c0022201360200200220022903b802220e3703e80b200641086a20013602002006200e370200410121010b20024190056a41206a42818080801037030020024190056a41186a2001360200200241a4056a2001360200200220022800880b3602900920022002418b0b6a28000036009309200241bc056a200228009309360000200241013a00b805200220053602ac05200220063602a0052002427f3703980520022008ad220e3703900520022002280290093600b905200241a80a6a200241980c6a20024190056a109b04200241980c6a41286a200241a80a6a41286a290300370300200241980c6a41206a200241a80a6a41206a290300370300200241980c6a41186a200241a80a6a41186a290300370300200241980c6a41106a200241a80a6a41106a290300370300200241980c6a41086a200241a80a6a41086a290300370300200220022903a80a3703980c200241b8026a200b4101712201200310b80320022d00b8020d14200241b8026a2008200110b90320022d00b802450d1320022f00b90220022d00bb024110747221010c150b200241e4076a2802002100200241b8026a10fb01200010fc0120022802b802220120022802c00241014100410010032103024020022802bc02450d002001102a0b41800621012003417f470d1510fb01220c200241e0076a280200470d15200241b80b6a41086a22014200370300200242003703b80b41c2e1c000410d200241b80b6a1008200241880b6a41086a2001290300370300200220022903b80b3703880b200241003602b802200241880b6a4110200241b8026a100621010240024020022802b8022203417f460d002001450d00200220033602bc0b200220013602b80b200241b8026a200241b80b6a107c20022802b802220b450d0c20022902bc02210e2003450d012001102a0c010b4101210b4200210e20022802e40721000b024002402000200e422088a74f0d00200b20004105746a2211450d00200241003602c002200242013703b802200241c4076a2802002100410410282201450d0d20024284808080c0003702bc02200220013602b80220012000360000200241c8076a2802002106200241d0076a2802002201200241b8026a10b4010240024020022802bc02220320022802c00222006b2001490d0020022802b80221030c010b200020016a22072000490d1b200341017422082007200820074b1b22074100480d1b0240024020030d002007102821030c010b20022802b80220032007102c21030b2003450d0f200220073602bc02200220033602b8020b2002200020016a3602c002200320006a20062001109a051a200241d4076a2802002100200241dc076a2802002201200241b8026a10b4010240024020010d0020022802bc02210620022802c00221090c010b20002001410c6c6a210a034020002802002108200041086a2802002201200241b8026a10b4010240024020022802bc02220620022802c00222036b2001490d0020022802b80221070c010b200320016a22072003490d1d200641017422092007200920074b1b22094100480d1d0240024020060d002009102821070c010b20022802b80220062009102c21070b2007450d12200220093602bc02200220073602b802200921060b2002200320016a22093602c002200720036a20082001109a051a2000410c6a2200200a470d000b0b20022802e007210302400240200620096b4104490d0020022802b80221010c010b200941046a22012009490d1b200641017422002001200020014b1b22004100480d1b0240024020060d002000102821010c010b20022802b80220062000102c21010b2001450d11200220003602bc02200220013602b802200021060b2002200941046a22003602c002200120096a200336000020022802e407210702400240200620006b41034d0d00200621030c010b200041046a22032000490d1b200641017422082003200820034b1b22034100480d1b0240024020060d002003102821010c010b200120062003102c21010b2001450d12200220033602bc02200220013602b8020b200120006a20073600002001200941086a200241e8076a2011100a210002402003450d002001102a0b2000450d010b4180082101200ea7450d16200b102a0c160b410c10282201450d10410410282200450d1120024284808080c0003702bc02200220003602b8022000200c3600002011200241b8026a108f01200241b80b6a41086a20022802c0022200360200200220022903b802220d3703b80b200141086a20003602002001200d370200200220022800880b3602d80a20022002418b0b6a2800003600db0a0240200ea7450d00200b102a0b20024190056a41206a42818080801037030020024190056a41186a4100360200200241bc056a20022800db0a360000200241013a00b805200220013602ac05200242043703a0052002427f370398052002420037039005200220022802d80a3600b905200241e80b6a200241980c6a20024190056a109b04200241b8026a41086a20022903e80b370300200241b8026a41106a200241e80b6a41086a290300370300200241b8026a41186a200241e80b6a41106a290300370300200241b8026a41206a200241e80b6a41186a290300370300200241b8026a41286a200241e80b6a41206a290300370300200241e8026a200241e80b6a41286a290300370300200241003a00b8020c160b200241246a410436020020024184036a4102360200200242023702f402200241bca7c4003602f0022002410436021c200241aca9c4003602182002410036029405200241b8aec600360290052002200241186a36028003200220024190056a360220200241f0026a41cca7c400103e000b41c4d1c3004133200241c80c6a419cd9c3001038000b41fcf8c5001032000b411341011037000b410c41041037000b410441011037000b200141011037000b410c41041037000b410441011037000b200141011037000b41c4d1c3004133200241c80c6a419cd9c3001038000b410441011037000b200741011037000b200941011037000b200041011037000b200341011037000b410c41041037000b410441011037000b20024190056a41206a2205420037030020024190056a41186a22064280808080c000370300200220022800880b3602e80b20022002418b0b6a2800003600eb0b200241bc056a20022800eb0b360000200242043703a0052002427f370398052002427f200e20011b37039005200220022802e80b3600b905200241013a00b805200241d80a6a200241980c6a20024190056a109b04200241e80b6a41286a2207200241d80a6a41286a290300370300200241e80b6a41206a2209200241d80a6a41206a290300370300200241e80b6a41186a2200200241d80a6a41186a290300370300200241e80b6a41106a220a200241d80a6a41106a290300370300200241e80b6a41086a220b200241d80a6a41086a290300370300200220022903d80a3703e80b20024190056a20022903a807200241b0076a290300200241f0066a200820012003109e02024020022d0090054101470d00200220022d0093053a00bb02200220022f0091053b00b902200241013a00b80220022802f80b2103024020002802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b0240200241fc0b6a280200450d002003102a0b20022802840c210302402002418c0c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b200241880c6a280200450d042003102a0c040b200241980c6a41286a20024190056a41306a2201290300370300200241980c6a41206a20024190056a41286a290300370300200241980c6a41186a2005290300370300200241980c6a41106a2006290300370300200241980c6a41086a20024190056a41106a29030037030020022002290398053703980c200241880b6a200241e80b6a200241980c6a109b042007200241880b6a41286a2903003703002009200241880b6a41206a2903003703002000200241880b6a41186a290300370300200a200241880b6a41106a290300370300200b200241880b6a41086a290300370300200220022903880b3703e80b20024190056a200410d203024020022d0090054101470d00200220022d0093053a00bb02200220022f0091053b00b902200241013a00b80220022802f80b21030240200241800c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b0240200241fc0b6a280200450d002003102a0b20022802840c210302402002418c0c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b200241880c6a280200450d042003102a0c040b200241980c6a41286a2001290300370300200241980c6a41206a20024190056a41286a290300370300200241980c6a41186a20024190056a41206a290300370300200241980c6a41106a20024190056a41186a290300370300200241980c6a41086a20024190056a41106a29030037030020022002290398053703980c200241b80b6a200241e80b6a200241980c6a109b04200241b8026a41086a20022903b80b370300200241b8026a41106a200241b80b6a41086a290300370300200241b8026a41186a200241b80b6a41106a290300370300200241b8026a41206a200241b80b6a41186a290300370300200241b8026a41286a200241b80b6a41206a290300370300200241b8026a41306a200241b80b6a41286a290300370300200241003a00b8020c030b20022f00b90220022d00bb024110747221010b200220022800880b3602e80b20022002418b0b6a2800003600eb0b200241013a00b802200220013b00b902200220014110763a00bb0220022802a80c21030240200241b00c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b0240200241ac0c6a280200450d002003102a0b20022802b40c21030240200241bc0c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b200241b80c6a280200450d012003102a0c010b200241003a00bb02200220013b00b902200241013a00b80220022802a80c2103024020052802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b0240200241ac0c6a280200450d002003102a0b20022802b40c21030240200241bc0c6a2802002201450d002001410c6c21002003210103400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b200241b80c6a280200450d002003102a0b2004106a20022d00b80221000b024002400240024002400240410110282201450d00200242013702f406200220013602f00602400240200041ff01714101460d00200241013602f806200141003a0000200241c0026a290300210e024020022802f4062200417f6a41074b0d00200041017422034109200341094b1b22034100480d09200120002003102c2201450d04200220033602f406200220013602f0060b200241093602f8062001200e370001200241d0026a2802002100200241d8026a2802002201200241f0066a10b40102402001450d0020002001410c6c6a2108034020002802002106200041086a2802002201200241f0066a10b4010240024020022802f406220520022802f80622036b2001490d0020022802f00621050c010b200320016a22072003490d0b200541017422042007200420074b1b22074100480d0b0240024020050d002007102821050c010b20022802f00620052007102c21050b2005450d07200220073602f406200220053602f0060b2002200320016a3602f806200520036a20062001109a051a2000410c6a22002008470d000b0b200241dc026a2802002100200241e4026a2802002201200241f0066a10b4010240024020010d0020022802f406210620022802f80621080c010b20002001410c6c6a2104034020002802002107200041086a2802002201200241f0066a10b4010240024020022802f406220620022802f80622036b2001490d0020022802f00621050c010b200320016a22052003490d0b200641017422082005200820054b1b22084100480d0b0240024020060d002008102821050c010b20022802f00620062008102c21050b2005450d08200220083602f406200220053602f006200821060b2002200320016a22083602f806200520036a20072001109a051a2000410c6a22002004470d000b0b200241c8026a290300210e02400240200620086b4108490d0020022802f00621030c010b200841086a22012008490d09200641017422002001200020014b1b22014100480d090240024020060d002001102821030c010b20022802f00620062001102c21030b2003450d07200220013602f406200220033602f0060b2002200841086a3602f806200320086a200e370000024020022802f40620022802f8062201470d00200141016a22002001490d09200141017422052000200520004b1b22004100480d090240024020010d002000102821030c010b200320012000102c21030b2003450d08200220003602f406200220033602f0060b2002200141016a22053602f806200320016a20022d00e8023a00000c010b200241013602f806200141013a0000200241b8026a410172200241f0066a10c60320022802f806210520022802f00621030b024020022d00b8020d000240200241d8026a2802002200450d00200241d0026a28020021012000410c6c210003400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b0240200241d4026a280200450d0020022802d002102a0b0240200241e4026a2802002200450d00200241dc026a28020021012000410c6c210003400240200141046a280200450d002001280200102a0b2001410c6a2101200041746a22000d000b0b200241e0026a280200450d0020022802dc02102a0b200241d00c6a24002005ad4220862003ad840f0b410141011037000b200341011037000b200741011037000b200841011037000b200141011037000b200041011037000b1031000bd40505017f027e077f017e017f230041206b220324002002290300210420012903002105200141106a2106200228021021070240024002400240024002400240200141146a2802002208200141186a28020022096b200241186a280200220a490d00200628020021080c010b2009200a6a220b2009490d032008410174220c200b200c200b4b1b220bad420c7e220d422088a70d03200da7220c4100480d030240024020080d00200c102821080c010b20062802002008410c6c200c102c21080b2008450d0120012008360210200141146a200b3602000b20082009410c6c6a2007200a410c6c109a051a200141186a2009200a6a36020020024100360218200341086a200641086a280200360200200320062902003703002001411c6a2106200228021c210b02400240200141206a2802002208200141246a28020022096b200241246a280200220a490d00200628020021080c010b2009200a6a220c2009490d032008410174220e200c200e200c4b1b220cad420c7e220d422088a70d03200da7220e4100480d030240024020080d00200e102821080c010b20062802002008410c6c200e102c21080b2008450d022001200836021c200141206a200c3602000b427f200520047c220420042005541b210520082009410c6c6a200b200a410c6c109a051a200141246a2009200a6a36020020024100360224200341106a41086a200641086a28020036020020032006290200370310200229030822042001290308220d200d2004561b210420012d0028450d034101210120022d0028450d030c040b200c41041037000b200e41041037000b1031000b410021010b20002005370300200020032903003702102000200329031037021c200020013a002820002004370308200041186a200341086a280200360200200041246a200341106a41086a2802003602000240200241146a280200450d002007102a0b0240200241206a280200450d00200b102a0b200341206a24000ba13507037f017e037f017e147f027e107f230041d0036b2202240002400240024002400240024002400240024020014104490d0020002800002103101a4101470d07200241a8016a41086a22004200370300200242003703a801419be1c0004111200241a8016a1008200241e8006a41086a2000290300370300200220022903a80137036841002101200241003602a801200241e8006a4110200241a8016a100621000240024020022802a8012204417f460d002000450d0020044104490d01200028000021012000102a0b200241003602a801410141838ac100411c200241a8016a101b2100024002400240024020022802a8012204417f470d00410121040c010b2004ad22054220862005842105200045210420000d010b41002100410121060c010b2005422088a74105490d04200028000121070240024020002d00000d0020072003460d0141002106200720034f0d02410121060c020b4101210620072001490d010b410021060b200120034f0d022006450d020240410110282201450d00200141003a00000240200141014105102c2201450d0020012003360001410141838ac100411c4100200020041b22062005422088a7417f20061b20014105101c21062001102a024020042005a745720d002000102a0b20060d0a200241a8016a41086a22004200370300200242003703a80141c2e1c000410d200241a8016a1008200241e8006a41086a2000290300370300200220022903a801370368200241003602a801200241e8006a4110200241a8016a1006210002400240024020022802a8012201417f460d002000450d002002200136022c20022000360228200241a8016a200241286a107c20022802a8012208450d0220022902ac0121092001450d012000102a0c010b42002109410121080b200241186a109d042002280218210a2002280220220b4115490d07200b410176220c41ffffff3f71200c470d09200c4105742200417f4c0d094101210d024002402000450d0020001028220d450d010b200a41606a210e200a41a07f6a210f41002110410021114104211241002113200b211403400240024020142215417f6a22040d0041012107410021140c010b024002400240024002400240200a20044105746a20154105742216200a6a41406a4120109c054100480d002015417e6a2106200f20166a210041002114410021010340024020062001470d00201521070c080b200141016a2101200041206a20004120109c052104200041606a21002004417f4a0d000b200141016a21072001417f7320156a21040c010b200f20166a210002400340024020044101470d00410021040c020b2004417f6a2104200041206a20004120109c052101200041606a210020014100480d000b0b20152004490d012015200b4b0d03201520046b22074101762206450d00200e20166a2100200a20044105746a21010340200241a8016a41186a2216200141186a2217290000370300200241a8016a41106a2218200141106a2219290000370300200241a8016a41086a221a200141086a221b290000370300200220012900003703a801200041086a221c2900002105200041106a221d290000211e200041186a2214290000211f200120002900003700002017201f3700002019201e370000201b200537000020142016290300370000201d2018290300370000201c201a290300370000200020022903a801370000200041606a2100200141206a21012006417f6a22060d000b0b024020040d00200421140c050b0240200741094d0d00200421140c050b2015200b4b0d01201520046b2106200a20044105746a2116034020152004417f6a2214490d040240201520146b22074102490d00200a20044105746a2200200a20144105746a22044120109c05417f4a0d002004290000210520042000290000370000200241a8016a41186a221a200441186a2201290000370300200241a8016a41106a221b200441106a2217290000370300200241a8016a41086a221c200441086a22182900003703002018200041086a2900003700002017200041106a2900003700002001200041186a290000370000200220053703a80141012119024020074103490d00200441c0006a200241a8016a4120109c05417f4a0d00410221012016210002400340200041186a200041386a290000370000200041106a200041306a290000370000200041086a200041286a2900003700002000200041206a221729000037000020062001460d01200041c0006a21182001211920172100200141016a21012018200241a8016a4120109c05417f4a0d020c000b0b200121190b200420194105746a220020022903a801370000200041186a201a290300370000200041106a201b290300370000200041086a201c2903003700000b2014450d05201641606a2116200641016a2106201421042007410a4f0d050c000b0b200420151044000b20152004417f6a2214490d010b2015200b103c000b201420151044000b02400240024020132011470d00201141016a22002011490d11201141017422012000200120004b1b220041ffffffff01712000470d11200041037422014100480d110240024020110d002001102821120c010b201220114103742001102c21120b2012450d0120002111201021130b201220134103746a2200200736020420002014360200201041016a2213211020134102490d0102400340024002400240024020122013417f6a22104103746a2200280200450d00201341037420126a220641746a2802002204200028020422014d0d000240201341024b0d0020132110410221130c080b20122013417d6a221a4103746a2802042200200120046a4d0d010240201341034b0d0020132110410321130c080b200641646a280200200020046a4d0d01201321100c070b20134103490d012000280204210120122013417d6a221a4103746a28020421000b20002001490d010b2013417e6a211a0b0240024002400240024002402013201a41016a22204b2221450d002013201a4b2222450d012012201a4103746a221b2802042223201b2802006a2200201220204103746a221c280200221d490d022000200b4b0d03200a201d4105746a2218201c280204221941057422016a2106200041057421042000201d6b221520196b220020194f0d04200d200620004105742201109a05221720016a21070240024020194101480d00200041014e0d010b20062100201721010c060b200e20046a21042006210003402004200041606a2206200741606a2215201520064120109c0541004822161b2201290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a2900003700002007201520161b2107024020182006200020161b2200490d00201721010c070b200441606a21042017210120172007490d000c060b0b41b8dbc000202020131034000b41b8dbc000201a20131034000b201d20001044000b2000200b103c000b200d20182001109a05221720016a21070240024020194101480d00201520194a0d010b20182100201721010c010b200a20046a211620172101201821000340200020062001200620014120109c0541004822151b2204290000370000200041186a200441186a290000370000200041106a200441106a290000370000200041086a200441086a2900003700002001200141206a20151b2101200041206a2100200641206a200620151b220620164f0d01200720014b0d000b0b20002001200720016b416071109a051a02402022450d00201b201d360200201b41046a202320196a3602002021450d02201c201c41086a20132020417f736a410374109b051a20102113201041014d0d040c010b0b41c8dbc000201a20131034000b41b0b1c0001032000b200141041037000b20140d000b02402011450d002012102a0b200c450d09200d102a0c090b200041011037000b41c4d1c3004133200241186a419cd9c3001038000b410541011037000b410141011037000b41c4d1c3004133200241186a419cd9c3001038000b200241f4006a4104360200200241bc016a4102360200200242023702ac01200241bca7c4003602a8012002410436026c200241c8a9c4003602682002410036022c200241b8aec6003602282002200241e8006a3602b8012002200241286a360270200241a8016a41cca7c400103e000b20042005a745720d052000102a0c050b02402005a7450d002000102a0b41e695c600412d100b0c040b200b4102490d00200a200b417f6a22014105746a21074101210403400240024002400240200b20012200417f6a2201490d00200b20016b22154102490d03200a20004105746a2200200a20014105746a22064120109c05417f4a0d032006290000210520062000290000370000200241a8016a41186a2213200641186a2216290000370300200241a8016a41106a2219200641106a2217290000370300200241a8016a41086a2212200641086a22182900003703002018200041086a2900003700002017200041106a2900003700002016200041186a290000370000200220053703a8014101210020154103490d02200641c0006a200241a8016a4120109c05417f4a0d0241002115200721000340200041186a200041386a290000370000200041106a200041306a290000370000200041086a200041286a2900003700002000200041206a2217290000370000200420152216460d022016417f6a2115200041c0006a2118201721002018200241a8016a4120109c05417f4a0d020c000b0b2001200b1044000b410220166b21000b200620004105746a220020022903a801370000200041186a2013290300370000200041106a2019290300370000200041086a20122903003700000b200741606a21072004417f6a210420010d000b0b2009a721102009422088a72200450d01200820004105746a2118200241a8016a41016a211a200241c0026a2124200241e9026a211b200241e0016a2125200241a8016a41306a2126200241a8016a41286a212741002115200821070240024002400240024002400340024002400240200b41014b0d000240200b0e020c000c0b0340200241a8016a41186a200741186a290000370300200241a8016a41106a200741106a290000370300200241a8016a41086a200741086a290000370300200220072900003703a801200a200241a8016a4120109c05450d02201541016a21152018200741206a2207470d000c0c0b0b0340200241a8016a41186a200741186a290000370300200241a8016a41106a200741106a290000370300200241a8016a41086a200741086a290000370300200220072900003703a801200741206a21070240200b450d0041002100200b210103402001410176220420006a22062000200a20064105746a200241a8016a4120109c054101481b2100200120046b220141014b0d000b200a20004105746a200241a8016a4120109c05450d030b201541016a211520072018460d0b0c000b0b200741206a2107410021000b0240024002400240024002400240200b20004d0d0020024100360268200241e8006a101d2104024020022802682201417f470d00410221060c0a0b200220013602ac01200220043602a8012001450d0320042d0000210620022001417f6a3602ac012002200441016a3602a801200641014b0d030240024020060e020100010b410021202021210c2012211c2019211420132128201721292016211d2021212a2012212b2019212c2013212d2017212e2016212f0c060b200241106a200241a8016a106c20022802100d0320022802ac0122062002280214222b490d03202b417f4c0d0e02400240202b0d004101212041010d010c050b202b102e2220450d02202020022802a801221c202b109a05211d20022006202b6b3602ac012002201c202b6a3602a801201d450d040b200241086a200241a8016a106c20022802080d0220022802ac01410c6e222e410c6c2206417f4c0d0e200228020c212f0240024002400240024020060d004104212d0c010b20061028222d450d010b024002400240202f0d00202d212c0c010b4100210c4100211c41002114202d212c03402002200241a8016a106c20022802000d0220022802ac01221d20022802042206490d022006417f4c0d140240024020060d00410121290c010b2006102e2229450d05202920022802a80122282006109a051a2002201d20066b3602ac012002202820066a3602a8010b201441016a211d02402014202e470d00200c201d200c201d4b1b222ead420c7e2205422088a70d182005a722284100480d180240024020140d0020281028212d0c010b202d201c2028102c212d0b202d450d06202d212c0b202c201c6a22142029360200201441046a2006ad2205422086200584370200200c41026a210c201c410c6a211c201d2114202f201d470d000b0b202c450d06202b212a202f211d202e2129202d2128202c2114202b211c202b210c20200d080c070b02402014450d004100210603400240202c20066a221d41046a280200450d00201d280200102a0b201c2006410c6a2206470d000b0b202e450d05202d102a0c050b200641041037000b200641011037000b202841041037000b41a08ac1002000200b1034000b202b41011037000b202b450d002020102a0b410021202016212f2017212e2013212d2019212c2012212b2021212a2022211d20232129200d212820112114200e211c200f210c0b2001450d010b2004102a0b024020200d00410221060c030b10fb012121200241003602b001200242013703a80102400240024002400240410410282201450d0020024284808080c0003702ac01200220013602a80120012003360000201c200241a8016a10b4010240024020022802ac01220420022802b00122016b201c490d0020022802a80121040c010b2001201c6a22062001490d10200441017422162006201620064b1b22064100480d100240024020040d002006102821040c010b20022802a80120042006102c21040b2004450d02200220063602ac01200220043602a8010b20022001201c6a3602b001200420016a2020201c109a051a201d200241a8016a10b401201d450d022014201d410c6c6a211220142104034020042802002113200441086a2802002201200241a8016a10b4010240024020022802ac01221620022802b00122066b2001490d0020022802a80121170c010b200620016a22172006490d11201641017422192017201920174b1b22194100480d110240024020160d002019102821170c010b20022802a80120162019102c21170b2017450d05200220193602ac01200220173602a801201921160b2002200620016a22193602b001201720066a20132001109a051a2004410c6a22042012470d000c050b0b410441011037000b200641011037000b20022802ac01211620022802b00121190c010b201941011037000b02400240201620196b4104490d0020022802a80121010c010b201941046a22012019490d0b201641017422042001200420014b1b22044100480d0b0240024020160d002004102821010c010b20022802a80120162004102c21010b2001450d04200220043602ac01200220013602a801200421160b2002201941046a22043602b001200120196a202136000002400240201620046b41034d0d00201621060c010b200441046a22062004490d0b201641017422172006201720064b1b22064100480d0b0240024020160d002006102821010c010b200120162006102c21010b2001450d05200220063602ac01200220013602a8010b200120046a2015360000200241e9dabdf3063602cc03202542003703002026420037030020274200370300200241a8016a41206a4200370300200241a8016a41186a4200370300200241a8016a41106a4200370300200241a8016a41086a4200370300200242003703a8010240200241cc036a200a20004105746a2001201941086a200241a8016a101e0d00200241e8006a41086a2200201a41086a290000370300200241e8006a41106a2204201a41106a290000370300200241e8006a41186a2216201a41186a290000370300200241e8006a41206a2217201a41206a290000370300200241e8006a41286a2213201a41286a290000370300200241e8006a41306a2219201a41306a290000370300200241e8006a41376a2212201a41376a2900003700002002201a29000037036820022d00a8012122200241286a41086a22232000290300370300200241286a41106a22002004290300370300200241286a41186a22042016290300370300200241286a41206a22162017290300370300200241286a41286a22172013290300370300200241286a41306a22132019290300370300200241286a41376a221920122900003700002002200229036837032802402006450d002001102a0b201b2002290328370000201b41086a2023290300370000201b41106a2000290300370000201b41186a2004290300370000201b41206a2016290300370000201b41286a2017290300370000201b41306a2013290300370000201b41376a2019290000370000200220223a00e802200220153602e402200220213602e0022002201d3602dc02200220293602d802200220283602d4022002201c3602d0022002200c3602cc02200220203602c802200220033602c402200241123602c0022002420237039002200241e8006a200241a8016a108704200228026c2100200228026822042002280270101f210102402000450d002004102a0b2024106a20010d02410110282200450d06200041013a0000200041014105102c2200450d07201541016a211520002003360001410141838ac100411c2000410510202000102a202f2116202e2117202d2113202c2119202b2112202a2121201d2122202921232028210d20142111201c210e200c210f20072018470d010c090b0b02402006450d002001102a0b0240200c450d002020102a0b0240201d450d00201d410c6c210003400240201441046a280200450d002014280200102a0b2014410c6a2114200041746a22000d000b0b410121062029450d012028102a0c010b410321060b02402010450d002008102a0b0240200228021c450d00200a102a0b412e2104419396c6002100200241186a2101024002400240024020060e0400010203000b412d210441e695c6002100200241286a21010c020b411f210441c795c6002100200241e8006a21010c010b419995c6002100200241a8016a21010b200120043602042001200036020020002004100b0c060b200441011037000b200641011037000b410141011037000b410541011037000b1036000b02402010450d002008102a0b200228021c450d00200a102a0b200241d0036a240042010f0b1031000bcb06020d7f037e230041e0006b22012400200141e9dabdf306360208410021022001410036020c200141086a2001410c6a102621032001200128020c360214200120033602102001200141106a106c2001280204210441002105024002400240024020012802000d00200128021422034160712206417f4c0d0202400240200341057622070d00410121050c010b200610282205450d020b2004450d0041002108034020032109200141003a00582008220a41016a2108410021030240024002400240034020092003460d01200141386a20036a200128021022062d00003a00002001200641016a3602102001200341016a22063a00582006210320064120470d000b200141186a41186a220b200141386a41186a290300370300200141186a41106a220c200141386a41106a290300370300200141186a41086a220d200141386a41086a290300370300200120012903383703182007200a470d03200a41017422032008200320084b1b220741ffffff3f712007470d082007410574220341004e0d010c080b200141003602140240200341ff0171450d00200141003a00580b2007450d012005102a0c010b02400240200a0d002003102821050c010b2005200a4105742003102c21050b20050d01200341011037000b410021050c020b200920066b21032005200a4105746a220a2001290318370000200a41186a200b290300370000200a41106a200c290300370000200a41086a200d29030037000020082004470d000b2001200920066b3602140b4101210a2005410120051b21084100210302402004410020051b2206450d0020064105742203410575220241ffffff3f712002470d03200241057422094100480d03024020091028220a0d00200941011037000b200820036a210420064105742109200a2103200821060340200641086a290000210e200641106a290000210f20062900002110200341186a200641186a290000370000200341106a200f370000200341086a200e37000020032010370000200341206a2103200641206a2106200941606a22090d000b200420086b41606a41057641016a21030b02402005450d002007450d002008102a0b20002003360208200020023602042000200a360200200141e0006a24000f0b200641011037000b1036000b1031000bf80303047f027e037f230041306b22022400200241106a41086a220342003703002002420037031041c694c600411b200241106a1008200241086a200329030037030020022002290310370300410021032002410036021020024110200241106a100621040240024002400240024020022802102205417f470d000c010b2002200536022420022004360220200241106a200241206a107720022802102203450d01200229021421062005450d002004102a0b20024100360218200242013703102006420020031b2207422088a72205200241106a10b4012003410820031b210802402005450d002008200541286c6a21092008210503402005200241106a108f01200541206a29030021060240024020022802142204200228021822036b4108490d00200228021021040c010b200341086a220a2003490d0520044101742203200a2003200a4b1b22034100480d050240024020040d002003102821040c010b200228021020042003102c21040b2004450d042002200336021420022004360210200228021821030b2002200341086a360218200420036a20063700002009200541286a2205470d000b0b200235021821062002280210210302402007a7450d002008102a0b200241306a240020064220862003ad840f0b41c4d1c3004133200241286a419cd9c3001038000b200341011037000b1031000b9d0d04047f017e027f017e230041c0016b22022400200241086a41086a220342003703002002420037030841eefbc5004110200241086a1008200241a0016a41086a2003290300370300200220022903083703a0014100210320024100360208200241a0016a4110200241086a10062104024002400240024002400240024002400240024020022802082205417f470d000c010b024020040d000c010b2002200536027c20022004360278200241086a200241f8006a107720022802082203450d01200229020c21062005450d002004102a0b200241086a41086a2205420037030020024200370308419efcc500410f200241086a1008200241a0016a41086a22042005290300370300200220022903083703a001200241f8006a200241a0016a10ef0220022d00782105200241a0016a41186a220720024191016a290000370300200241a0016a41106a220820024189016a290000370300200420024181016a290000370300200220022900793703a0012006420020031b21062003410820031b21030240024020054101460d00200241d8006a41186a4200370300200241d8006a41106a4200370300200241d8006a41086a4200370300200242003703580c010b200241d8006a41186a2007290300370300200241d8006a41106a2008290300370300200241d8006a41086a2004290300370300200220022903a0013703580b2002412c6a2006370200200241086a41186a42043703002002413c6a200241d8006a41086a290300370200200241c4006a200241e8006a290300370200200241cc006a200241d8006a41186a2903003702002002200336022820024201370318200242c801370310200242b81737030820022002290358370234200241013a0054200241003602800120024201370378410810282203450d012002410836027c2002200228028001220441086a3602800120022003360278200320046a42b8173700002002290310210602400240200228027c220420022802800122036b4108490d00200228027821040c010b200341086a22052003490d08200441017422032005200320054b1b22034100480d080240024020040d002003102821040c010b200228027820042003102c21040b2004450d032002200336027c2002200436027820022802800121030b2002200341086a36028001200420036a20063700002002290318210602400240200228027c220420022802800122036b4108490d00200228027821040c010b200341086a22052003490d08200441017422032005200320054b1b22034100480d080240024020040d002003102821040c010b200228027820042003102c21040b2004450d042002200336027c2002200436027820022802800121030b2002200341086a36028001200420036a20063700002002290320210602400240200228027c220420022802800122036b4108490d00200228027821040c010b200341086a22052003490d08200441017422032005200320054b1b22034100480d080240024020040d002003102821040c010b200228027820042003102c21040b2004450d052002200336027c2002200436027820022802800121030b2002200341086a36028001200420036a200637000020022802282104200241086a41286a2802002203200241f8006a10b40102402003450d002004200341286c6a210803402004200241f8006a108f01200441206a290300210602400240200228027c220520022802800122036b4108490d00200228027821050c010b200341086a22072003490d0a200541017422032007200320074b1b22034100480d0a0240024020050d002003102821050c010b200228027820052003102c21050b2005450d082002200336027c2002200536027820022802800121030b2002200341086a36028001200520036a20063700002008200441286a2204470d000b0b200241346a200241f8006a10f10202400240200228027c2002280280012203460d00200228027821040c010b200341016a22042003490d08200341017422052004200520044b1b22054100480d080240024020030d002005102821040c010b200228027820032005102c21040b2004450d072002200536027c2002200436027820022802800121030b2002200341016a36028001200420036a20022d00543a00002002350280012106200235027821090240200228022c450d002002280228102a0b200241c0016a240020064220862009840f0b41c4d1c3004133200241d8006a419cd9c3001038000b410841011037000b200341011037000b200341011037000b200341011037000b200341011037000b200541011037000b1031000baa0607017f017e077f017e027f017e027f230041c0006b2202240042002103200241086a2204420037030020024200370300419695c400411720021008200241206a41086a20042903003703002002200229030037032020024100360200200241206a411020021006210502400240024002400240024020022802002204417f460d0020022004360234200220053602302002200241306a107c20022802002206450d02200229020421032004450d012005102a0c010b410121060b41002107024002402003422088a7220441057422080d00410421094100210a0c010b2008410575220aad420c7e220b422088a70d04200ba722054100480d04200510282209450d020b2003a7210c02402004450d00200841606a210d20092105200621040340200441086a2900002103200441106a290000210b2004290000210e200241186a200441186a290000370300200241106a200b370300200241086a20033703002002200e370300200241206a2002108b04200541086a200241206a41086a280200360200200520022903203702002005410c6a2105200441206a2104200841606a22080d000b200d41057641016a21070b0240200c450d002006102a0b20024100360208200242013703002007200210b4010240024020070d002002280208210d200228020021060c010b20092007410c6c6a210f2009210503402005280200210c200541086a2802002204200210b4010240024020022802042206200228020822086b2004490d00200228020021060c010b200820046a220d2008490d0620064101742210200d2010200d4b1b220d4100480d060240024020060d00200d102821060c010b20022802002006200d102c21060b2006450d052002200d360204200220063602000b2002200820046a220d360208200620086a200c2004109a051a2005410c6a2205200f470d000b2007410c6c21052009210403400240200441046a280200450d002004280200102a0b2004410c6a2104200541746a22050d000b0b0240200a450d002009102a0b200241c0006a2400200dad4220862006ad840f0b41c4d1c3004133200241386a419cd9c3001038000b200541041037000b200d41011037000b1031000baf1905047f017e057f037e3c7f230041d0016b22022400024002402001450d00200220003602100c010b200241013602100b20022001360214200241086a200241106a106c024002400240024002400240024002400240024002400240024020022802080d0020022802142201200228020c2200490d002000417f4c0d010240024020000d00410121030c010b2000102e2203450d032003200228021022042000109a051a2002200120006b3602142002200420006a3602100b2003450d0020024188016a41086a220142003703002002420037038801419695c400411720024188016a1008200241e8006a41086a200129030037030020022002290388013703682002410036028801200241e8006a411020024188016a10062101024002402002280288012204417f460d002001450d002002200436025c2002200136025820024188016a200241d8006a107c2002280288012205450d05200229028c0121062004450d012001102a0c010b41012105420021060b200241d8006a109d044100210702402006422088a72201450d00200520014105746a21082002280258220920022802604105746a210a2005210b0340200b41086a290000210c200b41106a290000210d200b290000210e20024188016a41186a200b41186a29000037030020024188016a41106a200d37030020024188016a41086a200c3703002002200e37038801200b41206a210b20092101024003400240200a20016b41e0004b0d0002402001200a460d00034020024188016a2001460d04200120024188016a4120109c05450d04200a200141206a2201470d000b0b200b2008470d030c040b200120024188016a460d01200120024188016a4120109c05450d01200141206a220420024188016a460d01200420024188016a4120109c05450d01200141c0006a220420024188016a460d01200420024188016a4120109c05450d01200141e0006a220420024188016a460d0120014180016a2101200420024188016a4120109c050d000b0b0b200241e8006a41186a20024188016a41186a290300220c370300200241386a41086a20024188016a41086a290300370300200241386a41106a20024188016a41106a290300370300200241386a41186a200c3703002002200229038801370338410121070b2006a721010240200228025c450d002002280258102a0b02402001450d002005102a0b200241e8006a41186a2201200241386a41186a290300370300200241e8006a41106a2204200241386a41106a290300370300200241e8006a41086a220b200241386a41086a290300370300200220022903383703682007450d0b200241186a41186a2001290300370300200241186a41106a2004290300370300200241186a41086a200b29030037030020022002290368370318200241e9dabdf306360268200241c0016a4200370300200241b8016a4200370300200241b0016a4200370300200241a8016a420037030020024188016a41186a420037030020024188016a41106a420037030020024188016a41086a4200370300200242003703880102400240200241e8006a200241186a2003200020024188016a101e450d00410021010c010b4101210120022d00c701210f20022d00c601211020022d00c501211120022d00c401211220022d00c301211320022d00c201211420022d00c101211520022d00c001211620022d00bf01211720022d00be01211820022d00bd01211920022d00bc01211a20022d00bb01211b20022d00ba01211c20022d00b901211d20022d00b801211e20022d00b701211f20022d00b601212020022d00b501212120022d00b401212220022d00b301212320022d00b201212420022d00b101212520022d00b001212620022d00af01212720022d00ae01212820022d00ad01212920022d00ac01212a20022d00ab01212b20022d00aa01212c20022d00a901212d20022d00a801212e20022d00a701212f20022d00a601213020022d00a501213120022d00a401213220022d00a301213320022d00a201213420022d00a101213520022d00a001213620022d009f01213720022d009e01213820022d009d01213920022d009c01213a20022d009b01213b20022d009a01213c20022d009901213d20022d009801213e20022d009701213f20022d009601214020022d009501214120022d009401214220022d009301214320022d009201214420022d009101214520022d009001214620022d008f01214720022d008e01214820022d008d01214920022d008c01214a20022d008b01210820022d008a01210920022d008901210720022d00880121050b20024188016a41186a2204200241186a41186a29030037030020024188016a41106a220b200241186a41106a29030037030020024188016a41086a220a200241186a41086a29030037030020022002290318370388012001450d0b200241e8006a41186a20042903002206370300200241e8006a41106a200b290300220c370300200241e8006a41086a200a290300220d3703002002200229038801220e37036820042006370300200b200c370300200a200d3703002002200e37038801410110282201450d04200120053a0000200141014102102c2201450d05200120073a0001200141024104102c2201450d06200120083a0003200120093a0002200141044108102c2201450d07200120473a0007200120483a0006200120493a00052001204a3a0004200141084110102c2201450d082001203f3a000f200120403a000e200120413a000d200120423a000c200120433a000b200120443a000a200120453a0009200120463a0008200141104120102c2201450d092001202f3a001f200120303a001e200120313a001d200120323a001c200120333a001b200120343a001a200120353a0019200120363a0018200120373a0017200120383a0016200120393a00152001203a3a00142001203b3a00132001203c3a00122001203d3a00112001203e3a00102001412041c000102c2201450d0a2001200f3a003f200120103a003e200120113a003d200120123a003c200120133a003b200120143a003a200120153a0039200120163a0038200120173a0037200120183a0036200120193a00352001201a3a00342001201b3a00332001201c3a00322001201d3a00312001201e3a00302001201f3a002f200120203a002e200120213a002d200120223a002c200120233a002b200120243a002a200120253a0029200120263a0028200120273a0027200120283a0026200120293a00252001202a3a00242001202b3a00232001202c3a00222001202d3a00212001202e3a0020200241386a20024188016a108b042002280240210b200228023c2109200228023821050c0c0b200241f4006a41043602002002419c016a41023602002002420237028c01200241bca7c400360288012002410436026c200241e0a9c4003602682002410036023c200241b8aec6003602382002200241e8006a360298012002200241386a36027020024188016a41cca7c400103e000b1036000b200041011037000b41c4d1c3004133200241c8016a419cd9c3001038000b410141011037000b410241011037000b410441011037000b410841011037000b411041011037000b412041011037000b41c00041011037000b410021010b0240024002400240410110282204450d00200242818080801037028c0120022004360288010240024020010d00200441003a000042808080801021060c010b200441013a000041c00020024188016a10b40102400240200228028c01220720022802900122046b41c000490d00200441c0006a210a20022802880121070c010b200441c0006a220a2004490d0520074101742208200a2008200a4b1b22084100480d050240024020070d002008102821070c010b20022802880120072008102c21070b2007450d032002200836028c0120022007360288010b200720046a220441086a200141086a290000370000200441106a200141106a290000370000200441186a200141186a290000370000200441206a200141206a290000370000200441286a200141286a290000370000200441306a200141306a290000370000200441386a200141386a2900003700002002200a3602900120042001290000370000200b20024188016a10b40102400240200228028c012204200228029001220a6b200b490d0020022802880121040c010b200a200b6a2207200a490d05200441017422082007200820074b1b22074100480d050240024020040d002007102821040c010b20022802880120042007102c21040b2004450d042002200736028c0120022004360288010b2002200a200b6a2207360290012004200a6a2005200b109a051a2001102a2007ad42208621062009450d002005102a0b02402000450d002003102a0b200241d0016a240020062004ad840f0b410141011037000b200841011037000b200741011037000b1031000baf0e04077f027e047f077e23004190026b22022400024002402001450d00200220003602200c010b200241013602200b20022001360224200241186a200241206a106c024002400240024020022802180d0020022802242201200228021c2203490d000240024002402003417f4c0d000240024020030d00410121040c010b2003102e2204450d022004200228022022002003109a051a2002200120036b3602242002200020036a3602200b2004450d03200241106a200241206a106c20022802100d052002280224220120022802142200490d052000417f4c0d000240024020000d00410121050c010b2000102e2205450d032005200228022022062000109a051a2002200120006b3602242002200620006a3602200b2005450d05200241086a200241206a106c024020022802080d0020022802242206200228020c2201490d002001417f4c0d010240024020010d00410121070c010b2001102e2207450d062007200228022022082001109a051a2002200620016b3602242002200820016a3602200b2007450d002001ad2209422086200984210941002101200241003a00c8012000ad220a422086200a84220a422088a72108200521000240024002400240034020082001460d0120024188016a20016a20002d00003a00002002200141016a22063a00c801200041016a210020062101200641c000470d000b200241d0016a41386a220120024188016a41386a290300370300200241d0016a41306a220020024188016a41306a290300370300200241d0016a41286a220820024188016a41286a290300370300200241d0016a41206a220b20024188016a41206a290300370300200241d0016a41186a220c20024188016a41186a290300370300200241d0016a41106a220d20024188016a41106a290300370300200241d0016a41086a220e20024188016a41086a29030037030020022002290388013703d001200641ff017141c000490d02200241c8006a41386a22062001290300370300200241c8006a41306a2000290300220f370300200241c8006a41286a20082903002210370300200241c8006a41206a200b2903002211370300200241c8006a41186a200c2903002212370300200241c8006a41106a200d2903002213370300200241c8006a41086a200e2903002214370300200220022903d00122153703482000200f37030020082010370300200b2011370300200c2012370300200d2013370300200e201437030020012006290300370300200220153703d00141002101200241003a00a8012009422088a7210820072100034020082001460d0220024188016a20016a20002d00003a00002002200141016a22063a00a801200041016a21002006210120064120470d000b200241286a41186a220120024188016a41186a2200290300370300200241286a41106a220620024188016a41106a2208290300370300200241286a41086a220b20024188016a41086a220c290300370300200220022903880137032820024188016a41386a200241d0016a41386a29030037030020024188016a41306a200241d0016a41306a29030037030020024188016a41286a200241d0016a41286a29030037030020024188016a41206a200241d0016a41206a2903003703002000200241d0016a41186a2903003703002008200241d0016a41106a290300370300200c200241d0016a41086a290300370300200220022903d00137038801200241c8006a41186a2001290300370300200241c8006a41106a2006290300370300200241c8006a41086a200b290300370300200220022903283703482004200320024188016a200241c8006a100a4521000c030b200141ff0171450d01200241003a00c8010c010b200141ff0171450d00200241003a00a8010b410021000b410110282201450d07200120003a000002402009a7450d002007102a0b0240200aa7450d002005102a0b02402003450d002004102a0b20024190026a24002001ad428080808010840f0b200241dc016a41043602002002419c016a41023602002002420237028c01200241bca7c40036028801200241043602d401200241eca9c4003602d0012002410036024c200241b8aec6003602482002200241d0016a360298012002200241c8006a3602d80120024188016a41cca7c400103e000b1036000b200341011037000b200041011037000b200241dc016a41043602002002419c016a41023602002002420237028c01200241bca7c40036028801200241043602d401200241eca9c4003602d0012002410036024c200241b8aec6003602482002200241d0016a360298012002200241c8006a3602d80120024188016a41cca7c400103e000b200141011037000b200241dc016a41043602002002419c016a41023602002002420237028c01200241bca7c40036028801200241043602d401200241eca9c4003602d0012002410036024c200241b8aec6003602482002200241d0016a360298012002200241c8006a3602d80120024188016a41cca7c400103e000b410141011037000be30503037f047e017f230041a0016b2202240041002103200241003a00482000410120011b2104024002400240024002400240034020012003460d01200241286a20036a200420036a2d00003a00002002200341016a22003a00482000210320004120470d000b200241086a41186a200241286a41186a22002903002205370300200241086a41106a200241286a41106a22012903002206370300200241086a41086a200241286a41086a22042903002207370300200220022903282208370308200241d0006a41186a2005370300200241d0006a41106a2006370300200241d0006a41086a200737030020022008370350411310282203450d03200341002900cef0423700002003410f6a41002800ddf042360000200341086a41002900d6f04237000020024293808080b002370294012002200336029001200241d0006a20024190016a108f01200228029801210320022802900121092000420037030020014200370300200442003703002002420037032820092003200241286a1000200241f0006a41186a2000290300370300200241f0006a41106a2001290300370300200241f0006a41086a2004290300370300200220022903283703700240200228029401450d00200228029001102a0b20024100360228200241f0006a4120200241286a1006210320022802282200417f470d01410021000c020b0240200341ff0171450d00200241003a00480b2002413c6a4102360200200241fc006a41043602002002420237022c200241bca7c40036022820024104360274200241fca9c40036027020024100360254200241b8aec6003602502002200241f0006a3602382002200241d0006a360278200241286a41cca7c400103e000b024020030d00410021000c010b20004104490d02200328000021002003102a0b410410282203450d0220032000360000200241a0016a24002003ad4280808080c000840f0b411341011037000b41c4d1c3004133200241286a419cd9c3001038000b410441011037000b880f03057f037e017f230041c0016b22022400024020010d00410121000b200220003602082002200136020c41002103200241003a00702001417f6a21040340024020012003470d000240200341ff0171450d00200241003a00700b200241e4006a41023602002002419c016a410436020020024202370254200241bca7c400360250200241043602940120024194aac4003602900120024100360234200241b8aec600360230200220024190016a3602602002200241306a36029801200241d0006a41cca7c400103e000b200241d0006a20036a200020036a22052d00003a00002002200541016a3602082002200341016a22053a00702002200436020c2004417f6a21042005210320054120470d000b200241106a41086a200241d0006a41086a290300370300200241106a41106a200241d0006a41106a290300370300200241106a41186a200241d0006a41186a2903003703002002200229035037031041002103200241003a0070200120056b2106200020056a2100417f21010340024020062003470d000240200341ff0171450d00200241003a00700b200241e4006a41023602002002419c016a410436020020024202370254200241bca7c400360250200241043602940120024194aac4003602900120024100360234200241b8aec600360230200220024190016a3602602002200241306a36029801200241d0006a41cca7c400103e000b200241d0006a20036a200020036a22052d00003a00002002200420036b36020c2002200541016a3602082002200341016a22053a00702001417f6a21012005210320054120470d000b200241306a41086a200241d0006a41086a290300370300200241306a41106a200241d0006a41106a290300370300200241306a41186a200241d0006a41186a290300370300200220022903503703300240024002400240024002400240024002400240024002400240200420056b220441016a4110490d002002200020056a220341106a3602082002200441716a220536020c20054108490d0220032900002107200341086a29000021082002200441696a36020c2002200341186a360208200341106a29000021092002200241086a106c20022802000d0c200228020c2205200228020422034f0d010c0c0b2002419c016a4104360200200241e4006a410236020020024202370254200241bca7c400360250200241043602940120024194aac400360290012002410036027c200241b8aec600360278200220024190016a3602602002200241f8006a36029801200241d0006a41cca7c400103e000b2003417f4c0d0302400240024020030d00410121044101450d0d0c010b2003102e2204450d012004200228020822012003109a0521002002200520036b36020c2002200120036a3602082000450d0c0b20024190016a41186a200241106a41186a29030037030020024190016a41106a200241106a41106a29030037030020024190016a41086a200241106a41086a2903003703002002200229031037039001200241d0006a41186a200241306a41186a290300370300200241d0006a41106a200241306a41106a290300370300200241d0006a41086a200241306a41086a29030037030020022002290330370350200220033602b801200220033602b401200220043602b001200241f8006a20024190016a200241d0006a200720082009200241b0016a10f50320022802784101460d0220024184016a2802002104200241f8006a41086a2802002100200228027c210520022d00880121010c030b200341011037000b2002419c016a4104360200200241e4006a410236020020024202370254200241bca7c400360250200241043602940120024194aac400360290012002410036027c200241b8aec600360278200220024190016a3602602002200241f8006a36029801200241d0006a41cca7c400103e000b0240200228028801450d0020024184016a280200102a0b410021050b200241003602582002420137035041011028210302402005450d002003450d02200242818080801037025420022003360250200341003a0000200341014102102c2203450d03200242828080802037025420022003360250200320013a00012004200241d0006a10b401024020022802542203200228025822016b2004490d00200228025021030c070b0240200120046a22062001490d002003410174220a2006200a20064b1b22064100480d000240024020030d002006102821030c010b200228025020032006102c21030b2003450d0520022006360254200220033602500c070b1031000b2003450d04200242818080801037025420022003360250200341013a000042808080801021070c060b1036000b410141011037000b410241011037000b200641011037000b410141011037000b2002200120046a2206360258200320016a20052004109a051a2006ad42208621072005450d002000450d002005102a0b200241c0016a240020072003ad840f0b2002419c016a4104360200200241e4006a410236020020024202370254200241bca7c400360250200241043602940120024194aac400360290012002410036027c200241b8aec600360278200220024190016a3602602002200241f8006a36029801200241d0006a41cca7c400103e000bc00c03047f017e067f23004180026b220224000240024020010d002002200136020c200241013602080c010b20022001417f6a36020c410121032002200041016a36020820002d0000220141014b0d0041002104410021000240024002400240024002400240024020010e020100010b2002200241086a106c20022802000d07200228020c220120022802042200490d072000417f4c0d010240024020000d00410121040c010b2000102e2204450d032004200228020822052000109a051a2002200120006b36020c2002200520006a3602080b2004450d07200241106a20042000ad22064220862006842206422088a7105420022802104101460d03200241186a280200210520022802142100410021030b2002200536021420022000360210200241e7e485f3063602b001200241d0016a41186a22074200370300200241d0016a41106a22084200370300200241d0016a41086a22094200370300200242003703d00141002101200241106a410020001b210a0240024020000d004100210b0c010b200a41046a280200210c200a280200210b0b200241b0016a200b4101200b1b200c4100200b1b200241d0016a1021200241f0006a41186a2007290300370300200241f0006a41106a2008290300370300200241f0006a41086a2009290300370300200220022903d0013703702002200536021420022000360210200241e2c289ab063602b001200742003703002008420037030020094200370300200242003703d0010240024020000d000c010b200a41046a280200210b200a28020021010b200241b0016a2001410120011b200b410020011b200241d0016a102220024190016a41186a2207200241d0016a41186a220129030037030020024190016a41106a2208200241d0016a41106a220b29030037030020024190016a41086a2209200241d0016a41086a220a290300370300200220022903d00137039001200220053602fc01200220003602f801200241e9dabdf3063602f40120014200370300200b4200370300200a4200370300200242003703d0010240024020000d00410021000c010b200241f8016a410020001b220041046a2802002105200028020021000b200241f4016a2000410120001b2005410020001b200241d0016a1022200241b0016a41186a22002001290300370300200241b0016a41106a2201200b290300370300200241b0016a41086a2205200a290300370300200241106a41086a200241f0006a41086a290300370300200241106a41106a200241f0006a41106a290300370300200241106a41186a200241f0006a41186a290300370300200220022903d0013703b00120022002290370370310200241c8006a2007290300370300200241c0006a2008290300370300200241386a20092903003703002002200229039001370330200241e8006a2000290300370300200241e0006a2001290300370300200241d8006a2005290300370300200220022903b001370350200241003602d801200242013703d001200241106a200241d0016a108f01200241306a200241d0016a108f01200241d0006a200241d0016a108f0120022802d801210020022802d401210a20022802d001210b024020032006a745720d002004102a0b200041046a2201417f4c0d000240024020010d00410121050c010b200110282205450d040b2002410036021820022001360214200220053602102000200241106a10b4010240024020022802142205200228021822016b2000490d00200228021021050c010b200120006a22042001490d06200541017422072004200720044b1b22044100480d060240024020050d002004102821050c010b200228021020052004102c21050b2005450d0520022004360214200220053602100b200520016a200b2000109a051a200120006a21000240200a450d00200b102a0b20024180026a24002000ad4220862005ad840f0b1036000b200041011037000b200220022902143703d001419fdbc0004116200241d0016a41d4c7c0001038000b200141011037000b200441011037000b1031000b200241dc016a4104360200200241246a410236020020024202370214200241bca7c400360210200241043602d4012002419caac4003602d001200241003602b401200241b8aec6003602b0012002200241d0016a3602202002200241b0016a3602d801200241106a41cca7c400103e000b823305087f017e067f037e037f23004180066b220124000240024002400240411210282202450d00200241002900c1ae44370000200241106a41002f00d1ae443b0000200241086a41002900c9ae4437000020014292808080a0023702e404200120023602e0042000200141e0046a108f0120012802e804210220012802e0042100200141a0046a41186a22034200370300200141a0046a41106a22044200370300200141a0046a41086a22054200370300200142003703a00420002002200141a0046a1000200141c8006a41186a2003290300370300200141c8006a41106a2004290300370300200141c8006a41086a2005290300370300200120012903a004370348024020012802e404450d0020012802e004102a0b200141003602e004200141c8006a4120200141e0046a1006210620012802e0042207417f460d022006450d02200120073602e405200120063602e005200141306a200141e0056a109f0120012802300d0120012802e4052202450d0120012002417f6a22033602e405200120012802e005220541016a22043602e00520052d0000220241014b0d01410021080240024020020e020100010b41002102200141003a0080050340024020032002470d00200141003602e405200241ff0171450d04200141003a0080050c040b200141e0046a20026a200520026a220041016a2d00003a00002001200041026a3602e0052001200241016a22003a0080052000210220004120470d000b200141a0046a41086a200141e0046a41086a2903002209370300200141e8016a41186a200141e0046a41186a290300370300200141e8016a41106a200141e0046a41106a290300370300200141e8016a41086a20093703002001200320006b22033602e405200120012903e00422093703a004200120093703e80141012108200520006a41016a21040b20014180046a41186a200141e8016a41186a29030037030020014180046a41106a200141e8016a41106a29030037030020014180046a41086a200141e8016a41086a290300370300200120012903e801370380042003450d0120012003417f6a22033602e4052001200441016a3602e00520042d0000220041014b0d01410021020240024020000e020100010b41002102200141003a0080050340024020032002470d00200141003602e405200241ff0171450d04200141003a0080050c040b200141e0046a20026a200420026a220041016a2d00003a00002001200041026a3602e0052001200241016a22003a0080052000210220004120470d000b200141c0046a41086a200141e0046a41086a2903002209370300200141e8016a41186a200141e0046a41186a290300370300200141e8016a41106a200141e0046a41106a290300370300200141e8016a41086a20093703002001200320006b3602e405200120012903e00422093703c004200120093703e801410121020b200141c0036a41186a2205200141e8016a41186a2200290300370300200141c0036a41106a220a200141e8016a41106a2203290300370300200141c0036a41086a220b200141e8016a41086a2204290300370300200141e0036a41086a220c20014180046a41086a290300370300200141e0036a41106a220d20014180046a41106a290300370300200141e0036a41186a220e20014180046a41186a290300370300200120012903e8013703c00320012001290380043703e003200141a0036a41186a220f200e290300370300200141a0036a41106a220e200d290300370300200141a0036a41086a220d200c290300370300200120012903e0033703a00320014180036a41186a220c200529030037030020014180036a41106a2205200a29030037030020014180036a41086a220a200b290300370300200120012903c00337038003200141e0046a41186a220b200f290300370300200141e0046a41106a220f200e290300370300200141e0046a41086a220e200d290300370300200120012903a0033703e0042000200c290300370300200320052903003703002004200a29030037030020012001290380033703e801200141c0056a41046a2205200141fa026a41046a2f01003b0100200120012801fa023602c00520084102460d01200141d8026a41186a200b290300370300200141d8026a41106a200f290300370300200141d8026a41086a200e290300370300200141b8026a41086a2004290300370300200141b8026a41106a2003290300370300200141b8026a41186a2000290300370300200141b0026a41046a20052f01003b0100200120012903e0043703d802200120012903e8013703b802200120012802c0053602b00202402007450d002006102a0b200141c8006a412010090c030b411241011037000b41c4d1c3004133200141a0046a419cd9c3001038000b410221080b20014188016a41186a2200200141d8026a41186a29030037030020014188016a41106a2203200141d8026a41106a29030037030020014188016a41086a2204200141d8026a41086a290300370300200141e8006a41086a2205200141b8026a41086a290300370300200141e8006a41106a2206200141b8026a41106a290300370300200141e8006a41186a2207200141b8026a41186a290300370300200120012903d80237038801200120012903b802370368200141c8016a41086a220a2004290300370300200141c8016a41106a22042003290300370300200141c8016a41186a2203200029030037030020012001290388013703c801200141a8016a41086a22002005290300370300200141a8016a41106a22052006290300370300200141a8016a41186a22062007290300370300200120012903683703a8010240024020084102460d002001418a026a220720012903a801370100200141f1016a200a290300370000200141f9016a200429030037000020014181026a200329030037000020014192026a20002903003701002001419a026a2005290300370100200141a2026a2006290300370100200120083a00e801200120012903c8013700e901200120023a0089024100210602400240024002400240024002400240200241ff01714101470d00200141e0046a200710ac01200141e0056a41186a200141e0046a41186a22022900002209370300200141e0056a41106a200141e0046a41106a22002900002210370300200141e0056a41086a200141e0046a41086a22032900002211370300200120012900e00422123703e005200220093703002000201037030020032011370300200120123703e004412010282206450d01200620012903e004370000200641186a2002290300370000200641106a2000290300370000200641086a200329030037000020012d00e80121080b0240200841ff01714101460d0020012d0089024101460d03200141c0056a41186a22024200370300200141c0056a41106a22004200370300200141c0056a41086a22034200370300200142003703c00541d3aec400411a200141c0056a1000200141e0046a41186a2002290300370300200141e0046a41106a2000290300370300200141e0046a41086a2003290300370300200120012903c0053703e004200141e0046a412010090c060b200141e0046a200141e8016a41017210ac01200141e0056a41186a200141e0046a41186a22022903002209370300200141e0056a41106a200141e0046a41106a22002903002210370300200141e0056a41086a200141e0046a41086a22032903002211370300200120012903e00422123703e005200220093703002000201037030020032011370300200120123703e004412010282208450d01200820012903e004370000200841186a2002290300370000200841106a2000290300370000200841086a2003290300370000200141003602e00420084120200141e0046a1006210720012802e004220b417f460d032007450d032001200b360284042001200736028004200141186a20014180046a109f012001290318a70d042001280284042202450d04200141286a29030021092001290320211020012002417f6a2203360284042001200128028004220541016a22043602800420052d0000220241014b0d044100210a0240024020020e020100010b41002102200141003a0080050340024020032002470d002001410036028404200241ff0171450d07200141003a0080050c070b200141e0046a20026a200520026a220041016a2d00003a00002001200041026a360280042001200241016a22003a0080052000210220004120470d000b200141e0056a41086a200141e0046a41086a290300370300200141e0056a41106a200141e0046a41106a290300370300200141e0056a41186a200141e0046a41186a290300370300200120012903e0043703e0052001200320006b2203360284044101210a200520006a41016a21040b200141c0056a41186a200141e0056a41186a290300370300200141c0056a41106a200141e0056a41106a290300370300200141c0056a41086a200141e0056a41086a290300370300200120012903e0053703c0052003450d0420012003417f6a2203360284042001200441016a3602800420042d0000220241014b0d040240024020020e020100010b41002102200141003a0080050340024020032002470d002001410036028404200241ff0171450d07200141003a0080050c070b200141e0046a20026a200420026a220041016a2d00003a00002001200041026a360280042001200241016a22003a0080052000210220004120470d000b200141a0046a41086a200141e0046a41086a2903002211370300200141e0056a41186a200141e0046a41186a290300370300200141e0056a41106a200141e0046a41106a290300370300200141e0056a41086a20113703002001200320006b36028404200120012903e00422113703a004200120113703e0050b200141c0036a41186a2202200141e0056a41186a2200290300370300200141c0036a41106a2203200141e0056a41106a2204290300370300200141c0036a41086a2205200141e0056a41086a220c290300370300200141e0036a41086a220d200141c0056a41086a290300370300200141e0036a41106a220e200141c0056a41106a290300370300200141e0036a41186a220f200141c0056a41186a290300370300200120012903e0053703c003200120012903c0053703e003200141a0036a41186a2213200f290300370300200141a0036a41106a220f200e290300370300200141a0036a41086a220e200d290300370300200120012903e0033703a00320014180036a41186a200229030037030020014180036a41106a200329030037030020014180036a41086a2005290300370300200120012903c00337038003200141e0046a41186a22032013290300370300200141e0046a41106a2205200f290300370300200141e0046a41086a220d200e290300370300200120012903a0033703e004200141c0056a41046a220e200141fa026a41046a2f01003b0100200120012801fa023602c005200a4102460d0420014189026a21022000200329030037030020042005290300370300200c200d290300370300200141c0046a41046a200e2f01003b0100200120012903e0043703e005200120012802c0053602c0040240200b450d002007102a0b200141f1046a20012903e005370000200141f9046a200141e0056a41086a29030037000020014181056a200141e0056a41106a29030037000020014189056a200141e0056a41186a290300370000200141b6056a200141c4046a2f01003b0100200120103703e0042001200a3a00f004200120012802c0043601b205200120093703e80420014191056a200229000037000020014199056a200241086a290000370000200141a1056a200241106a290000370000200141a9056a200241186a290000370000200141b1056a200241206a2d00003a0000200141003602e805200142013703e0052001200141e0046a3602c005200141c0056a200141e0056a10a301200141e0046a41106a200141e0056a10a90120012802e40521022008412020012802e005220020012802e805100702402002450d002000102a0b2008102a4101210a0c060b412041011037000b412041011037000b200141c0056a41186a22024200370300200141c0056a41106a22004200370300200141c0056a41086a22034200370300200142003703c00541d3aec400411a200141c0056a1000200141e0046a41186a2002290300370300200141e0046a41106a2000290300370300200141e0046a41086a2003290300370300200120012903c0053703e004200141203602e4052001200141e0046a3602e0052007200141e0056a10ff010c020b41e2bbc00041d8001050000b41c4d1c3004133200141a0046a419cd9c3001038000b410021084100210a0b0240024002400240024020060d00410021020c010b200141003602e00420064120200141e0046a1006210720012802e004220b417f460d012007450d012001200b3602bc05200120073602b8052001200141b8056a109f012001290300a70d0520012802bc052202450d05200141106a29030021092001290308211020012002417f6a22033602bc05200120012802b805220541016a22043602b80520052d0000220241014b0d054100210c0240024020020e020100010b41002102200141003a0080050340024020032002470d00200141003602bc05200241ff0171450d08200141003a0080050c080b200141e0046a20026a200520026a220041016a2d00003a00002001200041026a3602b8052001200241016a22003a0080052000210220004120470d000b20014180046a41106a200141e0046a41106a2903002211370300200141e0056a41086a200141e0046a41086a290300370300200141e0056a41106a2011370300200141e0056a41186a200141e0046a41186a2903003703002001200320006b22033602bc05200120012903e0043703e0054101210c200520006a41016a21040b200141c0056a41186a200141e0056a41186a290300370300200141c0056a41106a200141e0056a41106a290300370300200141c0056a41086a200141e0056a41086a290300370300200120012903e0053703c0052003450d0520012003417f6a22033602bc052001200441016a3602b80520042d0000220241014b0d05410021050240024020020e020100010b41002102200141003a0080050340024020032002470d00200141003602bc05200241ff0171450d08200141003a0080050c080b200141e0046a20026a200420026a220041016a2d00003a00002001200041026a3602b8052001200241016a22003a0080052000210220004120470d000b200141c0046a41086a200141e0046a41086a2903002211370300200141e0056a41186a200141e0046a41186a290300370300200141e0056a41106a200141e0046a41106a290300370300200141e0056a41086a20113703002001200320006b3602bc05200120012903e00422113703c004200120113703e005410121050b200141c0036a41186a2204200141e0056a41186a2202290300370300200141c0036a41106a220d200141e0056a41106a2200290300370300200141c0036a41086a220e200141e0056a41086a2203290300370300200141e0036a41086a220f200141c0056a41086a290300370300200141e0036a41106a2213200141c0056a41106a290300370300200141e0036a41186a2214200141c0056a41186a290300370300200120012903e0053703c003200120012903c0053703e003200141a0036a41186a22152014290300370300200141a0036a41106a22142013290300370300200141a0036a41086a2213200f290300370300200120012903e0033703a00320014180036a41186a220f200429030037030020014180036a41106a2204200d29030037030020014180036a41086a220d200e290300370300200120012903c00337038003200141e0046a41186a220e2015290300370300200141e0046a41106a22152014290300370300200141e0046a41086a22142013290300370300200120012903a0033703e0042002200f290300370300200020042903003703002003200d29030037030020012001290380033703e005200141c0056a41046a2204200141fa026a41046a2f01003b0100200120012801fa023602c005200c4102460d05200141d8026a41186a200e290300370300200141d8026a41106a2015290300370300200141d8026a41086a2014290300370300200141b8026a41086a2003290300370300200141b8026a41106a2000290300370300200141b8026a41186a2002290300370300200141b0026a41046a20042f01003b0100200120012903e0043703d802200120012903e0053703b802200120012802c0053602b0020240200b450d002007102a0b20014191056a20053a000020014192056a20012903b8023701002001419a056a200141b8026a41086a290300370100200141a2056a200141b8026a41106a290300370100200141aa056a200141b8026a41186a290300370100200141b6056a200141b4026a2f01003b0100200120103703e004200120012802b0023601b205200120093703e80420014190056a200141e8016a41206a2d00003a000020014188056a200141e8016a41186a290300370300200141e0046a41206a200141e8016a41106a290300370300200141e0046a41186a200141e8016a41086a290300370300200120012903e8013703f004200141003602e805200142013703e0052001200141e0046a3602c005200141c0056a200141e0056a10a301200141e0046a41106a200141e0056a10a90120012802e40521022006412020012802e005220020012802e805100702402002450d002000102a0b2006102a410121020b200a20084572450d010c020b41e2bbc00041d8001050000b2008102a0b2006452002720d002006102a0b20014180066a24000f0b41c4d1c3004133200141a0046a419cd9c3001038000bde3305097f017e077f037e057f230041a0056b22012400024002400240024002400240411210282202450d0020024100290095ae44370000200241106a41002f00a5ae443b0000200241086a410029009dae4437000020014292808080a00237028c042001200236028804200020014188046a108f0120012802900421022001280288042100200141c8036a41186a22034200370300200141c8036a41106a22044200370300200141c8036a41086a22054200370300200142003703c80320002002200141c8036a1000200141186a2003290300370300200141106a2004290300370300200141086a2005290300370300200120012903c8033703000240200128028c04450d00200128028804102a0b20014100360288042001412020014188046a100621032001280288042204417f460d042003450d04200120043602e404200120033602e00420014180056a200141e0046a106d2001280280052206450d02200128028405210720012802e4042202450d0120012002417f6a22053602e404200120012802e004220841016a22093602e00420082d0000220041014b0d01410021020240024020000e020100010b41002102200141003a00a8040340024020052002470d00200141003602e404200241ff0171450d04200141003a00a8040c040b20014188046a20026a200820026a220041016a2d00003a00002001200041026a3602e0042001200241016a22003a00a8042000210220004120470d000b200141c8036a41086a20014188046a41086a290300220a370300200141a0016a41186a20014188046a41186a290300370300200141a0016a41106a20014188046a41106a290300370300200141a0016a41086a200a3703002001200520006b22053602e4042001200129038804220a3703c8032001200a3703a00141012102200820006a41016a21090b200141a8036a41186a200141a0016a41186a290300370300200141a8036a41106a200141a0016a41106a290300370300200141a8036a41086a200141a0016a41086a290300370300200120012903a0013703a8032005450d0120012005417f6a22083602e4042001200941016a3602e00420092d0000220541014b0d01410021000240024020050e020100010b41002100200141003a00a8040340024020082000470d00200141003602e404200041ff0171450d04200141003a00a8040c040b20014188046a20006a200920006a220541016a2d00003a00002001200541026a3602e0042001200041016a22053a00a8042005210020054120470d000b200141e8036a41086a20014188046a41086a290300220a370300200141a0016a41186a20014188046a41186a290300370300200141a0016a41106a20014188046a41106a290300370300200141a0016a41086a200a3703002001200820056b3602e4042001200129038804220a3703e8032001200a3703a001410121000b200141e8026a41186a2205200141a0016a41186a2208290300370300200141e8026a41106a2209200141a0016a41106a220b290300370300200141e8026a41086a220c200141a0016a41086a220d29030037030020014188036a41086a220e200141a8036a41086a29030037030020014188036a41106a220f200141a8036a41106a29030037030020014188036a41186a2210200141a8036a41186a290300370300200120012903a0013703e802200120012903a80337038803200141c8026a41186a22112010290300370300200141c8026a41106a2210200f290300370300200141c8026a41086a220f200e29030037030020012001290388033703c802200141a8026a41186a220e2005290300370300200141a8026a41106a22052009290300370300200141a8026a41086a2209200c290300370300200120012903e8023703a80220014188046a41186a201129030037030020014188046a41106a201029030037030020014188046a41086a200f290300370300200120012903c802370388042008200e290300370300200b2005290300370300200d2009290300370300200120012903a8023703a0010c030b411241011037000b2007450d002006102a0b410221020b024020024102460d0020014188026a41186a20014188046a41186a29030037030020014188026a41106a20014188046a41106a29030037030020014188026a41086a20014188046a41086a290300370300200141e8016a41086a200141a0016a41086a290300370300200141e8016a41106a200141a0016a41106a290300370300200141e8016a41186a200141a0016a41186a290300370300200120012903880437038802200120012903a0013703e801200120012f0180053b01e60102402004450d002003102a0b2001412010090c020b41c4d1c3004133200141a8036a419cd9c3001038000b410221020b200141c0006a41186a220320014188026a41186a290300370300200141c0006a41106a220420014188026a41106a290300370300200141c0006a41086a220520014188026a41086a290300370300200141206a41086a2208200141e8016a41086a290300370300200141206a41106a2209200141e8016a41106a290300370300200141206a41186a220b200141e8016a41186a2903003703002001200129038802370340200120012903e80137032020014180016a41086a220c200529030037030020014180016a41106a2205200429030037030020014180016a41186a220420032903003703002001200129034037038001200141e0006a41086a22032008290300370300200141e0006a41106a22082009290300370300200141e0006a41186a2209200b29030037030020012001290320370360024020024102460d00200141c2016a220b2001290360370100200141a9016a200c290300370000200141b1016a2005290300370000200141b9016a2004290300370000200141ca016a2003290300370100200141d2016a2008290300370100200141da016a2009290300370100200120023a00a00120012001290380013700a101200120003a00c101410021030240024002400240024002400240024002400240200041ff01714101470d0020014188046a200b10ae0120014180056a41186a20014188046a41186a2202290000220a37030020014180056a41106a20014188046a41106a2200290000221237030020014180056a41086a20014188046a41086a2204290000221337030020012001290088042214370380052002200a37030020002012370300200420133703002001201437038804412010282203450d012003200129038804370000200341186a2002290300370000200341106a2000290300370000200341086a200429030037000020012d00a00121020b0240200241ff01714101460d0020012d00c1014101460d03200141e0046a41186a22024200370300200141e0046a41106a22004200370300200141e0046a41086a22044200370300200142003703e00441a7aec400411a200141e0046a100020014188046a41186a200229030037030020014188046a41106a200029030037030020014188046a41086a2004290300370300200120012903e0043703880420014188046a412010090c080b20014188046a200141a0016a41017210ae0120014180056a41186a20014188046a41186a2202290300220a37030020014180056a41106a20014188046a41106a2200290300221237030020014180056a41086a20014188046a41086a2205290300221337030020012001290388042214370380052002200a37030020002012370300200520133703002001201437038804412010282204450d012004200129038804370000200441186a2002290300370000200441106a2000290300370000200441086a200529030037000020014100360288042004412020014188046a10062109200128028804220d417f460d032009450d032001200d3602cc03200120093602c803200141e8036a200141c8036a106d20012802e8032202450d0520012802ec03210c20012802cc032200450d04200141f0036a280200210820012000417f6a220e3602cc03200120012802c803220f41016a22103602c803200f2d0000220041014b0d044100210b0240024020000e020100010b41002100200141003a00a80403400240200e2000470d00200141003602cc03200041ff0171450d07200141003a00a8040c070b20014188046a20006a200f20006a220541016a2d00003a00002001200541026a3602c8032001200041016a22053a00a8042005210020054120470d000b20014180056a41086a20014188046a41086a29030037030020014180056a41106a20014188046a41106a29030037030020014180056a41186a20014188046a41186a2903003703002001200129038804370380052001200e20056b220e3602cc034101210b200f20056a41016a21100b200141e0046a41186a20014180056a41186a290300370300200141e0046a41106a20014180056a41106a290300370300200141e0046a41086a20014180056a41086a29030037030020012001290380053703e004200e450d042001200e417f6a220e3602cc032001201041016a3602c80320102d0000220041014b0d040240024020000e020100010b41002100200141003a00a80403400240200e2000470d00200141003602cc03200041ff0171450d07200141003a00a8040c070b20014188046a20006a201020006a220541016a2d00003a00002001200541026a3602c8032001200041016a22053a00a8042005210020054120470d000b200141a8036a41106a20014188046a41106a290300220a37030020014180056a41086a20014188046a41086a29030037030020014180056a41106a200a37030020014180056a41186a20014188046a41186a2903003703002001200e20056b3602cc032001200129038804370380050b200141e8026a41186a220020014180056a41186a290300370300200141e8026a41106a220520014180056a41106a290300370300200141e8026a41086a220e20014180056a41086a29030037030020014188036a41086a220f200141e0046a41086a29030037030020014188036a41106a2210200141e0046a41106a29030037030020014188036a41186a2211200141e0046a41186a29030037030020012001290380053703e802200120012903e00437038803200141c8026a41186a22152011290300370300200141c8026a41106a22112010290300370300200141c8026a41086a2210200f29030037030020012001290388033703c802200141a8026a41186a2000290300370300200141a8026a41106a2005290300370300200141a8026a41086a200e290300370300200120012903e8023703a80220014188046a41186a201529030037030020014188046a41106a201129030037030020014188046a41086a2010290300370300200120012903c802370388040c060b412041011037000b412041011037000b200141e0046a41186a22024200370300200141e0046a41106a22004200370300200141e0046a41086a22044200370300200142003703e00441a7aec400411a200141e0046a100020014188046a41186a200229030037030020014188046a41106a200029030037030020014188046a41086a2004290300370300200120012903e004370388042001412036028405200120014188046a36028005200b20014180056a10ff010c040b41e2bbc00041d8001050000b200c450d002002102a0b4102210b0b0240200b4102460d00200141c1016a210020014180056a41186a220520014188046a41186a29030037030020014180056a41106a220e20014188046a41106a29030037030020014180056a41086a220f20014188046a41086a290300370300200120012903880437038005200120012f01e0043b01e8030240200d450d002009102a0b20014195046a2001290380053700002001419d046a200f290300370000200141a5046a200e290300370000200141ad046a20052903003700002001200b3a00940420012008360290042001200c36028c042001200236028804200120012f01e8033b01d604200141b5046a2000290000370000200141bd046a200041086a290000370000200141c5046a200041106a290000370000200141cd046a200041186a290000370000200141d5046a200041206a2d00003a000020014100360288052001420137038005200820014180056a10b40120014194046a210502402008450d00200841057421000340200220014180056a108f01200241206a2102200041606a22000d000b0b200520014180056a10a9012001280284052102200441202001280280052200200128028805100702402002450d002000102a0b0240200128028c04450d00200128028804102a0b2004102a410121090c020b41c4d1c3004133200141a8036a419cd9c3001038000b41002104410021090b0240024002400240024020030d00410021020c010b20014100360288042003412020014188046a100621080240024002400240200128028804220b417f460d002008450d002001200b3602dc04200120083602d804200141a8036a200141d8046a106d4200211220012802a8032202450d0220012802ac03211020012802dc042200450d01200141b0036a350200210a20012000417f6a220c3602dc04200120012802d804220d41016a220f3602d804200d2d0000220041014b0d014100210e0240024020000e020100010b41002100200141003a00a80403400240200c2000470d00200141003602dc04200041ff0171450d04200141003a00a8040c040b20014188046a20006a200d20006a220541016a2d00003a00002001200541026a3602d8042001200041016a22053a00a8042005210020054120470d000b200141c8036a41086a20014188046a41086a290300221337030020014180056a41186a20014188046a41186a29030037030020014180056a41106a20014188046a41106a29030037030020014180056a41086a20133703002001200c20056b220c3602dc04200120012903880422133703c80320012013370380054101210e200d20056a41016a210f0b200141e0046a41186a20014180056a41186a290300370300200141e0046a41106a20014180056a41106a290300370300200141e0046a41086a20014180056a41086a29030037030020012001290380053703e004200c450d012001200c417f6a220c3602dc042001200f41016a3602d804200f2d0000220541014b0d01410021000240024020050e020100010b41002100200141003a00a80403400240200c2000470d00200141003602dc04200041ff0171450d04200141003a00a8040c040b20014188046a20006a200f20006a220541016a2d00003a00002001200541026a3602d8042001200041016a22053a00a8042005210020054120470d000b200141e8036a41086a20014188046a41086a290300221237030020014180056a41186a20014188046a41186a29030037030020014180056a41106a20014188046a41106a29030037030020014180056a41086a20123703002001200c20056b3602dc04200120012903880422123703e8032001201237038005410121000b200141e8026a41186a220520014180056a41186a220c290300370300200141e8026a41106a220d20014180056a41106a220f290300370300200141e8026a41086a221120014180056a41086a221529030037030020014188036a41086a2216200141e0046a41086a29030037030020014188036a41106a2217200141e0046a41106a29030037030020014188036a41186a2218200141e0046a41186a29030037030020012001290380053703e802200120012903e00437038803200141c8026a41186a22192018290300370300200141c8026a41106a22182017290300370300200141c8026a41086a2217201629030037030020012001290388033703c802200141a8026a41186a22162005290300370300200141a8026a41106a2205200d290300370300200141a8026a41086a220d2011290300370300200120012903e8023703a80220014188046a41186a201929030037030020014188046a41106a201829030037030020014188046a41086a2017290300370300200120012903c80237038804200c2016290300370300200f20052903003703002015200d290300370300200120012903a80237038005200a422086210a2010ad21120c030b41e2bbc00041d8001050000b2010450d002002102a0b4102210e4200210a0b200e4102460d0120014188026a41186a20014188046a41186a29030037030020014188026a41106a20014188046a41106a29030037030020014188026a41086a20014188046a41086a290300370300200141e8016a41086a220520014180056a41086a290300370300200141e8016a41106a220c20014180056a41106a290300370300200141e8016a41186a220d20014180056a41186a29030037030020012001290388043703880220012001290380053703e801200120012f01e0043b01e601200a20128421120240200b450d002008102a0b200141b5046a20003a0000200141b6046a20012903e801370100200141be046a2005290300370100200141c6046a200c290300370100200141ce046a200d2903003701002001419c046a200141a0016a41086a290300370200200141a4046a200141a0016a41106a290300370200200141ac046a200141a0016a41186a290300370200200141b4046a200141a0016a41206a2d00003a00002001201237028c042001200236028804200120012f01e6013b01d604200120012903a0013702940420014100360288052001420137038005200a422088a7220020014180056a10b40120014194046a210502402000450d00200041057421000340200220014180056a108f01200241206a2102200041606a22000d000b0b200520014180056a10a9012001280284052102200341202001280280052200200128028805100702402002450d002000102a0b0240200128028c04450d00200128028804102a0b2003102a410121020b200920044572450d010c020b41c4d1c3004133200141a8036a419cd9c3001038000b2004102a0b02402003452002720d002003102a0b2006450d002007450d002006102a0b200141a0056a24000b13002000410d360204200041bcafc4003602000b3400200041d9dbc40036020420004100360200200041146a4113360200200041106a41e0dbc400360200200041086a42073702000b09002000410010e6020b6c01027f230041106b22022400200241003602082002420137030002404104102822030d00410441011037000b2003410036000020024284808080c000370204200220033602004100200210b401200041086a200228020836020020002002290300370200200241106a24000b3001017f02404108102822020d00410841011037000b20004288808080800137020420002002360200200242003700000b8e0201037f230041c0006b22022400200241186a4200370300200241106a22034200370300200241086a4200370300200241286a22044100360200200242003703002002420837032020024100360238200242013703302002200236023c2002413c6a200241306a10a3012002200336023c2002413c6a200241306a10a3012002280220210320042802002204200241306a10b40102402004450d00200441306c21040340200341106a200241306a108f012002200336023c200341306a21032002413c6a200241306a10a301200441506a22040d000b0b20002002290330370200200041086a200241306a41086a28020036020002402002280224450d002002280220102a0b200241c0006a24000b7001027f230041306b2202240020024200370310200242003703082002200241086a36021c02404101102822030d00410141011037000b20024201370224200220033602202002411c6a200241206a10a301200041086a200228022836020020002002290320370200200241306a24000b3001017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241043600000b9c0402057f027e230041d0016b220224002002200110b1040240024020022d00004101470d00200241286a41186a200241196a290000370300200241286a41106a200241116a290000370300200241286a41086a200241096a2900003703002002200229000137032802400240410e10282201450d002001410029008aaf44370000200141066a4100290090af443700002002428e808080e00137026c20022001360268200241286a200241e8006a108f012002280270210120022802682103200241f8006a41186a22044200370300200241f8006a41106a22054200370300200241f8006a41086a220642003703002002420037037820032001200241f8006a1000200241c8006a41186a2004290300370300200241c8006a41106a2005290300370300200241c8006a41086a2006290300370300200220022903783703480240200228026c450d002002280268102a0b20024100360278200241c8006a4120200241f8006a100621040240024020022802782203417f470d00410021010c010b2002200336026c20022004360268200241f8006a200241e8006a108a022002280298012201450d0220024190016a29030021072002290388012108200228029c0121052003450d002004102a0b2001450d022005450d032001102a0c030b410e41011037000b41c4d1c3004133200241c8016a419cd9c3001038000b42002108420021070b2000200837030020002007370308200241d0016a24000bb70301057f230041f0006b220224000240410e10282203450d00200341002900fcae44370000200341066a4100290082af443700002002428e808080e001370254200220033602502001200241d0006a108f012002280258210320022802502101200241086a41186a22044200370300200241086a41106a22054200370300200241086a41086a220642003703002002420037030820012003200241086a1000200241306a41186a2004290300370300200241306a41106a2005290300370300200241306a41086a20062903003703002002200229030837033002402002280254450d002002280250102a0b200241086a200241306a412010fd01200241d0006a41086a200241086a41096a290000370300200241d0006a41106a200241086a41116a290000370300200241d0006a41186a200241086a41196a290000370300200220022900093703500240024020022d00084101460d00200041003a00000c010b200041013a000020002002290350370001200041096a200241d8006a290300370000200041116a200241e0006a290300370000200041196a200241e8006a2903003700000b200241f0006a24000f0b410e41011037000b13002000410236020420004184fcc4003602000b3101017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241a0053600000bdf14030d7f077e0b7f23004180046b22042400024002400240024002400240410d10282205450d0020054100290098af44370000200541056a410029009daf443700002004428d808080d0013702ec02200420053602e8022001200441e8026a108f0120042802f002210520042802e8022106200441a8036a41186a22074200370300200441a8036a41106a22084200370300200441a8036a41086a22094200370300200442003703a80320062005200441a8036a100020044198016a41186a200729030037030020044198016a41106a200829030037030020044198016a41086a2009290300370300200420042903a80337039801024020042802ec02450d0020042802e802102a0b200441003602a80320044198016a4120200441a8036a1006210502400240024020042802a8032206417f460d002005450d002006450d0420052d0000220641034f0d042005102a20060e03000201000b200441f0006a200110b10420042d00704101470d06200441b8016a41186a20044189016a290000370300200441b8016a41106a20044181016a290000370300200441b8016a41086a200441f9006a290000370300200420042900713703b801410e10282205450d042005410029008aaf44370000200541066a4100290090af443700002004428e808080e0013702ec02200420053602e802200441b8016a200441e8026a108f0120042802f002210520042802e8022106200441a8036a41186a22074200370300200441a8036a41106a22084200370300200441a8036a41086a22094200370300200442003703a80320062005200441a8036a100020044198016a41186a200729030037030020044198016a41106a200829030037030020044198016a41086a2009290300370300200420042903a80337039801024020042802ec02450d0020042802e802102a0b200441003602a80320044198016a4120200441a8036a100621070240024020042802a8032206417f470d00410021050c010b200420063602cc02200420073602c802200441a8036a200441c8026a108a0220042802c8032205450d06200441a8026a41186a200441a8036a41186a290300370300200441a8026a41106a200441a8036a41106a290300370300200441a8026a41086a200441a8036a41086a290300370300200441e8026a41086a200441d4036a290200370300200441e8026a41106a200441dc036a290200370300200441e8026a41186a200441e4036a29020037030020044188036a200441ec036a29020037030020044190036a200441f4036a280200360200200420042903a8033703a802200420042902cc033703e8022006450d002007102a0b200441c8026a41086a2209200441a8026a41086a290300370300200441c8026a41106a220a200441a8026a41106a290300370300200441c8026a41186a220b200441a8026a41186a290300370300200441a8036a41086a220c200441e8026a41086a2206290300370300200441a8036a41106a220d200441e8026a41106a2207290300370300200441a8036a41186a220e200441e8026a41186a2208290300370300200441a8036a41206a220f200441e8026a41206a290300370300200441a8036a41286a2210200441e8026a41286a280200360200200420042903a8023703c802200420042903e8023703a80302402005450d0020044188026a41186a200b29030037030020044188026a41106a200a29030037030020044188026a41086a2009290300370300200441d8016a41086a200c290300370300200441d8016a41106a200d290300370300200441d8016a41186a200e290300370300200441d8016a41206a200f290300370300200441d8016a41286a2010280200360200200420042903c80237038802200420042903a8033703d8010b2008200441b8016a41186a2903003703002007200441b8016a41106a2903003703002006200441b8016a41086a290300370300200420042903b8013703e8022005450d06200441306a41206a220c2004290388022211370300200441a8036a41186a2206200441e8026a41186a220d2903002212370300200441a8036a41106a2207200441e8026a41106a220e2903002213370300200441a8036a41086a2208200441e8026a41086a220f2903002214370300200441a8036a41286a20044188026a41086a2903002215370300200441a8036a41306a20044188026a41106a2903002216370300200441a8036a41386a20044188026a41186a2903002217370300200441306a41386a22102017370300200441306a41306a22182016370300200441306a41286a22192015370300200441306a41186a22092012370300200441306a41106a220a2013370300200441306a41086a220b2014370300200420042903e80222123703a803200420113703c80320042012370330200441286a221a200441d8016a41286a280200360200200441206a221b200441d8016a41206a290300370300200441186a221c200441d8016a41186a221d290300370300200441106a221e200441d8016a41106a221f290300370300200441086a2220200441d8016a41086a2221290300370300200420042903d801370300200441e8026a41386a22222010290300370300200441e8026a41306a22102018290300370300200441e8026a41286a22182019290300370300200441e8026a41206a2219200c290300370300200d2009290300370300200e200a290300370300200f200b290300370300200420042903303703e802201d2009290300370300201f200a2903003703002021200b290300370300200420042903303703d801200620222903003703002007201029030037030020082018290300370300200420053602c803200420192903003703a803200441cc036a22052004290300370200200441d4036a2020290300370200200441dc036a201e290300370200200441e4036a201c290300370200200441ec036a201b290300370200200441f4036a201a2802003602002006290300211120072007290300221220027c22133703002006201120037c2013201254ad7c37030020082903002111200420042903a803221220027c22133703a8032008201120037c2013201254ad7c370300200441f0006a20012002200310a50220043502702102200441f0006a41106a2903002111200441f0006a41086a2903002103200441d8016a200441a8036a10b50402402005280200450d0020042802c803102a0b200242018521020c070b200441a8036a200110b10420042d00a8034101470d0520044180036a200441c1036a290000370300200441e8026a41106a200441b9036a290000370300200441e8026a41086a200441b1036a290000370300200420042900a9033703e802200441306a200441e8026a2002200310a50220043502304201852102200441306a41106a2903002111200441306a41086a29030021030c060b200441a8036a20012002200310a50220043502a8034201852102200441b8036a2903002111200441b0036a29030021030c050b410d41011037000b41c4d1c3004133200441f8036a419cd9c3001038000b410e41011037000b41c4d1c3004133200441f8036a419cd9c3001038000b420021020b2000200337030820002002370300200041106a201137030020044180046a24000bc80201057f230041e0006b22022400200242f3e885db96cddbb320370308200241086a2001412c6a2001290300200141086a290300417f410f10a9020240410e10282203450d002003410029008aaf44370000200341066a4100290090af443700002002428e808080e001370234200220033602302000200241306a108f012002280238210320022802302100200241c0006a41186a22044200370300200241c0006a41106a22054200370300200241c0006a41086a220642003703002002420037034020002003200241c0006a1000200241106a41186a2004290300370300200241106a41106a2005290300370300200241106a41086a20062903003703002002200229034037031002402002280234450d002002280230102a0b200241203602442002200241106a3602402001200241c0006a10b604200241e0006a24000f0b410e41011037000bce0101027f230041106b2202240020024100360208200242013703002000412c6a2002108f012002200036020c2002410c6a200210a3012002200041106a36020c2002410c6a200210a30120002802202103200041286a2802002200200210b40102402000450d002003200041186c6a210003402002200336020c2002410c6a200210a301200341106a200210a0012000200341186a2203470d000b0b2002280204210320012802002001280204200228020022002002280208100702402003450d002000102a0b200241106a24000bf30901047f230041e0026b22052400200541a0016a41086a22064200370300200542003703a00141a990c6004119200541a0016a1008200541086a41086a2006290300370300200520052903a00137030841002106200541003602a001200541086a4110200541a0016a10062107024002400240024020052802a0012208417f460d002007450d0020084104490d01200728000021062007102a0b02402006417f6a220720064d0d00200541133602080c020b200541086a200710ca0320052802084113460d01200541a0016a200541086a419801109a051a20052802a8022107200541a0016a106a200720014d0d01200041828ac50036020420004101360200200041086a41c7003602002002106a0c020b41c4d1c3004133200541a0016a419cd9c3001038000b200541a0016a41086a22074200370300200542003703a00141a990c6004119200541a0016a1008200541086a41086a2007290300370300200520052903a0013703082005200641016a3602a001200541086a4110200541a0016a41041007200541a0016a2002418801109a051a200520033a00b002200520043602ac02200520013602a802024002400240024002400240411a10282207450d00200741186a41002f00ce88453b0000200741106a41002900c68845370000200741086a41002900be8845370000200741002900b688453700002007411a4134102c2207450d012007200636001a200541086a41186a22014200370300200541086a41106a22024200370300200541086a41086a22044200370300200542003703082007411e200541086a1000200541b8026a41186a2001290300370300200541b8026a41106a2002290300370300200541b8026a41086a2004290300370300200520052903083703b8022007102a200541003602102005420137030820052802a8022101410410282207450d022005410436020c20052005280210220241046a36021020052007360208200720026a2001360000200541a0016a200541086a10eb01024020052d00b002220741024b0d00024002400240024020070e03000102000b410021010c020b410121010c010b410221010b200520013a00df0202400240200528020c20052802102207460d00200528020821020c010b200741016a22022007490d07200741017422042002200420024b1b22044100480d070240024020070d002004102821020c010b200528020820072004102c21020b2002450d052005200436020c20052002360208200528021021070b2005200741016a360210200220076a20013a00000b20052802ac02210202400240200528020c2201200528021022076b4104490d00200528020821010c010b200741046a22042007490d06200141017422072004200720044b1b22074100480d060240024020010d002007102821010c010b200528020820012007102c21010b2001450d052005200736020c20052001360208200528021021070b2005200741046a360210200120076a2002360000200528020c2107200541b8026a4120200528020822012005280210100702402007450d002001102a0b200541a0016a106a200541ac016a2006360200200541a9016a20033a0000200541a8016a41033a0000200541053a00a00141014100200541a0016a10cc0120004100360200200020063602040c060b411a41011037000b413441011037000b410441011037000b200441011037000b200741011037000b1031000b200541e0026a24000bfe0201047f230041e0006b2202240002400240411310282203450d002003410f6a41002800e38945360000200341086a41002900dc8945370000200341002900d48945370000200341134126102c2203450d0120032001360013200241c0006a41186a22044200370300200241c0006a41106a22054200370300200241c0006a41086a220142003703002002420037034020034117200241c0006a1000200241186a2004290300370300200241106a2005290300370300200241086a2001290300370300200220022903403703002003102a200241c0006a200210e003200241306a41086a2001290300370300200241206a41086a200241c0006a411c6a2802003602002002200229034037033020022002290254370320024020022802502203450d002000200229033037030020002002290320370214200041086a200241306a41086a2903003703002000411c6a200241206a41086a2802003602000b20002003360210200241e0006a24000f0b411341011037000b412641011037000b130020004111360204200041cc8bc5003602000b3400200041f9aac50036020420004100360200200041146a410f360200200041106a4184abc500360200200041086a42093702000b4f01027f230041106b2202240002404101102822030d00410141011037000b200341003a0000200041086a4101360200200241013602042002200336020020002002290300370200200241106a24000b5b01027f23004190016b22022400200241133602000240410110282203450d00200341003a0000200042818080801037020420002003360200024020022802004113460d002002106a0b20024190016a24000f0b410141011037000bfd0201057f230041c0006b22022400200241206a4200370300200241186a4200370300200241086a41086a4200370300200241003a0028200242003703082002410036023820024201370330200241086a200241306a108f0102400240024020022d0028220341064b0d000240024002400240024002400240024020030e0700010203040506000b410021040c060b410121040c050b410221040c040b410321040c030b410421040c020b410521040c010b410621040b200220043a003f02400240200228023420022802382203460d00200228023021050c010b200341016a22052003490d03200341017422062005200620054b1b22064100480d030240024020030d002006102821050c010b200228023020032006102c21050b2005450d022002200636023420022005360230200228023821030b2002200341016a360238200520036a20043a00000b20002002290330370200200041086a200241306a41086a280200360200200241c0006a24000f0b200641011037000b1031000b4001017f230041106b2202240020024100360208200242013703004100200210b401200041086a200228020836020020002002290300370200200241106a24000b130020004106360204200041acc7c5003602000b3201017f02404104102822020d00410441011037000b20004284808080c00037020420002002360200200241809c313600000b3201017f02404104102822020d00410441011037000b20004284808080c0003702042000200236020020024180a3053600000b3e01017f02404110102822020d00411041011037000b20024200370008200242808084fea6dee111370000200042908080808002370204200020023602000b3201017f02404104102822020d00410441011037000b20004284808080c0003702042000200236020020024180de343600000ba30301047f230041c0006b22022400024002400240411310282203450d002003410f6a41002800e38945360000200341086a41002900dc8945370000200341002900d48945370000200341134126102c2203450d0120032000360013200241206a41186a22004200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034117200241206a1000200241186a2000290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002003102a411010282203450d02200320012903003700002003200141086a2903003700082002429080808080023702242002200336022020012802102104200141186a2802002203200241206a10b40102402003450d00200341057421002004210303402003200241206a108f01200341206a2103200041606a22000d000b0b2002280224210320024120200228022022002002280228100702402003450d002000102a0b0240200141146a280200450d002004102a0b200241c0006a24000f0b411341011037000b412641011037000b411041011037000bc01401077f230041d0016b2204240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240411a10282205450d00200541186a41002f00ce88453b0000200541106a41002900c68845370000200541086a41002900be8845370000200541002900b688453700002005411a4134102c2205450d012005200136001a200441e0006a41186a22064200370300200441e0006a41106a22074200370300200441e0006a41086a22084200370300200442003703602005411e200441e0006a1000200441306a41186a2006290300370300200441306a41106a2007290300370300200441306a41086a2008290300370300200420042903603703302005102a0240200441306a41204101410041001003417f470d0041b7d5c50021000c110b200441146a200041086a2900003702002004411c6a200041106a290000370200200441246a200041186a290000370200200420013602082004200029000037020c411010282205450d02200541002900a68845370000200541086a41002900ae88453700002004429080808080023702b401200420053602b001200541104120102c2205450d03200441203602b401200420042802b801220641046a3602b801200420053602b001200520066a2001360000200441086a410472200441b0016a108f0120042802b801210520042802b0012106200441e0006a41186a22074200370300200441e0006a41106a22084200370300200441e0006a41086a220942003703002004420037036020062005200441e0006a1000200441306a41186a2007290300370300200441306a41106a2008290300370300200441306a41086a200929030037030020042004290360370330024020042802b401450d0020042802b001102a0b200441306a41204101410041001003417f470d0f200441086a41186a200041186a290000370300200441086a41106a200041106a290000370300200441086a41086a200041086a29000037030020042000290000370308411310282205450d042005410f6a41002800a88945360000200541086a41002900a18945370000200541002900998945370000200541134126102c2205450d0520052001360013200441e0006a41186a22064200370300200441e0006a41106a22074200370300200441e0006a41086a220842003703002004420037036020054117200441e0006a1000200441306a41186a2006290300370300200441306a41106a2007290300370300200441306a41086a2008290300370300200420042903603703302005102a20044100360260200441306a4120200441e0006a100621050240024020042802602207417f460d002007210620050d010b20044100360268200442013703604100200441e0006a10b4012004280268210620042802642107200428026021050b200420063602582004200736025420042005360250024002402006450d00200441e0006a20052006410110d60220042802604101470d012004280254450d102004280250102a0c100b4101200441d0006a10b401200441086a200441d0006a108f010c0d0b200428026421080240200441ec006a2802002205200441e8006a2802002206460d002004280258200520066b6a220741206a2209417f4c0d070240024020090d004101210a0c010b20091028220a450d090b20042009360284012004200a360280012004200736028801200420044180016a3602602008200441e0006a200510d70120072005490d0920042802880122082007490d0a200428025822082006490d0b20042802800121092004280250210a2004200720056b2207360290012004200820066b22083602940120072008470d0c200920056a200a20066a2007109a051a200441086a20044180016a108f012004280288012106200428028401210720042802800121052004280254450d0e2004280250102a0c0e0b2004200441d0006a3602602008200441e0006a200610d701200441086a200441d0006a108f010c0c0b411a41011037000b413441011037000b411041011037000b412041011037000b411341011037000b412641011037000b1036000b200941011037000b200520071044000b20072008103c000b200620081044000b200441b0016a41146a4108360200200441bc016a412536020020044198016a41146a41033602002004420337029c01200441c8afc60036029801200441253602b401200420044190016a3602c801200420044194016a3602cc0120044204370370200442013702642004419cb0c6003602602004200441b0016a3602a8012004200441e0006a3602c0012004200441cc016a3602b8012004200441c8016a3602b00120044198016a41d8b0c600103e000b2004280258210620042802542107200428025021050b2005450d00200441306a41202005200610072007450d012005102a0c010b412010282206450d0220062004290308370000200641186a200441086a41186a290300370000200641106a200441086a41106a290300370000200641086a200441086a41086a290300370000411310282207450d03410021052007410f6a41002800a88945360000200741086a41002900a18945370000200741002900998945370000200741134126102c2207450d0420072001360013200441e0006a41186a22084200370300200441e0006a41106a22094200370300200441e0006a41086a220a42003703002004420037036020074117200441e0006a1000200441306a41186a2008290300370300200441306a41106a2009290300370300200441306a41086a200a290300370300200420042903603703302007102a20044100360268200442013703604101200441e0006a10b4010340200620056a200441e0006a108f014120200541206a2205470d000b20042802642105200441306a4120200428026022072004280268100702402005450d002007102a0b2006102a0b200441146a200041086a2900003702002004411c6a200041106a290000370200200441246a200041186a290000370200200420013602082004200029000037020c411010282205450d04200541002900a68845370000200541086a41002900ae88453700002004429080808080023702b401200420053602b001200541104120102c2205450d05200441203602b401200420042802b801220041046a3602b801200420053602b001200520006a2001360000200441086a410472200441b0016a108f0120042802b801210520042802b0012100200441e0006a41186a22064200370300200441e0006a41106a22014200370300200441e0006a41086a220742003703002004420037036020002005200441e0006a1000200441306a41186a2006290300370300200441306a41106a2001290300370300200441306a41086a200729030037030020042004290360370330024020042802b401450d0020042802b001102a0b410110282205450d0641002100200541807f410020021b2003723a0000200441306a41202005410110072005102a0b200441d0016a240020000f0b412041011037000b411341011037000b412641011037000b411041011037000b412041011037000b410141011037000bc76501037f230041206b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00000eac010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab0100010b2002200128021841dfd6c50041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000cab010b2002200128021841f0d6c500410b2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000caa010b2002200128021841fbd6c50041032001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca9010b2002200128021841fed6c50041052001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4184d7c500105d21000ca8010b200220012802184194d7c50041042001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4184d7c500105d21000ca7010b200220012802184198d7c50041022001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4184d7c500105d21000ca6010b20022001280218419ad7c50041042001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca5010b20022001280218419ed7c50041032001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca4010b2002200128021841a1d7c50041022001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000ca3010b2002200128021841a3d7c50041042001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000ca2010b2002200128021841a7d7c50041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0d7c500105d21000ca1010b2002200128021841c0d7c50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca0010b2002200128021841c6d7c50041042001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000c9f010b2002200128021841cad7c500410c2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041016a36020c20012002410c6a41d8d7c500105d21000c9e010b2002200128021841e8d7c50041042001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c9d010b2002200128021841ecd7c50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c9c010b2002200128021841f2d7c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000c9b010b2002200128021841fad7c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000c9a010b200220012802184182d8c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000c99010b20022001280218418ad8c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000c98010b200220012802184193d8c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000c97010b20022001280218419cd8c50041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c96010b2002200128021841a3d8c50041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c95010b2002200128021841aad8c50041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c94010b2002200128021841b1d8c50041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c93010b2002200128021841b8d8c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c92010b2002200128021841c1d8c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c91010b2002200128021841cad8c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c90010b2002200128021841d4d8c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c8f010b2002200128021841ded8c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c8e010b2002200128021841e7d8c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c8d010b2002200128021841f0d8c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c8c010b2002200128021841fad8c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c8b010b200220012802184184d9c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c8a010b20022001280218418ed9c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c89010b200220012802184198d9c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c88010b2002200128021841a0d9c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c87010b2002200128021841a8d9c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c86010b2002200128021841b0d9c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c85010b2002200128021841b8d9c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c84010b2002200128021841c1d9c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c83010b2002200128021841cbd9c50041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c82010b2002200128021841d4d9c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c81010b2002200128021841ded9c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21012002200041086a36020c20012002410c6a41a8d6c500105d21000c80010b2002200128021841e8d9c500410d2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41d8d7c500105d21000c7f0b2002200128021841f5d9c500410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41d8d7c500105d21000c7e0b2002200128021841ffd9c50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4188dac500105d21000c7d0b200220012802184198dac50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a41a0dac500105d21000c7c0b2002200128021841b0dac50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a8d6c500105d21000c7b0b2002200128021841b8dac50041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a41c0dac500105d21000c7a0b2002200128021841d0dac50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c790b2002200128021841d6dac50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c780b2002200128021841dbdac50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c770b2002200128021841e0dac50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c760b2002200128021841e6dac50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c750b2002200128021841ecdac50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c740b2002200128021841f2dac50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c730b2002200128021841f8dac50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c720b2002200128021841fedac50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c710b200220012802184184dbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c700b20022001280218418adbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6f0b200220012802184190dbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6e0b200220012802184196dbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6d0b20022001280218419bdbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6c0b2002200128021841a0dbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6b0b2002200128021841a6dbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6a0b2002200128021841acdbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c690b2002200128021841b2dbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c680b2002200128021841b8dbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c670b2002200128021841bedbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c660b2002200128021841c4dbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c650b2002200128021841cadbc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c640b2002200128021841d0dbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c630b2002200128021841d5dbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c620b2002200128021841dadbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c610b2002200128021841dfdbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c600b2002200128021841e4dbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5f0b2002200128021841e9dbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5e0b2002200128021841eedbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5d0b2002200128021841f3dbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5c0b2002200128021841f8dbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5b0b2002200128021841fddbc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5a0b200220012802184182dcc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c590b200220012802184187dcc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c580b20022001280218418cdcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c570b200220012802184192dcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c560b200220012802184198dcc50041092001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c550b2002200128021841a1dcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c540b2002200128021841a7dcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c530b2002200128021841addcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c520b2002200128021841b3dcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c510b2002200128021841badcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c500b2002200128021841c1dcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4f0b2002200128021841c8dcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4e0b2002200128021841cfdcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4d0b2002200128021841d5dcc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4c0b2002200128021841dadcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4b0b2002200128021841e0dcc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4a0b2002200128021841e6dcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c490b2002200128021841eddcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c480b2002200128021841f4dcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c470b2002200128021841fbdcc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c460b200220012802184182ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c450b200220012802184188ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c440b20022001280218418eddc50041092001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c430b200220012802184197ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c420b20022001280218419dddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c410b2002200128021841a3ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c400b2002200128021841a9ddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3f0b2002200128021841b0ddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3e0b2002200128021841b7ddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3d0b2002200128021841beddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3c0b2002200128021841c5ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3b0b2002200128021841cbddc50041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3a0b2002200128021841d0ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c390b2002200128021841d6ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c380b2002200128021841dcddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c370b2002200128021841e3ddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c360b2002200128021841eaddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c350b2002200128021841f1ddc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c340b2002200128021841f8ddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c330b2002200128021841feddc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c320b200220012802184184dec50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c310b20022001280218418bdec50041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c300b200220012802184193dec50041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2f0b20022001280218419bdec500410a2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2e0b2002200128021841a5dec50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2d0b2002200128021841acdec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2c0b2002200128021841b2dec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2b0b2002200128021841b8dec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2a0b2002200128021841bedec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c290b2002200128021841c4dec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c280b2002200128021841cadec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c270b2002200128021841d0dec500410b2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c260b2002200128021841dbdec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c250b2002200128021841e1dec50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c240b2002200128021841e7dec50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c230b2002200128021841eedec50041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c220b2002200128021841f6dec50041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c210b2002200128021841fedec500410a2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c200b200220012802184188dfc50041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1f0b20022001280218418fdfc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1e0b200220012802184195dfc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1d0b20022001280218419bdfc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1c0b2002200128021841a1dfc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1b0b2002200128021841a7dfc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1a0b2002200128021841addfc50041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c190b2002200128021841b3dfc500410b2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c180b2002200128021841bedfc500410a2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c170b2002200128021841c8dfc500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c160b2002200128021841d4dfc500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c150b2002200128021841e0dfc500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c140b2002200128021841ecdfc500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c130b2002200128021841f8dfc500410d2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c120b200220012802184185e0c500410d2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c110b200220012802184192e0c500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c100b20022001280218419ee0c500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0f0b2002200128021841aae0c500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0e0b2002200128021841b6e0c500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0d0b2002200128021841c2e0c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0c0b2002200128021841d0e0c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0b0b2002200128021841dee0c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0a0b2002200128021841ece0c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c090b2002200128021841fae0c500410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c080b200220012802184186e1c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c070b200220012802184194e1c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c060b2002200128021841a2e1c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c050b2002200128021841b0e1c500410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c040b2002200128021841bee1c500410d2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c030b2002200128021841cbe1c50041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c020b2002200128021841dce1c50041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c010b2002200128021841ede1c50041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000b20002d00082101024020002802042203450d00200141ff0171210441012101024020040d00024020034101470d0020002d0009450d00200028020022042d00004104710d0041012101200428021841f4afc00041012004411c6a28020028020c1100000d010b2000280200220128021841c8a4c60041012001411c6a28020028020c11000021010b200020013a00080b200241206a2400200141ff01714100470bcd0203027f017e017f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210020034120710d012000ac22042004423f8722047c2004852000417f73411f762001103f21000c020b20002802002103410021000340200220006a41ff006a2003410f712205413072200541d7006a2005410a491b3a00002000417f6a2100200341047622030d000b20004180016a22034181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021030340200220036a41ff006a2000410f712205413072200541376a2005410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d0220014101419087c0004102200220036a4180016a410020036b104221000b20024180016a240020000f0b20034180011044000b20004180011044000bcd0202027f027e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120042004423f8722057c2005852004427f552001103f21000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000b20024180016a240020000f0b20034180011044000b20034180011044000bc00201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff018341012001103f21000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d0220014101419087c0004102200220006a4180016a410020006b104221000b20024180016a240020000f0b20044180011044000b20044180011044000bd30101017f230041106b22022400024002400240024020002d00000e03010200010b2002200128021841fee1c500410b2001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c020b200220012802184189e2c500410c2001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b200220012802184195e2c500410d2001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040b200241106a240020000b8a0201027f230041106b2202240020002802002802002100200128021841b8d6c500410b2001411c6a28020028020c1100002103200241003a0005200220033a0004200220013602002002200036020c200241c3d6c50041052002410c6a41c8d6c500105c21012002200041086a36020c200141d8d6c50041072002410c6a41a8d6c500105c1a20022d00042101024020022d0005450d00200141ff0171210041012101024020000d0020022802002201411c6a28020028020c210020012802182103024020012d00004104710d00200341eeafc0004102200011000021010c010b200341f0afc0004101200011000021010b200220013a00040b200241106a2400200141ff01714100470b890501047f230041d0006b220224002000280200220041046a28020021032000280200210041012104200128021841adafc00041012001411c6a28020028020c110000210502402003450d0020022000360204024020050d00024020012d0000410471450d0041012104200128021841afafc0004101200128021c28020c1100000d012001280200210541012104200241013a001720022005360218200241b0afc00036023420022001290218370308200220012d00303a00482002200128020436021c200220012902283703402002200129022037033820022001290210370328200220012902083703202002200241176a3602102002200241086a360230200241046a200241186a10d8010d01200228023041c8afc0004102200228023428020c11000021040c010b200241046a200110d80121040b024020034101470d00200421050c010b200041046a21002003410274417c6a210320042105034020022000360204200541ff0171210441012105024020040d00024020012802002204410471450d00200241013a001720022004360218200241b0afc00036023420022001290218370308200220012d00303a00482002200128020436021c200220012902283703402002200129022037033820022001290210370328200220012902083703202002200241176a3602102002200241086a360230200241046a200241186a10d8010d01200228023041c8afc0004102200228023428020c11000021050c010b200128021841caafc0004102200128021c28020c1100000d00200241046a200110d80121050b200041046a21002003417c6a22030d000b0b41012100024020050d00200128021841aeafc0004101200128021c28020c11000021000b200241d0006a240020000b19002000200141186a280200360204200020012802103602000bc50201037f230041206b2202240002400240200028020022002d00004104470d002002200128021841b7e2c50041082001411c6a28020028020c11000022003a001820022001360210200241003a0019200241003602140c010b2002200128021841bfe2c50041052001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a41c4e2c500105d210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841f4afc00041012004411c6a28020028020c1100000d010b2001280200220028021841c8a4c60041012000411c6a28020028020c11000021000b200120003a00080b200241206a2400200041ff01714100470b0c002000280200200110d0040b8f0201017f230041106b220224000240024002400240024020002d00000e0401020300010b2002200128021841d4e2c50041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c030b2002200128021841d7e2c50041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c020b2002200128021841dae2c50041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b2002200128021841dde2c50041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040b200241106a240020000bc00201037f230041206b220224000240024020002d00004104470d002002200128021841b7e2c50041082001411c6a28020028020c11000022003a001820022001360210200241003a0019200241003602140c010b2002200128021841bfe2c50041052001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a41c4e2c500105d210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841f4afc00041012004411c6a28020028020c1100000d010b2001280200220028021841c8a4c60041012000411c6a28020028020c11000021000b200120003a00080b200241206a2400200041ff01714100470b0c002000280200200110c6040bed0902067f017e024020010d00200041ac013a00000f0b024002400240024002400240024020012d00002202414f6a41fb004f0d000c010b02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020020e312c2c0001022c2c0304052c06072c2c08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292c0b20012d00012103410221020c2b0b20012d00012103410321020c2a0b20012d00012103410421020c290b200141046a2802002104410721020c270b200141046a2802002104410821020c260b200141046a2802002105410c10282204450d272005280204220641ffffffff03712006470d2820064102742201417f4c0d280240024020010d00410421070c010b200110282207450d2a0b02402006450d00200528020021012006410274210320072102034020022001280200360200200241046a2102200141046a21012003417c6a22030d000b0b200420063602042004200736020020042005280208360208410921020c250b200141046a2802002104410b21020c240b200141046a280200210420012d00012103410c21020c240b200141046a2802002104410f21020c220b200141046a2802002104411021020c210b200141046a2802002104411121020c200b200141046a2802002104411221020c1f0b200141046a2802002104411321020c1e0b200141046a280200210420013502082108411421020c1d0b200141046a280200210420013502082108411521020c1c0b200141046a280200210420013502082108411621020c1b0b200141046a280200210420013502082108411721020c1a0b200141046a280200210420013502082108411821020c190b200141046a280200210420013502082108411921020c180b200141046a280200210420013502082108411a21020c170b200141046a280200210420013502082108411b21020c160b200141046a280200210420013502082108411c21020c150b200141046a280200210420013502082108411d21020c140b200141046a280200210420013502082108411e21020c130b200141046a280200210420013502082108411f21020c120b200141046a280200210420013502082108412021020c110b200141046a280200210420013502082108412121020c100b200141046a280200210420013502082108412221020c0f0b200141046a280200210420013502082108412321020c0e0b200141046a280200210420013502082108412421020c0d0b200141046a280200210420013502082108412521020c0c0b200141046a280200210420013502082108412621020c0b0b200141046a280200210420013502082108412721020c0a0b200141046a280200210420013502082108412821020c090b200141046a280200210420013502082108412921020c080b200141046a280200210420013502082108412a21020c070b20012d00012103412b21020c070b20012d00012103412c21020c060b200141046a2802002104412d21020c040b20012903082108412e21020c020b200141046a2802002104412f21020c020b20012903082108413021020b0b0b200020033a0001200020023a0000200041086a2008370300200041046a20043602000f0b410c41041037000b1036000b200141041037000bba0201037f230041106b220224000240024020002802000d002002200128021841e0e2c50041042001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b2002200128021841e4e2c50041042001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41e8e2c500105d210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841f4afc00041012004411c6a28020028020c1100000d010b2001280200220028021841c8a4c60041012000411c6a28020028020c11000021000b200120003a00080b200241106a2400200041ff01714100470b22002001419daec0004198aec00020002802002d000022001b4104410520001b10450bd60501087f230041106b220324002002280208220441546a2105200241106a280200220641306c210702400340410021082007450d01200741506a21072005412c6a2109200541306a220a210520092d00004103470d000b200a41086a2802002207450d00200741286c2105200a28020041186a2107410021080340200820072d0000456a2108200741286a2107200541586a22050d000b0b02400240024002400240024002400240200120086b220a20014b0d00200641306c2107200441546a210503402007450d02200741506a21072005412c6a2108200541306a2209210520082d0000410c470d000b200941086a280200200a4b0d02411e102822070d05411e41011037000b412c102822070d02412c41011037000b412c102822070d02412c41011037000b2009280200200a41186c6a28020821072003200a200210dd0420032802004101460d0320032802042105200041003602002000200520076a3602040c040b2000200736020420004101360200200741286a41002800fee545360000200741206a41002900f6e545370000200741186a41002900eee545370000200741106a41002900e6e545370000200741086a41002900dee545370000200741002900d6e545370000200041086a42ac808080c0053702000c030b2000200736020420004101360200200741286a41002800aae645360000200741206a41002900a2e645370000200741186a410029009ae645370000200741106a4100290092e645370000200741086a410029008ae64537000020074100290082e645370000200041086a42ac808080c0053702000c020b2000200736020420004101360200200741166a41002900c4e645370000200741106a41002900bee645370000200741086a41002900b6e645370000200741002900aee645370000200041086a429e808080e0033702000c010b20002003290204370204200041013602002000410c6a2003410c6a2802003602000b200341106a24000b8d0301067f230041106b220224000240024002400240200041046a2802002203200041086a28020022046b20012802042205200128020022066b4104762207490d00200028020021030c010b200420076a22062004490d02200341017422052006200520064b1b220641ffffffff00712006470d02200641047422054100480d020240024020030d002005102821030c010b200028020020034104742005102c21030b2003450d0120002003360200200041046a2006360200200041086a280200210420012802042105200128020021060b0240024020062005470d00410021060c010b2001200641106a3602000b2002200610d304024020022d000041ac01460d00200320044104746a2106034020062002290300370300200641086a200241086a29030037030002400240200128020022052001280204470d00410021050c010b2001200541106a3602000b200441016a2104200641106a21062002200510d30420022d000041ac01470d000b0b200041086a2004360200200241106a24000f0b200541081037000b1031000b1000200028020035020041012001103f0be00a01067f024002400240024020012d00002202414f6a41fb00490d0002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020020e312a2a0001022a2a0304052a06072a2a08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a0b200020012d00013a0001200041023a00000f0b200020012d00013a0001200041033a00000f0b200020012d00013a0001200041043a00000f0b200041046a200141046a280200360200200041073a00000f0b200041046a200141046a280200360200200041083a00000f0b200141046a2802002103410c10282204450d252003280204220541ffffffff03712005470d2620054102742201417f4c0d260240024020010d00410421060c010b200110282206450d280b02402005450d00200328020021012005410274210720062102034020022001280200360200200241046a2102200141046a21012007417c6a22070d000b0b200420053602042004200636020020042003280208360208200041046a2004360200200041093a00000f0b200041046a200141046a2802003602002000410b3a00000f0b200020012d00013a0001200041046a200141046a2802003602002000410c3a00000f0b200041046a200141046a2802003602002000410f3a00000f0b200041046a200141046a280200360200200041103a00000f0b200041046a200141046a280200360200200041113a00000f0b200041046a200141046a280200360200200041123a00000f0b200041046a200141046a280200360200200041133a00000f0b200041046a200141046a290200370200200041143a00000f0b200041046a200141046a290200370200200041153a00000f0b200041046a200141046a290200370200200041163a00000f0b200041046a200141046a290200370200200041173a00000f0b200041046a200141046a290200370200200041183a00000f0b200041046a200141046a290200370200200041193a00000f0b200041046a200141046a2902003702002000411a3a00000f0b200041046a200141046a2902003702002000411b3a00000f0b200041046a200141046a2902003702002000411c3a00000f0b200041046a200141046a2902003702002000411d3a00000f0b200041046a200141046a2902003702002000411e3a00000f0b200041046a200141046a2902003702002000411f3a00000f0b200041046a200141046a290200370200200041203a00000f0b200041046a200141046a290200370200200041213a00000f0b200041046a200141046a290200370200200041223a00000f0b200041046a200141046a290200370200200041233a00000f0b200041046a200141046a290200370200200041243a00000f0b200041046a200141046a290200370200200041253a00000f0b200041046a200141046a290200370200200041263a00000f0b200041046a200141046a290200370200200041273a00000f0b200041046a200141046a290200370200200041283a00000f0b200041046a200141046a290200370200200041293a00000f0b200041046a200141046a2902003702002000412a3a00000f0b200020012d00013a00012000412b3a00000f0b200020012d00013a00012000412c3a00000f0b200041046a200141046a2802003602002000412d3a00000f0b200041086a200141086a2903003703002000412e3a00000f0b200041046a200141046a2802003602002000412f3a00000f0b200041086a200141086a290300370300413021020b200020023a00000f0b410c41041037000b1036000b200141041037000bea0302057f017e02402001450d00034020002802940321002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d00200020014105746a220441c4006a2802002105200441386a2802002106200441346a2802002107200141016a21010c010b02400240200028020022010d002003ad210841002104410021010c010b20003301044220862003ad842108410121040b2000102a2008a72103024002402008422088a7220620012f01064f0d00200121050c010b034002400240200128020022050d002003ad2108410021050c010b200441016a210420013301044220862003ad8421080b2001102a2008a72103200521012008422088a7220620052f01064f0d000b0b200641027420056a4198036a2802002100200520064105746a220141c4006a2802002105200141386a2802002106200141346a280200210702402004417f6a2201450d00034020002802940321002001417f6a22010d000b0b410021010b20054102460d012002417f6a210202402006450d002007102a0b20020d000b0b0240200041f8b9c000460d00200028020021012000102a2001450d00200128020021052001102a2005450d00024020052802002201450d0003402005102a2001210520012802002200210120000d000b0b2005102a0b0bba09010b7f230041e0006b22032400200320013602202002280208220441546a2105200241106a280200220641306c210202400340024020020d00410021070c020b200241506a21022005412c6a2107200541306a2208210520072d00004102470d000b200341186a200810fa0320032802182107200328021c21020b2002410020071b2109200641306c2102200441546a21052007410420071b210a02400340024020020d004100210b0c020b200241506a21022005412c6a2107200541306a2208210520072d00004104470d000b200341106a200810fa032003280210210b2003280214210c0b200641306c2102200441546a2105200b4104200b1b210d02400240024002400240024003402002450d01200241506a21022005412c6a2107200541306a2208210520072d00004103470d000b200841086a2802002202450d00200241286c2107200828020041186a2102410021050340200520022d0000456a2105200241286a2102200741586a22070d000b200520014d0d01200641306c2102200441546a2105024003402002450d01200241506a21022005412c6a2107200541306a2208210520072d00004103470d000b200341086a200810fa0320032802082202200328020c41286c6a21070240024002400340024002400240200720026b41f8004b0d0020022007460d0d2002411c6a2105034020022d0018450d02200541286a2105200241286a22022007470d000c0e0b0b20022d00180d01200241186a2105200241286a21080c040b2005410c6a21080c040b200241c0006a22052d0000450d010240200241e8006a22052d0000450d0020024190016a2105200241a0016a2208210220052d00000d010c030b0b200241f8006a21080c010b200241d0006a21080b200541046a21050b2001450d0303402001417f6a210120082102024002400340024002400240200720026b41f8004b0d0020022007460d0d2002411c6a2105034020022d0018450d02200541286a2105200241286a22022007460d0e0c000b0b20022d00180d01200241186a2105200241286a21080c040b2005410c6a210820010d040c080b200241c0006a22052d0000450d010240200241e8006a22052d0000450d0020024190016a2105200241a0016a2208210220052d00000d010c030b0b200241f8006a21080c010b200241d0006a21080b20010d000b200541046a21050c030b41cce6c50041c2001050000b410021050b0240200c4100200b1b200120056b22024d0d00200d20024102746a22050d010b200341cc006a41013602002003420237023c200341ece7c5003602382003410136022c2003200341286a3602482003200341206a360228200341d0006a200341386a1033200341d0006a21020c010b2003200528020022023602240240200920024d0d00200a20024104746a2202450d0020002002360204410021020c020b200341cc006a4102360200200341dc006a41013602002003420337023c200341fce7c500360238200341013602542003200341d0006a3602482003200341206a3602582003200341246a360250200341286a200341386a1033200341286a21020b20022802002105200041086a200229020437020020002005360204410121020b20002002360200200341e0006a24000f0b418ee7c50041dd001050000bf80d01067f0240024020002d00002201410e4b0d00024002400240024002400240024002400240024002400240024020010e0f0001020304050607080e090e0a0b0c000b200041086a280200450d0d200041046a280200102a0f0b0240200041086a280200450d00200041046a280200102a0b200041146a280200450d0c200041106a280200102a0f0b02402000410c6a2802002202450d00200041046a28020021012002410474210203400240200141046a280200450d002001280200102a0b200141106a2101200241706a22020d000b0b200041086a280200450d0b2000280204102a0f0b02402000410c6a2802002202450d00200041046a2802002101200241286c210203400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101200241586a22020d000b0b200041086a280200450d0a2000280204102a0f0b200041086a280200450d09200041046a280200102a0f0b200041086a280200450d08200041046a280200102a0f0b200041086a280200450d07200041046a280200102a0f0b02402000410c6a2802002201450d00200041046a280200220320014104746a21040340024020032802082202450d0020032802002101200241047421020340024020012d00004109470d000240200141046a2205280200220628020441ffffffff0371450d002006280200102a200528020021060b2006102a0b200141106a2101200241706a22020d000b0b200341106a21010240200341046a280200450d002003280200102a0b2001210320012004470d000b0b200041086a280200450d062000280204102a0f0b02402000410c6a2802002202450d00200041046a2802002101200241146c210203400240200141046a280200450d002001280200102a0b200141146a21012002416c6a22020d000b0b200041086a280200450d052000280204102a0f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a21040340024020032802042201450d0002402003410c6a2802002202450d00200241047421020340024020012d00004109470d000240200141046a2205280200220628020441ffffffff0371450d002006280200102a200528020021060b2006102a0b200141106a2101200241706a22020d000b0b200341086a280200450d002003280204102a0b2003411c6a21010240200341146a280200450d002003280210102a0b2001210320012004470d000b0b200041086a280200450d042000280204102a0f0b02402000410c6a2802002201450d00200041046a2802002203200141186c6a210403400240200341046a280200450d002003280200102a0b0240200341146a2802002202450d00200328020c2101200241047421020340024020012d00004109470d000240200141046a2205280200220628020441ffffffff0371450d002006280200102a200528020021060b2006102a0b200141106a2101200241706a22020d000b0b200341186a21010240200341106a280200450d00200328020c102a0b2001210320012004470d000b0b200041086a280200450d032000280204102a0f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a21040340024020032802042201450d0002402003410c6a2802002202450d00200241047421020340024020012d00004109470d000240200141046a2205280200220628020441ffffffff0371450d002006280200102a200528020021060b2006102a0b200141106a2101200241706a22020d000b0b200341086a280200450d002003280204102a0b2003411c6a21010240200341146a280200450d002003280210102a0b2001210320012004470d000b0b200041086a280200450d022000280204102a0f0b0240200041046a2802002201450d00200041086a280200450d002001102a0b0240200041146a2802002201450d0002402000411c6a2802002202450d002002410c6c21020340024020012802002206450d00200141046a280200450d002006102a0b2001410c6a2101200241746a22020d000b0b200041186a280200450d002000280214102a0b200041246a2802002203450d0102402000412c6a2802002201450d00200320014104746a210403402003220541106a2103024020052802042201450d0002402005410c6a2802002202450d002002410c6c21020340024020012802002206450d00200141046a280200450d002006102a0b2001410c6a2101200241746a22020d000b0b200541086a280200450d002005280204102a0b20032004470d000b0b200041286a280200450d012000280224102a0c010b0240200041086a280200450d00200041046a280200102a0b0240200041146a2802002201450d00200041186a280200450d002001102a0b200041246a280200450d00200041206a280200102a0f0b0bd65e010c7f23004190016b220324002003200136021c2002280208220441546a2105200241106a280200220641306c21010240024002400240024002400240024002400240024002400240024003402001450d01200141506a21012005412c6a2107200541306a2208210520072d00004104470d000b200641306c2101200441546a210503402001450d02200141506a21012005412c6a2107200541306a2209210520072d0000410c470d000b200641306c2101200441546a210503402001450d03200141506a21012005412c6a2107200541306a2204210520072d00004102470d000b02404100280280b1464105490d002003410136023c20032003411c6a3602384100280284b146210120034188016a41980136020020034180016a42ed80808010370300200341f8006a4125360200200341f0006a4101360200200341e0006a4201370300200341d8006a410a360200200341fcf0c50036027c200341d7f0c500360274200341ec006a200341386a360200200341f8edc50036025c200341cdf0c500360254200341053602504188b1c60041b8aec600200141024622011b200341d0006a41c8b0c00041e0b0c00020011b2802101102000b200341106a200810fa032003280214200328021c22014d0d03200328021020014102746a2201450d03200341086a200410fa030240200328020c200128020022014d0d00200328020820014104746a22010d050b412510282201450d052001411d6a410029009dee45370000200141186a4100290098ee45370000200141106a4100290090ee45370000200141086a4100290088ee4537000020014100290080ee45370000200041086a42a5808080d00437020020002001360204200041013602000c0d0b411310282201450d082001410f6a41002800d3ed45360000200141086a41002900cced45370000200141002900c4ed45370000200041086a4293808080b00237020020002001360204200041013602000c0c0b410f10282201450d06200141076a41002900deed45370000200141002900d7ed45370000200041086a428f808080f00137020020002001360204200041013602000c0b0b410f10282201450d04200141076a41002900eded45370000200141002900e6ed45370000200041086a428f808080f00137020020002001360204200041013602000c0a0b412510282201450d022001411d6a410029009dee45370000200141186a4100290098ee45370000200141106a4100290090ee45370000200141086a4100290088ee4537000020014100290080ee45370000200041086a42a5808080d00437020020002001360204200041013602000c090b02400240200941086a280200200328021c22054b0d00412710282201450d012001411f6a41002900c4ee45370000200141186a41002900bdee45370000200141106a41002900b5ee45370000200141086a41002900adee45370000200141002900a5ee45370000200041086a42a7808080f00437020020002001360204200041013602000c0a0b20092802002109200341206a41086a420037030020034280808080c00037032020012d000d2107410021012003410036024020032007410447220a36023c2003200a360238200341003a0044024002400240024002404100280280b14641044b0d00200341d0006a41086a200341386a41086a29030037030020032003290338370350200341206a410472210b200341d0006a21070c010b2003412d36024c2003200341386a3602484100280284b146210120034188016a41cb0036020020034180016a42ed80808010370300200341f8006a4125360200200341f0006a4101360200200341e0006a4201370300200341d0006a41086a2207410a360200200341fcf0c50036027c200341d7f0c500360274200341ec006a200341c8006a360200200341cceec50036025c200341cdf0c500360254200341053602504188b1c60041b8aec600200141024622011b200341d0006a41c8b0c00041e0b0c00020011b280210110200200328022c2108200328022821012007200341386a41086a29030037030020032003290338370350200341206a410472210b200341d0006a210720082001470d010b200141016a22082001490d01200141017422062008200620084b1b220841ffffffff00712008470d01200841047422064100480d010240024020010d002006102821010c010b200b28020020014104742006102c21010b2001450d02200b200136020020032008360228200328022c21080b200b28020020084104746a22012007290200370200200141086a200741086a2902003702002003200328022c41016a36022c410021072009200541186c6a2201280214450d092009200541186c6a410c6a2109200141146a2108200341d0006a410472210c410021074100210103400240200328022020074d0d00200341d0006a200341206a410010e304024020032802504101470d00200041013602002000200c2902003702042000410c6a200c41086a2802003602000c0d0b2007200328022020032802542d000c1b21070b02400240024002400240024002402001200828020022054f0d002003200928020020014104746a220536023402404100280280b1464105490d002003412936023c2003200341346a3602384100280284b1462105200341c90136028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341b0aec60036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328023421050b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020052d000022060eac0102220000002201030405060708090a0b0c0d0e0f1010101010101010101010101010111111111111111111121314141414151616161616161616161615161616161616161616161616161616161616161616161717171818181818181818181818181818181717171818181818181818181818181818181717171717171718181818181818171717171717171818181818181819191919191919191919191919191919191919191919191919020b20052d00012105200320032802203602402003200541044722053602382003200641034720057136023c200341003a004402404100280280b1464105490d002003412d36024c2003200341386a3602484100280284b1462105200341cb0036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341cceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341c8006a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b2802101102000b200341d0006a41086a2206200341386a41086a290300370300200320032903383703500240200328022c22052003280228470d00200541016a220d2005490d242005410174220e200d200e200d4b1b220d41ffffffff0071200d470d24200d410474220e4100480d240240024020050d00200e102821050c010b200b2802002005410474200e102c21050b2005450d1d200b20053602002003200d360228200328022c21050b200b28020020054104746a22052003290350370200200541086a20062903003702002003200328022c41016a36022c0c210b4100210502404100280280b1464105490d000240200328022c2206417f6a220d20064b0d00200b280200200d4104746a4100200d2006491b21050b2003412e36024c200320053602382003200341386a3602484100280284b1462105200341d30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341d4eec50036025c2003410a360258200341cdf0c500360254200341053602502003200341c8006a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b2802101102000b0240200328022c2205450d0020032005417f6a220536022c200b28020020054104746a22052d000c4102470d1a0b411710282201450d1c2001410f6a41002900ebee45370000200141086a41002900e4ee45370000200141002900dcee45370000200041086a4297808080f00237020020002001360204200041013602000c2c0b02404100280280b1464105490d004100280284b1462105200341c10036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003420437026c20034201370360200341f4eec50036025c2003410a360258200341cdf0c500360254200341053602504188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b2802101102000b0240200328022c2205417f6a220620054f0d00200620054d0d180b411710282201450d1e2001410f6a41002900ebee45370000200141086a41002900e4ee45370000200141002900dcee45370000200041086a4297808080f00237020020002001360204200041013602000c2b0b200341d0006a200341206a200541046a28020010e304024020032802504101470d00200041013602002000200c2902003702042000410c6a200c41086a2802003602000c2b0b200341d0006a200341206a200328025428020410e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c2b0b02404100280280b1464105490d004100280284b1462105200341c10036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003420437026c20034201370360200341f4eec50036025c2003410a360258200341cdf0c500360254200341053602504188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b2802101102000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102822010d01411741011037000b200b28020020064104746a41013a000c0c1f0b2001410f6a41002900ebee45370000200141086a41002900e4ee45370000200141002900dcee45370000200041086a4297808080f00237020020002001360204200041013602000c2a0b200341d0006a200341206a200541046a28020010e304024020032802504101470d00200041013602002000200c2902003702042000410c6a200c41086a2802003602000c2a0b200341d0006a200341206a2003280254280204220510e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c2a0b200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c2a0b2003200536024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c1e0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c290b200341d0006a200341206a200541046a28020028020810e304024020032802504101470d00200041013602002000200c2902003702042000410c6a200c41086a2802003602000c290b2003280254280204210d2005280204220628020441027421052006280200210602400340024020050d00200341d0006a200341206a200d10e4042003280250450d0220002003290350370204200041013602002000410c6a200341d8006a2802003602000c2b0b200341d0006a200341206a200628020010e304024020032802504101470d00200041013602002000200c2902003702042000410c6a200c41086a2802003602000c2b0b2005417c6a2105200641046a21062003280254280204200d460d000b412710282201450d1a2001411f6a41002900b1ef45370000200141186a41002900aaef45370000200141106a41002900a2ef45370000200141086a410029009aef4537000020014100290092ef45370000200041086a42a7808080f00437020020002001360204200041013602000c290b02404100280280b1464105490d004100280284b1462105200341c10036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003420437026c20034201370360200341f4eec50036025c2003410a360258200341cdf0c500360254200341053602504188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b2802101102000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102822010d01411741011037000b200b28020020064104746a41013a000c0c1d0b2001410f6a41002900ebee45370000200141086a41002900e4ee45370000200141002900dcee45370000200041086a4297808080f00237020020002001360204200041013602000c280b200341d0006a200341206a200a10e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c280b02404100280280b1464105490d004100280284b1462105200341c10036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003420437026c20034201370360200341f4eec50036025c2003410a360258200341cdf0c500360254200341053602504188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b2802101102000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102822010d01411741011037000b200b28020020064104746a41013a000c0c1c0b2001410f6a41002900ebee45370000200141086a41002900e4ee45370000200141002900dcee45370000200041086a4297808080f00237020020002001360204200041013602000c270b200341d0006a200541046a280200200210db04024020032802504101470d00200041013602002000200c2902003702042000410c6a200c41086a2802003602000c270b200341d0006a200341206a2003280254220528020810e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c270b200320052d000d410447220536024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c1b0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c260b2003200410fa03024002402003280204200541046a28020022054d0d002003280200220620054104746a220d0d010b410e10282201450d18200141066a41002900bfef45370000200141002900b9ef45370000200041086a428e808080e00137020020002001360204200041013602000c260b200341d0006a200341206a200620054104746a28020810e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c260b2003200d2d000d410447220536024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c1a0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c250b200341d0006a200341206a410110e4042003280250450d1820002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b200341d0006a200341206a410210e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b41012105200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b2003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c180b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c230b410121052003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c170b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c220b200341d0006a200341206a410110e4042003280250450d1520002003290350370204200041013602002000410c6a200341d8006a2802003602000c210b41012105200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c210b2003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c150b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c200b410121052003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c140b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c1f0b200341d0006a200341206a410110e4042003280250450d1220002003290350370204200041013602002000410c6a200341d8006a2802003602000c1e0b41012105200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1e0b2003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c120b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c1d0b200341d0006a200341206a410210e4042003280250450d1020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1c0b410121052003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c100b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c1b0b41012105200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1b0b2003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c0f0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c1a0b410121052003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c0e0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c190b41012105200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c190b2003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c0d0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c180b200341d0006a200341206a410210e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c180b410121052003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c0c0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c170b41012105200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c170b2003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c0b0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c160b200341d0006a200341206a410210e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c160b410121052003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c0a0b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c150b41012105200341d0006a200341206a410110e40402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c150b2003410136024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328024821050b024002402003280220220620056a220520064f0d00410e102822010d01410e41011037000b200320053602200c090b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c140b200b28020020064104746a41013a000c0c070b2005280200210620032005280208220536023802404100280280b1464105490d002003410136024c2003200341386a3602484100280284b1462105200341db0036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341c8efc50036025c2003410a360258200341cdf0c500360254200341053602502003200341c8006a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b280210110200200328023821050b200320053602202003200636024802404100280280b1464105490d002003410136023c2003200341c8006a3602384100280284b1462105200341e30036028801200342ed8080801037038001200341fcf0c50036027c20034125360278200341d7f0c5003602742003410136027020034201370360200341fceec50036025c2003410a360258200341cdf0c500360254200341053602502003200341386a36026c4188b1c60041b8aec600200541024622051b200341d0006a41c8b0c00041e0b0c00020051b28021011020020032802202105200328024821060b0240200520066a220620054f0d00410e102822010d11410e41011037000b200320063602200c060b41d0efc500200120051034000b200e41041037000b411741011037000b412741011037000b410e41011037000b411741011037000b200141016a22012008280200490d000c0a0b0b1031000b200641041037000b412741011037000b412541011037000b412541011037000b410f41011037000b410f41011037000b411341011037000b200141066a410029008aef4537000020014100290084ef45370000200041086a428e808080e00137020020002001360204200041013602000c010b20004100360200200020073602042003280228450d01200b280200102a0c010b2003280228450d00200b280200102a0b20034190016a24000bf50202057f017e02400240024020014108490d00200141017641feffffff07712202417f6a220320014f0d022001410d74200173220441117620047322044105742004732205417f2001417f6a677622067122044100200120042001491b6b220420014f0d01200020034103746a220329020021072003200020044103746a220429020037020020042007370200024020022001490d00200221030c030b2005410d7420057322044111762004732204410574200473220520067122044100200120042001491b6b220420014f0d01200020024103746a220329020021072003200020044103746a2204290200370200200420073702002002410172220320014f0d022005410d742005732204411176200473220441057420047320067122044100200120042001491b6b220420014f0d01200020034103746a220129020021072001200020044103746a2200290200370200200020073702000b0f0b41a8e9c500200420011034000b4198e9c500200320011034000bd50302047f017e024020014101762202450d0003402002417f6a2202210302400240024003402003410174220441017221050240200441026a220420014f0d00200520014f0d0220042005200020054103746a280200200020044103746a280200491b21050b200520014f0d03200320014f0d02200020034103746a2203280200200020054103746a22042802004f0d03200329020021062003200429020037020020042006370200200521030c000b0b41e8eac500200520011034000b41f8eac500200320011034000b20020d000b0b0240024020014102490d002001210403402004417f6a220420014f0d02200029020021062000200020044103746a2205290200370200200520063702004100210302400240024003402003410174220241017221050240200241026a220220044f0d00200520044f0d0220022005200020054103746a280200200020024103746a280200491b21050b200520044f0d03200320044f0d02200020034103746a2203280200200020054103746a22022802004f0d03200329020021062003200229020037020020022006370200200521030c000b0b41e8eac500200520041034000b41f8eac500200320041034000b200441014b0d000b0b0f0b41a8e9c500200420011034000bea04050a7f017e017f017e027f200041686a21022001417f6a2103200041086a2104410021052001413249210641012107024003400240024020072001490d00410021080c010b410121082000200741037422096a220a280200220b200a41786a280200490d00200420096a210803404101210a20032007460d03200741016a21072008280200220a200b4f2109200841086a2108200a210b20090d000b200720014921080b2007200146210a20060d0120072001460d010240024002400240024002402007417f6a220b20014f0d002008450d012000200b4103746a220b290200210c200b20002007410374220d6a2208290200220e3702002008200c37020020074102490d0520002007417e6a220a4103746a220f280200200ea722094d0d05200b200f290200370200200a450d0420002007417d6a220a4103746a28020020094d0d042002200d6a210b0340200b41086a200b290200370200200a450d03200a417f6a210a200b41786a220b28020020094b0d000b200a41016a210b0c030b4198e9c500200b20011034000b41a8e9c500200720011034000b4100210b0b2000200b4103746a210f0b200f200e3702000b200541016a21050240200120076b220a4102490d00200828020820082802004f0d002008290200210c20082008290208370200200841086a210f0240200a4103490d002008280210200ca722104f0d00200841106a21094103210b4102210d0340200d41037420086a220f41786a2009290200370200200b200a4f0d01200b4103742109200b210d200b41016a210b200820096a22092802002010490d000b0b200f200c3702000b20054105470d000b4100210a0b200a0bcc0201027f230041106b2202240020002802002802002100200128021841ebecc50041052001411c6a28020028020c1100002103200241003a0005200220033a00042002200136020020022000410c6a36020c200241f0ecc500410e2002410c6a4180edc500105c21012002200036020c20014190edc50041092002410c6a419cedc500105c21012002200041046a36020c200141acedc500410c2002410c6a419cedc500105c21012002200041086a36020c200141b8edc500410c2002410c6a419cedc500105c1a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d00200341eeafc0004102200111000021000c010b200341f0afc0004101200111000021000b200220003a00040b200241106a2400200041ff01714100470bc20201027f230041106b22022400200128021841ebecc50041052001411c6a28020028020c1100002103200241003a0005200220033a00042002200136020020022000410c6a36020c200241f0ecc500410e2002410c6a4180edc500105c21012002200036020c20014190edc50041092002410c6a419cedc500105c21012002200041046a36020c200141acedc500410c2002410c6a419cedc500105c21012002200041086a36020c200141b8edc500410c2002410c6a419cedc500105c1a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d00200341eeafc0004102200111000021000c010b200341f0afc0004101200111000021000b200220003a00040b200241106a2400200041ff01714100470b9b0201027f024002400240024002402001410c6a2802002203417f6a220420034d0d00411610282201450d01200020013602042001410e6a41002900ddf245370000200141086a41002900d7f245370000200141002900cff245370000200041086a4296808080e0023702000c040b0240200420026b220220044d0d00411b10282201450d0220002001360204200141176a41002800fcf245360000200141106a41002900f5f245370000200141086a41002900edf245370000200141002900e5f245370000200041086a429b808080b0033702000c040b200320024d0d022000200128020420024104746a360204200041003602000f0b411641011037000b411b41011037000b4180f3c500200220031034000b200041013602000bc50401027f230041d0006b220324002003200236020402404100280280b1464105490d002003410136020c2003200341046a3602084100280284b1462102200341c8006a41ef00360200200341c0006a42ed80808010370300200341386a4125360200200341306a4101360200200341206a4201370300200341186a410a360200200341fcf0c50036023c200341d7f0c5003602342003412c6a200341086a360200200341f8f1c50036021c200341cdf0c500360214200341053602104188b1c60041b8aec600200241024622021b200341106a41c8b0c00041e0b0c00020021b280210110200200328020421020b0240024002402002450d00200341106a2001410010e30420032802104101470d012000200341106a4104722202290200370200200041086a200241086a2802003602000c020b200041003602000c010b02400240024002402001280200220220032802142204280208460d00200220032802046b220420024d0d02410f102822020d01410f41011037000b024020042d000c0d00412510282202450d03200042a5808080d004370204200020023602002002411d6a410029009df245370000200241186a4100290098f245370000200241106a4100290090f245370000200241086a4100290088f24537000020024100290080f2453700000c040b200041003602000c030b2000428f808080f00137020420002002360200200241076a41002900acf245370000200241002900a5f2453700000c020b20004100360200200120043602000c010b412541011037000b200341d0006a24000bac0301047f230041c0006b2202240020002802002100410121030240200128021841baaec000410c2001411c6a28020028020c1100000d0002400240200028020822030d0020002802002203200028020428020c11070042e4aec285979ba58811520d012002200336020c2002412b36021420022002410c6a36021020012802182104200128021c2105410121032002413c6a41013602002002420237022c200241c8aec0003602282002200241106a36023820042005200241286a10350d020c010b2002200336020c2002412f36021420022002410c6a36021020012802182104200128021c2105410121032002413c6a41013602002002420237022c200241c8aec0003602282002200241106a36023820042005200241286a10350d010b200241106a41146a4101360200200241106a410c6a4101360200200241043602142002200041186a3602202002200041146a36021820022000410c6a36021020012802182100200128021c2101200241286a41146a41033602002002420337022c200241d8aec0003602282002200241106a36023820002001200241286a103521030b200241c0006a240020030b1500200120002802002200280200200028020410450b080020002001100b0bbe04020d7f017e230041c0006b22032400200128020022042001280208220541047422066a210720012802042108200421010240024002402005450d00200641706a2109200341306a410172210a200341306a41026a2106200341206a410172220b41076a210c20042101034020012d000021052006200141036a2d00003a00002003200141016a2f00003b01300240200541ac01470d00200141106a21010c020b2003410c6a41026a20062d0000220d3a0000200320032f0130220e3b010c200141046a280200210f200141086a2903002110200a200e3b0000200a41026a200d3a0000200320053a0030200320103703382003200f360234200341206a200341306a200210e9042003200b2900003703102003200c290000370017024020032d00202205411f470d00200941706a2109200141106a22012007470d010c030b0b200020053a000020002003290310370001200041086a200329001737000002402009450d00200141106a210103400240024020012d000022054109460d00200541ac01470d010c030b0240200141046a280200220528020441ffffffff0371450d002005280200102a0b2005102a0b200141106a22012007470d000b0b2008450d022004102a0c020b20012007460d0003400240024020012d000022054109460d00200541ac01470d010c030b0240200141046a280200220528020441ffffffff0371450d002005280200102a0b2005102a0b200141106a22012007470d000b0b02402008450d002004102a0b2000411f3a00000b200341c0006a24000bcbd60202097f017e230041106b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41003a00000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41013a00000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df501200441017422082005200820054b1b22084100480df5010240024020040d002008102821050c010b200628020020042008102c21050b2005450dad0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41023a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df501200441017422082005200820054b1b22084100480df5010240024020040d002008102821050c010b200628020020042008102c21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df401200441017422082005200820054b1b22084100480df4010240024020040d002008102821050c010b200628020020042008102c21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41033a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df401200441017422082005200820054b1b22084100480df4010240024020040d002008102821050c010b200628020020042008102c21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df301200441017422082005200820054b1b22084100480df3010240024020040d002008102821050c010b200628020020042008102c21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41043a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df301200441017422082005200820054b1b22084100480df3010240024020040d002008102821050c010b200628020020042008102c21050b2005450db00120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41053a00000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410b3a00000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490df001200441017422072006200720064b1b22074100480df0010240024020040d002007102821060c010b200928020020042007102c21060b2006450db00120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410c3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df1012004410174220a2006200a20064b1b220a4100480df1010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db201200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490def01200441017422072006200720064b1b22074100480def010240024020040d002007102821060c010b200928020020042007102c21060b2006450db10120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410d3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df0012004410174220a2006200a20064b1b220a4100480df0010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db301200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca4010b0b200241046a210902400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490dee01200441017422062005200620054b1b22064100480dee010240024020040d002006102821050c010b200928020020042006102c21050b2005450db20120022005360204200241086a20063602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a410e3a0000200320012802042204280204220520042802002204200420054102746a200210ea042003210420032d0000411f470d930320012802042802082105200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490def012004410174220a2006200a20064b1b220a4100480def010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db401200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca3010b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490ded01200441017422062005200620054b1b22064100480ded010240024020040d002006102821050c010b200228020420042006102c21050b2005450db30120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410f3a00000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490dec01200441017422072006200720064b1b22074100480dec010240024020040d002007102821060c010b200928020020042007102c21060b2006450db30120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41103a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490ded012004410174220a2006200a20064b1b220a4100480ded010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db501200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490deb01200441017422072006200720064b1b22074100480deb010240024020040d002007102821060c010b200928020020042007102c21060b2006450db40120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41113a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490dec012004410174220a2006200a20064b1b220a4100480dec010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db601200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b02400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490deb01200441017422062005200620054b1b22064100480deb010240024020040d002006102821050c010b200928020020042006102c21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a200b3a00000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dea01200441017422062005200620054b1b22064100480dea010240024020040d002006102821050c010b200228020420042006102c21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411a3a00000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490de901200441017422062005200620054b1b22064100480de9010240024020040d002006102821050c010b200228020420042006102c21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411b3a00000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de801200441017422072006200720064b1b22074100480de8010240024020040d002007102821060c010b200928020020042007102c21060b2006450db60120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41203a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de9012004410174220a2006200a20064b1b220a4100480de9010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db801200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de701200441017422072006200720064b1b22074100480de7010240024020040d002007102821060c010b200928020020042007102c21060b2006450db70120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41213a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de8012004410174220a2006200a20064b1b220a4100480de8010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db901200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de601200441017422072006200720064b1b22074100480de6010240024020040d002007102821060c010b200928020020042007102c21060b2006450db80120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41223a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de7012004410174220a2006200a20064b1b220a4100480de7010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450dba01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de501200441017422072006200720064b1b22074100480de5010240024020040d002007102821060c010b200928020020042007102c21060b2006450db90120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41233a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de6012004410174220a2006200a20064b1b220a4100480de6010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450dbb01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de401200441017422072006200720064b1b22074100480de4010240024020040d002007102821060c010b200928020020042007102c21060b2006450dba0120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41243a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de5012004410174220a2006200a20064b1b220a4100480de5010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450dbc01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c99010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de301200441017422082007200820074b1b22084100480de3010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dbb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41283a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de4012004410174220b2007200b20074b1b220b4100480de4010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dbd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de401200441017422092006200920064b1b22094100480de4010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dbe012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de201200441017422082007200820074b1b22084100480de2010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dbd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41293a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de3012004410174220b2007200b20074b1b220b4100480de3010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dbf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de301200441017422092006200920064b1b22094100480de3010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de101200441017422082007200820074b1b22084100480de1010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dbf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de2012004410174220b2007200b20074b1b220b4100480de2010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de201200441017422092006200920064b1b22094100480de2010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c96010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de001200441017422082007200820074b1b22084100480de0010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de1012004410174220b2007200b20074b1b220b4100480de1010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de101200441017422092006200920064b1b22094100480de1010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddf01200441017422082007200820074b1b22084100480ddf010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de0012004410174220b2007200b20074b1b220b4100480de0010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de001200441017422092006200920064b1b22094100480de0010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dde01200441017422082007200820074b1b22084100480dde010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddf012004410174220b2007200b20074b1b220b4100480ddf010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc701200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddf01200441017422092006200920064b1b22094100480ddf010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc8012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddd01200441017422082007200820074b1b22084100480ddd010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc70120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dde012004410174220b2007200b20074b1b220b4100480dde010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc901200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dde01200441017422092006200920064b1b22094100480dde010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dca012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddc01200441017422082007200820074b1b22084100480ddc010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc90120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412f3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddd012004410174220b2007200b20074b1b220b4100480ddd010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dcb01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddd01200441017422092006200920064b1b22094100480ddd010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dcc012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c91010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddb01200441017422082007200820074b1b22084100480ddb010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dcb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41303a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddc012004410174220b2007200b20074b1b220b4100480ddc010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dcd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddc01200441017422092006200920064b1b22094100480ddc010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dce012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dda01200441017422082007200820074b1b22084100480dda010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dcd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41313a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddb012004410174220b2007200b20074b1b220b4100480ddb010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dcf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddb01200441017422092006200920064b1b22094100480ddb010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd901200441017422082007200820074b1b22084100480dd9010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dcf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41323a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dda012004410174220b2007200b20074b1b220b4100480dda010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dda01200441017422092006200920064b1b22094100480dda010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd801200441017422082007200820074b1b22084100480dd8010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41333a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd9012004410174220b2007200b20074b1b220b4100480dd9010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd901200441017422092006200920064b1b22094100480dd9010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8d010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd701200441017422082007200820074b1b22084100480dd7010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41343a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd8012004410174220b2007200b20074b1b220b4100480dd8010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd801200441017422092006200920064b1b22094100480dd8010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd601200441017422082007200820074b1b22084100480dd6010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41353a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da3022004410174220b2007200b20074b1b220b4100480da3020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da302200441017422092006200920064b1b22094100480da3020240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8b010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da102200441017422082007200820074b1b22084100480da1020240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41363a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da2022004410174220b2007200b20074b1b220b4100480da2020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dda01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da202200441017422092006200920064b1b22094100480da2020240024020040d002009102821060c010b200a28020020042009102c21060b2006450ddb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da002200441017422082007200820074b1b22084100480da0020240024020040d002008102821070c010b200a28020020042008102c21070b2007450dda0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41373a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da1022004410174220b2007200b20074b1b220b4100480da1020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450ddc01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da102200441017422092006200920064b1b22094100480da1020240024020040d002009102821060c010b200a28020020042009102c21060b2006450ddd012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c89010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9f02200441017422082007200820074b1b22084100480d9f020240024020040d002008102821070c010b200a28020020042008102c21070b2007450ddc0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41383a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da0022004410174220b2007200b20074b1b220b4100480da0020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dde01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da002200441017422092006200920064b1b22094100480da0020240024020040d002009102821060c010b200a28020020042009102c21060b2006450ddf012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9e02200441017422082007200820074b1b22084100480d9e020240024020040d002008102821070c010b200a28020020042008102c21070b2007450dde0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41393a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9f022004410174220b2007200b20074b1b220b4100480d9f020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de001200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9f02200441017422092006200920064b1b22094100480d9f020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de1012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9d02200441017422082007200820074b1b22084100480d9d020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de00120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9e022004410174220b2007200b20074b1b220b4100480d9e020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de201200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9e02200441017422092006200920064b1b22094100480d9e020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de3012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9c02200441017422082007200820074b1b22084100480d9c020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de20120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9d022004410174220b2007200b20074b1b220b4100480d9d020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de401200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9d02200441017422092006200920064b1b22094100480d9d020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de5012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c85010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9b02200441017422082007200820074b1b22084100480d9b020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de40120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9c022004410174220b2007200b20074b1b220b4100480d9c020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de601200220073602042009200b360200200828020021040b2008200441016a360200200720046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021050c010b200441016a22052004490d9c02200441017422092005200920054b1b22094100480d9c020240024020040d002009102821050c010b200a28020020042009102c21050b2005450de7012002200536020420082009360200200728020021040b2007200441016a360200200520046a200641807f72200641ff0071200641077622041b3a00002004210620040d000c84010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9a02200441017422082007200820074b1b22084100480d9a020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de60120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9b022004410174220b2007200b20074b1b220b4100480d9b020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9b02200441017422092006200920064b1b22094100480d9b020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c83010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9902200441017422082007200820074b1b22084100480d99020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9a022004410174220b2007200b20074b1b220b4100480d9a020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dea01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9a02200441017422092006200920064b1b22094100480d9a020240024020040d002009102821060c010b200a28020020042009102c21060b2006450deb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9802200441017422082005200820054b1b22084100480d98020240024020040d002008102821050c010b200628020020042008102c21050b2005450dea0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a413f3a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d9802200441017422082005200820054b1b22084100480d98020240024020040d002008102821050c010b200628020020042008102c21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9702200441017422082005200820054b1b22084100480d97020240024020040d002008102821050c010b200628020020042008102c21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c0003a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d9702200441017422082005200820054b1b22084100480d97020240024020040d002008102821050c010b200628020020042008102c21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9602200441017422072005200720054b1b22074100480d96020240024020040d002007102821050c010b200228020420042007102c21050b2005450dec0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c1003a000020032006200210eb042003210420032d0000411f470def020c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9502200441017422062005200620054b1b22064100480d95020240024020040d002006102821050c010b200228020420042006102c21050b2005450dec0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c2003a00002003200c200210ec042003210420032d0000411f470dee020c7d0b200241046a2106200141046a280200210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9402200441017422082005200820054b1b22084100480d94020240024020040d002008102821050c010b200628020020042008102c21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c3003a000002400240200241086a2802002205200828020022046b4104490d00200628020021050c010b200441046a22082004490d9402200541017422042008200420084b1b22044100480d94020240024020050d002004102821050c010b200628020020052004102c21050b2005450ded0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441046a360200200520046a20073600000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9302200441017422072005200720054b1b22074100480d93020240024020040d002007102821050c010b200628020020042007102c21050b2005450ded0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a41c4003a000002400240200241086a2802002205200728020022046b4108490d00200628020021050c010b200441086a22072004490d9302200541017422042007200420074b1b22044100480d93020240024020050d002004102821050c010b200628020020052004102c21050b2005450dee0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441086a360200200520046a200c3700000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9202200441017422062005200620054b1b22064100480d92020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c5003a00000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9102200441017422062005200620054b1b22064100480d91020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c6003a00000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9002200441017422062005200620054b1b22064100480d90020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c7003a00000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f02200441017422062005200620054b1b22064100480d8f020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c8003a00000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e02200441017422062005200620054b1b22064100480d8e020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c9003a00000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d02200441017422062005200620054b1b22064100480d8d020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ca003a00000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c02200441017422062005200620054b1b22064100480d8c020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cb003a00000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b02200441017422062005200620054b1b22064100480d8b020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cc003a00000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a02200441017422062005200620054b1b22064100480d8a020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cd003a00000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8902200441017422062005200620054b1b22064100480d89020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ce003a00000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8802200441017422062005200620054b1b22064100480d88020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cf003a00000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8702200441017422062005200620054b1b22064100480d87020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d0003a00000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8602200441017422062005200620054b1b22064100480d86020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d1003a00000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8502200441017422062005200620054b1b22064100480d85020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d2003a00000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8402200441017422062005200620054b1b22064100480d84020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d3003a00000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8302200441017422062005200620054b1b22064100480d83020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d4003a00000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8202200441017422062005200620054b1b22064100480d82020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d5003a00000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8102200441017422062005200620054b1b22064100480d81020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d6003a00000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8002200441017422062005200620054b1b22064100480d80020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d7003a00000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff01200441017422062005200620054b1b22064100480dff010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d8003a00000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe01200441017422062005200620054b1b22064100480dfe010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d9003a00000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd01200441017422062005200620054b1b22064100480dfd010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41da003a00000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc01200441017422062005200620054b1b22064100480dfc010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41db003a00000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb01200441017422062005200620054b1b22064100480dfb010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dc003a00000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa01200441017422062005200620054b1b22064100480dfa010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dd003a00000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df901200441017422062005200620054b1b22064100480df9010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41de003a00000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df801200441017422062005200620054b1b22064100480df8010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41df003a00000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e0003a00000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e1003a00000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df501200441017422062005200620054b1b22064100480df5010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e2003a00000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df401200441017422062005200620054b1b22064100480df4010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e3003a00000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df301200441017422062005200620054b1b22064100480df3010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e4003a00000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e5003a00000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e6003a00000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df001200441017422062005200620054b1b22064100480df0010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e7003a00000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490def01200441017422062005200620054b1b22064100480def010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e8003a00000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dba02200441017422062005200620054b1b22064100480dba020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e9003a00000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db902200441017422062005200620054b1b22064100480db9020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ea003a00000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db802200441017422062005200620054b1b22064100480db8020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41eb003a00000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db702200441017422062005200620054b1b22064100480db7020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ec003a00000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db602200441017422062005200620054b1b22064100480db6020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ed003a00000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db502200441017422062005200620054b1b22064100480db5020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ee003a00000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db402200441017422062005200620054b1b22064100480db4020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ef003a00000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db302200441017422062005200620054b1b22064100480db3020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f0003a00000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db202200441017422062005200620054b1b22064100480db2020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f1003a00000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db102200441017422062005200620054b1b22064100480db1020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f2003a00000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db002200441017422062005200620054b1b22064100480db0020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f3003a00000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daf02200441017422062005200620054b1b22064100480daf020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f4003a00000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dae02200441017422062005200620054b1b22064100480dae020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f5003a00000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad02200441017422062005200620054b1b22064100480dad020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f6003a00000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac02200441017422062005200620054b1b22064100480dac020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f7003a00000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dab02200441017422062005200620054b1b22064100480dab020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f8003a00000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daa02200441017422062005200620054b1b22064100480daa020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f9003a00000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da902200441017422062005200620054b1b22064100480da9020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fa003a00000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da802200441017422062005200620054b1b22064100480da8020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fb003a00000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da702200441017422062005200620054b1b22064100480da7020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fc003a00000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da602200441017422062005200620054b1b22064100480da6020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fd003a00000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da502200441017422062005200620054b1b22064100480da5020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fe003a00000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da402200441017422062005200620054b1b22064100480da4020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ff003a00000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da302200441017422062005200620054b1b22064100480da3020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4180013a00000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da202200441017422062005200620054b1b22064100480da2020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4181013a00000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da102200441017422062005200620054b1b22064100480da1020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4182013a00000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da002200441017422062005200620054b1b22064100480da0020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4183013a00000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f02200441017422062005200620054b1b22064100480d9f020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4184013a00000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9e02200441017422062005200620054b1b22064100480d9e020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4185013a00000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9d02200441017422062005200620054b1b22064100480d9d020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4186013a00000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9c02200441017422062005200620054b1b22064100480d9c020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4187013a00000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9b02200441017422062005200620054b1b22064100480d9b020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4188013a00000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9a02200441017422062005200620054b1b22064100480d9a020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4189013a00000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9902200441017422062005200620054b1b22064100480d99020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418a013a00000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9802200441017422062005200620054b1b22064100480d98020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418b013a00000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9702200441017422062005200620054b1b22064100480d97020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418c013a00000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9602200441017422062005200620054b1b22064100480d96020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418d013a00000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9502200441017422062005200620054b1b22064100480d95020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418e013a00000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9402200441017422062005200620054b1b22064100480d94020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418f013a00000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9302200441017422062005200620054b1b22064100480d93020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4190013a00000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9202200441017422062005200620054b1b22064100480d92020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4191013a00000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9102200441017422062005200620054b1b22064100480d91020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4192013a00000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9002200441017422062005200620054b1b22064100480d90020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4193013a00000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f02200441017422062005200620054b1b22064100480d8f020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4194013a00000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e02200441017422062005200620054b1b22064100480d8e020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4195013a00000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d02200441017422062005200620054b1b22064100480d8d020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4196013a00000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c02200441017422062005200620054b1b22064100480d8c020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4197013a00000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b02200441017422062005200620054b1b22064100480d8b020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4198013a00000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a02200441017422062005200620054b1b22064100480d8a020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4199013a00000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8902200441017422062005200620054b1b22064100480d89020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419a013a00000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8802200441017422062005200620054b1b22064100480d88020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419b013a00000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8702200441017422062005200620054b1b22064100480d87020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419c013a00000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8602200441017422062005200620054b1b22064100480d86020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419d013a00000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8502200441017422062005200620054b1b22064100480d85020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419e013a00000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8402200441017422062005200620054b1b22064100480d84020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419f013a00000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8302200441017422062005200620054b1b22064100480d83020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a0013a00000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8202200441017422062005200620054b1b22064100480d82020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a1013a00000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8102200441017422062005200620054b1b22064100480d81020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a2013a00000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8002200441017422062005200620054b1b22064100480d80020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a3013a00000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff01200441017422062005200620054b1b22064100480dff010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a4013a00000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe01200441017422062005200620054b1b22064100480dfe010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a5013a00000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd01200441017422062005200620054b1b22064100480dfd010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a6013a00000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc01200441017422062005200620054b1b22064100480dfc010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a7013a00000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb01200441017422062005200620054b1b22064100480dfb010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a8013a00000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa01200441017422062005200620054b1b22064100480dfa010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a9013a00000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df901200441017422062005200620054b1b22064100480df9010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41aa013a00000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df801200441017422062005200620054b1b22064100480df8010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ab013a00000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ac013a00000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ad013a00000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df501200441017422062005200620054b1b22064100480df5010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ae013a00000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df401200441017422062005200620054b1b22064100480df4010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41af013a00000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df301200441017422062005200620054b1b22064100480df3010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b0013a00000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b1013a00000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b2013a00000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df001200441017422062005200620054b1b22064100480df0010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b3013a00000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc01200441017422062005200620054b1b22064100480dfc010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b4013a00000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb01200441017422062005200620054b1b22064100480dfb010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b5013a00000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa01200441017422062005200620054b1b22064100480dfa010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b6013a00000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df901200441017422062005200620054b1b22064100480df9010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b7013a00000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df801200441017422062005200620054b1b22064100480df8010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b8013a00000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b9013a00000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ba013a00000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df501200441017422062005200620054b1b22064100480df5010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bb013a00000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df401200441017422062005200620054b1b22064100480df4010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bc013a00000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df301200441017422062005200620054b1b22064100480df3010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bd013a00000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41be013a00000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bf013a00000b2000411f3a000020012d00004109470df1010240200141046a280200220228020441ffffffff0371450d002002280200102a200128020421020b2002102a0cf1010b200641011037000b200641011037000b200841011037000b200841011037000b200841011037000b200841011037000b200841011037000b200841011037000b200641011037000b200641011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200641011037000b200a41011037000b200641011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200641011037000b200641011037000b200641011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b1031000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200841011037000b200841011037000b200841011037000b200741011037000b200641011037000b200841011037000b200441011037000b200741011037000b200441011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b1031000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b1031000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b1031000b20002004290200370200200041086a200441086a29020037020020012d00004109470d000240200141046a280200220228020441ffffffff0371450d002002280200102a200128020421020b2002102a0b200341106a24000bb60301057f2004410c6a2105200441086a2106024002400240034002400240200628020020052802002207460d00200428020421080c010b200741016a22082007490d04200741017422092008200920084b1b22094100480d040240024020070d002009102821080c010b200428020420072009102c21080b2008450d022004200836020420062009360200200528020021070b2005200741016a360200200820076a200141807f72200141ff0071200141077622071b3a00002007210120070d000b024020022003460d002004410c6a2105200441086a2106034020022802002101034002400240200628020020052802002207460d00200428020421080c010b200741016a22082007490d06200741017422092008200920084b1b22094100480d060240024020070d002009102821080c010b200428020420072009102c21080b2008450d052004200836020420062009360200200528020021070b2005200741016a360200200820076a200141807f72200141ff0071200141077622071b3a00002007210120070d000b200241046a22022003470d000b0b2000411f3a00000f0b200941011037000b200941011037000b1031000baf0301067f024002400240024020014107752203200141c00071220472452003417f4720044572460d002002410c6a2105200241086a2106034002400240200628020020052802002204460d00200228020421070c010b200441016a22072004490d05200441017422082007200820074b1b22084100480d050240024020040d002008102821070c010b200228020420042008102c21070b2007450d032002200736020420062008360200200528020021040b2005200441016a360200200720046a200141807f723a0000200341c000712104200321012003410775220721032007200472452007417f4720044572470d000b0b02400240200241086a2802002002410c6a2802002204460d00200228020421030c010b200441016a22032004490d03200441017422072003200720034b1b22074100480d030240024020040d002007102821030c010b200228020420042007102c21030b2003450d0220022003360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200320046a200141ff00713a00002000411f3a00000f0b200841011037000b200741011037000b1031000bb30302017e067f024002400240024020014207872203502001a7220441c00071452205712003427f52200572460d002002410c6a2106200241086a2107034002400240200728020020062802002205460d00200228020421080c010b200541016a22082005490d05200541017422092008200920084b1b22094100480d050240024020050d002009102821080c010b200228020420052009102c21080b2008450d032002200836020420072009360200200628020021050b2006200541016a360200200820056a200441807f723a00002003a72104200342078722012103200150200441c00071452205712001427f52200572470d000b0b02400240200241086a2802002002410c6a2802002205460d00200228020421080c010b200541016a22082005490d03200541017422062008200620084b1b22064100480d030240024020050d002006102821080c010b200228020420052006102c21080b2008450d0220022008360204200241086a20063602002002410c6a28020021050b2002410c6a200541016a360200200820056a200441ff00713a00002000411f3a00000f0b200941011037000b200641011037000b1031000be103010a7f230041306b22022400200241216a220341076a210441002105410021064100210741002108410821090240024002400340200241186a200110ee04024020022802184101470d002000200229021c370204200041013602002000410c6a200241186a410c6a29020037020002402007450d00200921070340024020072d00004109470d000240200741046a220a280200220528020441ffffffff0371450d002005280200102a200a28020021050b2005102a0b200741106a2107200641706a22060d000b0b2008450d042009102a0c040b200220032900003703082002200429000037000f20022d0020210a2002200229000f37001f200220022903083703180240024020072008470d00200741016a220b2007490d032005200b2005200b4b1b220841ffffffff00712008470d032008410474220b4100480d030240024020070d00200b102821090c010b20092006200b102c21090b2009450d010b200920066a220b200a3a0000200b41016a2002290318370000200b41086a200229001f370000200541026a2105200641106a2106200741016a2107200a41ff01714106460d030c010b0b200b41081037000b1031000b20002009360204200041003602002000410c6a2007360200200041086a20083602000b200241306a24000b80b601020b7f017e230041f0006b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490d02200320054f0d0120052003103c000b200241013a0048200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1033200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c640b2001280200220620046a2d000021072001410c6a2208200536020002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200741bf014b0d0020070ec001b902b902010203b90200000000000405060708090a00000000000000000b0c000000000d0e0f101100000012131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901b9020b2000410b3a000420004101360200200041056a20073a00000cbc020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da302200620056a2c00002101200820093602004100210a0240200141004e0d00411921090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410221070cbf020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a1033200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbf020b4102210a410221070cba020b4103210a410221070cb9020b4101210a0b410221070cb7020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da302200620056a2c00002101200820093602004100210a0240200141004e0d00411921090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410321070cbe020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a1033200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbe020b4102210a410321070cb9020b4103210a410321070cb8020b4101210a0b410321070cb6020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da302200620056a2c00002101200820093602004100210a0240200141004e0d00411921090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410421070cbd020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a1033200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbd020b4102210a410421070cb8020b4103210a410421070cb7020b4101210a0b410421070cb5020b410621070cb4020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb8020b410721070cb3020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb7020b410821070cb2020b200241d8006a200110ef044104210a200228025822074101460da201200241e0006a280200210b41002106200228025c210c02400240200241e4006a280200220941027422050d00410021040c010b2005410275220441ffffffff03712004470dda01200441027422034100480dda0120031028220a450dd9010b02402009450d00200941027421032005417c6a2106200a2109200c2105034020092005280200360200200941046a2109200541046a21052003417c6a22030d000b200641027641016a21060b0240200b450d00200c102a0b20022d005c4105470db0022007450db00220022802640da3010cb0020b410a21070cb0020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb4020b410b21070caf020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22044f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210720082004360200200741ff00712001411f71742009722109200141076a2101200421052007418001710d000b20014120490d01410d210120074110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb3020b0240024020032004460d00200441016a22012004490ddb01200320014f0d0120012003103c000b200241013a0048200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1033200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000cb3020b200620046a2d0000210520082001360200024020050d00410c21074100210a0caf020b200041163a000420004101360200200041056a20053a00000cb2020b410d21070cad020b410e21070cac020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb0020b410f21070cab020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000caf020b411021070caa020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cae020b411121070ca9020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cad020b411221070ca8020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cac020b411321070ca7020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddd01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000cab020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9c010b20032001460d9a012001417f460dd9012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9b010b200aad210d411421070ca6020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dde01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000caa020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9d010b20032001460d9b012001417f460dda012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9c010b200aad210d411521070ca5020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddf01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca9020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9e010b20032001460d9c012001417f460ddb012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9d010b200aad210d411621070ca4020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de001200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca8020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9f010b20032001460d9d012001417f460ddc012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9e010b200aad210d411721070ca3020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de101200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca7020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca0010b20032001460d9e012001417f460ddd012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9f010b200aad210d411821070ca2020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de201200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca6020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca1010b20032001460d9f012001417f460dde012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da0010b200aad210d411921070ca1020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de301200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca5020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca2010b20032001460da0012001417f460ddf012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da1010b200aad210d411a21070ca0020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de401200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca4020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca3010b20032001460da1012001417f460de0012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da2010b200aad210d411b21070c9f020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de501200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca3020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca4010b20032001460da2012001417f460de1012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da3010b200aad210d411c21070c9e020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de601200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca2020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca5010b20032001460da3012001417f460de2012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da4010b200aad210d411d21070c9d020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de701200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca1020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca6010b20032001460da4012001417f460de3012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da5010b200aad210d411e21070c9c020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de801200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca0020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca7010b20032001460da5012001417f460de4012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da6010b200aad210d411f21070c9b020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de901200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9f020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca8010b20032001460da6012001417f460de5012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b41202107024020054120490d00410d21012004410f4b0da7010b200aad210d0c9a020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dea01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9e020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca9010b20032001460da7012001417f460de6012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da8010b200aad210d412121070c99020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450deb01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9d020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010caa010b20032001460da8012001417f460de7012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da9010b200aad210d412221070c98020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dec01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cab010b20032001460da9012001417f460de8012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0daa010b200aad210d412321070c97020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ded01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9b020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cac010b20032001460daa012001417f460de9012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dab010b200aad210d412421070c96020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dee01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9a020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cad010b20032001460dab012001417f460dea012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dac010b200aad210d412521070c95020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450def01200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c99020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cae010b20032001460dac012001417f460deb012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dad010b200aad210d412621070c94020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df001200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c98020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010caf010b20032001460dad012001417f460dec012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dae010b200aad210d412721070c93020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df101200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c97020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb0010b20032001460dae012001417f460ded012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0daf010b200aad210d412821070c92020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df201200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c96020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb1010b20032001460daf012001417f460dee012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0db0010b200aad210d412921070c91020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df301200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c95020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb2010b20032001460db0012001417f460def012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0db1010b200aad210d412a21070c90020b0240024020032005460d00200441026a21012005417f460df001200320014f0d0120012003103c000b200241013a0048200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1033200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c94020b200620056a2d0000210920082001360200024020090d00412b21074100210a0c90020b200041153a000420004101360200200041056a20093a00000c93020b0240024020032005460d00200441026a21012005417f460df001200320014f0d0120012003103c000b200241013a0048200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1033200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c93020b200620056a2d0000210920082001360200024020090d00412c21074100210a0c8f020b200041153a000420004101360200200041056a20093a00000c92020b41002101410021090240024002400340410d210a2001411f4b0d010240024020032005460d002005417f460df4012003200541016a22074f0d01200541016a2003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a10334105210a0c020b200620056a2c0000210420082007360200200441ff00712001411f71742009722109200141076a21012007210520044100480d000b200441c00071210502402001411f4b0d0020050d020b0240024020014120490d0020050d010b200441ff01714108490d0320014120490d032005450d010c030b20044180017241ff017141f7014b0d020b2000200a36020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c93020b2009417f2001411f71747221090b412d21070c8d020b4200210d4100210102400240024002400340410e21072001413f4b0d010240024020032005460d002005417f460df5012003200541016a22094f0d01200541016a2003103c000b200241013a0008200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241086a360238200241286a200241d8006a10332002290328210d20022802302101410521070c030b200620056a2d0000210420082009360200200441ff0071220aad2001413f71ad86200d84210d200141076a210120092105200441187441187522094100480d000b200941c00071210502402001413f4b0d0020050d030b02400240200141c000490d0020050d010b200141c000490d0420090d010c040b200a41ff00460d030b0b200020073a0004200020022f00183b000520004101360200200041106a2001360200200041086a200d370200200041076a2002411a6a2d00003a00000c92020b200d427f2001413f71ad8684210d0b412e21070c8c020b02400240200320056b4104490d00200441056a21012005417b4b0df001200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a103320004281808080d000370300200041086a2002290228370200200041106a200241286a41086a2802003602000c90020b200620056a280000210920082001360200412f21070c8b020b02400240200320056b4108490d00200441096a2101200541774b0df001200320014f0d0120012003103c000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a10332002290328210d200041106a2002280230360200200041086a200d37020020004281808080d0003703000c8f020b200620056a290000210d20082001360200413021070c8a020b413121070c89020b413221070c88020b413321070c87020b413421070c86020b413521070c85020b413621070c84020b413721070c83020b413821070c82020b413921070c81020b413a21070c80020b413b21070cff010b413c21070cfe010b413d21070cfd010b413e21070cfc010b413f21070cfb010b41c00021070cfa010b41c10021070cf9010b41c20021070cf8010b41c30021070cf7010b41c40021070cf6010b41c50021070cf5010b41c60021070cf4010b41c70021070cf3010b41c80021070cf2010b41c90021070cf1010b41ca0021070cf0010b41cb0021070cef010b41cc0021070cee010b41cd0021070ced010b41ce0021070cec010b41cf0021070ceb010b41d00021070cea010b41d10021070ce9010b41d20021070ce8010b41d30021070ce7010b41d40021070ce6010b41d50021070ce5010b41d60021070ce4010b41d70021070ce3010b41d80021070ce2010b41d90021070ce1010b41da0021070ce0010b41db0021070cdf010b41dc0021070cde010b41dd0021070cdd010b41de0021070cdc010b41df0021070cdb010b41e00021070cda010b41e10021070cd9010b41e20021070cd8010b41e30021070cd7010b41e40021070cd6010b41e50021070cd5010b41e60021070cd4010b41e70021070cd3010b41e80021070cd2010b41e90021070cd1010b41ea0021070cd0010b41eb0021070ccf010b41ec0021070cce010b41ed0021070ccd010b41ee0021070ccc010b41ef0021070ccb010b41f00021070cca010b41f10021070cc9010b41f20021070cc8010b41f30021070cc7010b41f40021070cc6010b41f50021070cc5010b41f60021070cc4010b41f70021070cc3010b41f80021070cc2010b41f90021070cc1010b41fa0021070cc0010b41fb0021070cbf010b41fc0021070cbe010b41fd0021070cbd010b41fe0021070cbc010b41ff0021070cbb010b41800121070cba010b41810121070cb9010b41820121070cb8010b41830121070cb7010b41840121070cb6010b41850121070cb5010b41860121070cb4010b41870121070cb3010b41880121070cb2010b41890121070cb1010b418a0121070cb0010b418b0121070caf010b418c0121070cae010b418d0121070cad010b418e0121070cac010b418f0121070cab010b41900121070caa010b41910121070ca9010b41920121070ca8010b41930121070ca7010b41940121070ca6010b41950121070ca5010b41960121070ca4010b41970121070ca3010b41980121070ca2010b41990121070ca1010b419a0121070ca0010b419b0121070c9f010b419c0121070c9e010b419d0121070c9d010b419e0121070c9c010b419f0121070c9b010b41a00121070c9a010b41a10121070c99010b41a20121070c98010b41a30121070c97010b41a40121070c96010b41a50121070c95010b41a60121070c94010b41a70121070c93010b41a80121070c92010b41a90121070c91010b41aa0121070c90010b41ab0121070c8f010b200041013602002000200241d8006a41047222012902003702042000410c6a200141086a2902003702000c92010b2002280260102a0c8c010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8f010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8d010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8b010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c89010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c87010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c85010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c83010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c81010b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7f0b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7d0b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7b0b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c790b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c770b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c750b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c730b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c710b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6f0b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6d0b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6b0b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c690b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c670b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c650b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c630b417f20051044000b417f20091044000b417f20091044000b417f20091044000b417f200541016a1044000b417f200541016a1044000b200341041037000b1031000b417f200541016a1044000b417f200541016a1044000b417f20011044000b417f200541016a1044000b417f200541016a1044000b417f200541016a1044000b417f200541016a1044000b417f200541016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f200141016a1044000b417f20011044000b417f20011044000b417f200541016a1044000b417f200541016a1044000b200520011044000b200520011044000b20092003103c000b20092003103c000b20092003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b200141016a2003103c000b02400240024002400240024020042006460d0020042006490d01024020060d00024020040d004104210a0c020b200a102a4104210a0c010b200a200441027420064102742209102c220a450d020b4100210941002104034002402009411f4d0d00410f21010c0a0b20012802082207200128020c2205460d08200541016a22032005490d0320072003490d04200128020020056a2d0000210520082003360200200541ff00712009411f71742004722104200941076a21092005418001710d000b20094120490d04410d21012005410f4b0d080c040b41dcfdc5001032000b200941041037000b417f20031044000b20032007103c000b410c10282209450d0120092004360208200920063602042009200a360200410921070b20004100360200200041106a200d3703002000410c6a2009360200200041096a200a3a0000200041086a20073a00000c030b410c41041037000b200241013a0018200241ec006a41013602002002420137025c200241a4e2c5003602582002412636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1033410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a280200360200200641ffffffff0371450d00200a102a0b200241f0006a24000bd60703067f017e067f230041d0006b220224004100210341002104024002400240024002400240024002400240024002400240034002402003411f4d0d00410f21030c020b0240024020012802082205200128020c2206460d00200641016a22072006490d05200520074f0d0120072005103c000b200241013a0027200241cc006a41013602002002420137023c200241a4e2c5003602382002412636021c2002200241186a3602482002200241276a360218200241286a200241386a1033410521030c020b200128020020066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b20034120490d01410d210320064110490d010b200241086a41086a200241286a41086a280200220136020020022002290228220837030820002003360204200041086a2008370200200041106a2001360200200041013602000c0a0b20024100360210200242043703082004450d0841042109410021034100210a03402003210b200a220c41016a210a410021034100210503402003411f4b0d04024002402001280208220d200128020c2206460d00200641016a22072006490d05200d20074f0d012007200d103c000b2002200b36020c2002200c360210200241013a0027200241cc006a41013602002002420137023c200241a4e2c5003602382002412636021c2002200241186a3602482002200241276a360218200241286a200241386a103320022802282103200228022c2106200228023021074100210e410521010c090b200128020020066a2d000021062001200736020c200641ff00712003411f71742005722105200341076a21032006418001710d000b024020034120490d002006410f4d0d002002200b36020c2002200c360210410d21010c070b02400240200c200b460d00200b2103200c210b0c010b200b41016a2203200b490d06200b41017422062003200620034b1b220341ffffffff03712003470d06200341027422064100480d0602400240200b0d002006102821090c010b2009200b4102742006102c21090b2009450d05200220093602080b2005410876210e2009200b4102746a2005360200200a2004460d080c000b0b417f20071044000b417f20071044000b2002200b36020c2002200c360210410f21010c020b200641041037000b1031000b0b20004101360200200041106a20073602002000410c6a2006360200200041086a20033602002000200e410874200172360204200b450d022009102a0c020b2002200336020c2002200a3602100b20002002290308370204200041003602002000410c6a200241106a2802003602000b200241d0006a24000bcbd60202097f017e230041106b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41003a00000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41013a00000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df501200441017422082005200820054b1b22084100480df5010240024020040d002008102821050c010b200628020020042008102c21050b2005450dad0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41023a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df501200441017422082005200820054b1b22084100480df5010240024020040d002008102821050c010b200628020020042008102c21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df401200441017422082005200820054b1b22084100480df4010240024020040d002008102821050c010b200628020020042008102c21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41033a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df401200441017422082005200820054b1b22084100480df4010240024020040d002008102821050c010b200628020020042008102c21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df301200441017422082005200820054b1b22084100480df3010240024020040d002008102821050c010b200628020020042008102c21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41043a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df301200441017422082005200820054b1b22084100480df3010240024020040d002008102821050c010b200628020020042008102c21050b2005450db00120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41053a00000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410b3a00000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490df001200441017422072006200720064b1b22074100480df0010240024020040d002007102821060c010b200928020020042007102c21060b2006450db00120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410c3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df1012004410174220a2006200a20064b1b220a4100480df1010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db201200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490def01200441017422072006200720064b1b22074100480def010240024020040d002007102821060c010b200928020020042007102c21060b2006450db10120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410d3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df0012004410174220a2006200a20064b1b220a4100480df0010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db301200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca4010b0b200241046a210902400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490dee01200441017422062005200620054b1b22064100480dee010240024020040d002006102821050c010b200928020020042006102c21050b2005450db20120022005360204200241086a20063602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a410e3a0000200320012802042204280204220520042802002204200420054102746a200210ea042003210420032d0000411f470d930320012802042802082105200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490def012004410174220a2006200a20064b1b220a4100480def010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db401200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca3010b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490ded01200441017422062005200620054b1b22064100480ded010240024020040d002006102821050c010b200228020420042006102c21050b2005450db30120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410f3a00000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490dec01200441017422072006200720064b1b22074100480dec010240024020040d002007102821060c010b200928020020042007102c21060b2006450db30120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41103a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490ded012004410174220a2006200a20064b1b220a4100480ded010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db501200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490deb01200441017422072006200720064b1b22074100480deb010240024020040d002007102821060c010b200928020020042007102c21060b2006450db40120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41113a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490dec012004410174220a2006200a20064b1b220a4100480dec010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db601200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b02400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490deb01200441017422062005200620054b1b22064100480deb010240024020040d002006102821050c010b200928020020042006102c21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a200b3a00000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dea01200441017422062005200620054b1b22064100480dea010240024020040d002006102821050c010b200228020420042006102c21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411a3a00000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490de901200441017422062005200620054b1b22064100480de9010240024020040d002006102821050c010b200228020420042006102c21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411b3a00000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de801200441017422072006200720064b1b22074100480de8010240024020040d002007102821060c010b200928020020042007102c21060b2006450db60120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41203a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de9012004410174220a2006200a20064b1b220a4100480de9010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db801200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de701200441017422072006200720064b1b22074100480de7010240024020040d002007102821060c010b200928020020042007102c21060b2006450db70120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41213a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de8012004410174220a2006200a20064b1b220a4100480de8010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450db901200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de601200441017422072006200720064b1b22074100480de6010240024020040d002007102821060c010b200928020020042007102c21060b2006450db80120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41223a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de7012004410174220a2006200a20064b1b220a4100480de7010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450dba01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de501200441017422072006200720064b1b22074100480de5010240024020040d002007102821060c010b200928020020042007102c21060b2006450db90120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41233a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de6012004410174220a2006200a20064b1b220a4100480de6010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450dbb01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de401200441017422072006200720064b1b22074100480de4010240024020040d002007102821060c010b200928020020042007102c21060b2006450dba0120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41243a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de5012004410174220a2006200a20064b1b220a4100480de5010240024020040d00200a102821060c010b20092802002004200a102c21060b2006450dbc01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c99010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de301200441017422082007200820074b1b22084100480de3010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dbb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41283a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de4012004410174220b2007200b20074b1b220b4100480de4010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dbd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de401200441017422092006200920064b1b22094100480de4010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dbe012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de201200441017422082007200820074b1b22084100480de2010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dbd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41293a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de3012004410174220b2007200b20074b1b220b4100480de3010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dbf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de301200441017422092006200920064b1b22094100480de3010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de101200441017422082007200820074b1b22084100480de1010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dbf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de2012004410174220b2007200b20074b1b220b4100480de2010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de201200441017422092006200920064b1b22094100480de2010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c96010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de001200441017422082007200820074b1b22084100480de0010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de1012004410174220b2007200b20074b1b220b4100480de1010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de101200441017422092006200920064b1b22094100480de1010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddf01200441017422082007200820074b1b22084100480ddf010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de0012004410174220b2007200b20074b1b220b4100480de0010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de001200441017422092006200920064b1b22094100480de0010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dde01200441017422082007200820074b1b22084100480dde010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddf012004410174220b2007200b20074b1b220b4100480ddf010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc701200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddf01200441017422092006200920064b1b22094100480ddf010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dc8012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddd01200441017422082007200820074b1b22084100480ddd010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc70120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dde012004410174220b2007200b20074b1b220b4100480dde010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dc901200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dde01200441017422092006200920064b1b22094100480dde010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dca012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddc01200441017422082007200820074b1b22084100480ddc010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dc90120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412f3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddd012004410174220b2007200b20074b1b220b4100480ddd010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dcb01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddd01200441017422092006200920064b1b22094100480ddd010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dcc012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c91010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddb01200441017422082007200820074b1b22084100480ddb010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dcb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41303a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddc012004410174220b2007200b20074b1b220b4100480ddc010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dcd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddc01200441017422092006200920064b1b22094100480ddc010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dce012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dda01200441017422082007200820074b1b22084100480dda010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dcd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41313a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddb012004410174220b2007200b20074b1b220b4100480ddb010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dcf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddb01200441017422092006200920064b1b22094100480ddb010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd901200441017422082007200820074b1b22084100480dd9010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dcf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41323a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dda012004410174220b2007200b20074b1b220b4100480dda010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dda01200441017422092006200920064b1b22094100480dda010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd801200441017422082007200820074b1b22084100480dd8010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41333a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd9012004410174220b2007200b20074b1b220b4100480dd9010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd901200441017422092006200920064b1b22094100480dd9010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8d010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd701200441017422082007200820074b1b22084100480dd7010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41343a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd8012004410174220b2007200b20074b1b220b4100480dd8010240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd801200441017422092006200920064b1b22094100480dd8010240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd601200441017422082007200820074b1b22084100480dd6010240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41353a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da3022004410174220b2007200b20074b1b220b4100480da3020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dd801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da302200441017422092006200920064b1b22094100480da3020240024020040d002009102821060c010b200a28020020042009102c21060b2006450dd9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8b010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da102200441017422082007200820074b1b22084100480da1020240024020040d002008102821070c010b200a28020020042008102c21070b2007450dd80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41363a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da2022004410174220b2007200b20074b1b220b4100480da2020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dda01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da202200441017422092006200920064b1b22094100480da2020240024020040d002009102821060c010b200a28020020042009102c21060b2006450ddb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da002200441017422082007200820074b1b22084100480da0020240024020040d002008102821070c010b200a28020020042008102c21070b2007450dda0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41373a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da1022004410174220b2007200b20074b1b220b4100480da1020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450ddc01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da102200441017422092006200920064b1b22094100480da1020240024020040d002009102821060c010b200a28020020042009102c21060b2006450ddd012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c89010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9f02200441017422082007200820074b1b22084100480d9f020240024020040d002008102821070c010b200a28020020042008102c21070b2007450ddc0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41383a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da0022004410174220b2007200b20074b1b220b4100480da0020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dde01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da002200441017422092006200920064b1b22094100480da0020240024020040d002009102821060c010b200a28020020042009102c21060b2006450ddf012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9e02200441017422082007200820074b1b22084100480d9e020240024020040d002008102821070c010b200a28020020042008102c21070b2007450dde0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41393a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9f022004410174220b2007200b20074b1b220b4100480d9f020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de001200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9f02200441017422092006200920064b1b22094100480d9f020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de1012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9d02200441017422082007200820074b1b22084100480d9d020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de00120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9e022004410174220b2007200b20074b1b220b4100480d9e020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de201200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9e02200441017422092006200920064b1b22094100480d9e020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de3012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9c02200441017422082007200820074b1b22084100480d9c020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de20120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9d022004410174220b2007200b20074b1b220b4100480d9d020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de401200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9d02200441017422092006200920064b1b22094100480d9d020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de5012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c85010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9b02200441017422082007200820074b1b22084100480d9b020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de40120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9c022004410174220b2007200b20074b1b220b4100480d9c020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de601200220073602042009200b360200200828020021040b2008200441016a360200200720046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021050c010b200441016a22052004490d9c02200441017422092005200920054b1b22094100480d9c020240024020040d002009102821050c010b200a28020020042009102c21050b2005450de7012002200536020420082009360200200728020021040b2007200441016a360200200520046a200641807f72200641ff0071200641077622041b3a00002004210620040d000c84010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9a02200441017422082007200820074b1b22084100480d9a020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de60120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9b022004410174220b2007200b20074b1b220b4100480d9b020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450de801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9b02200441017422092006200920064b1b22094100480d9b020240024020040d002009102821060c010b200a28020020042009102c21060b2006450de9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c83010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9902200441017422082007200820074b1b22084100480d99020240024020040d002008102821070c010b200a28020020042008102c21070b2007450de80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9a022004410174220b2007200b20074b1b220b4100480d9a020240024020040d00200b102821070c010b200a2802002004200b102c21070b2007450dea01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9a02200441017422092006200920064b1b22094100480d9a020240024020040d002009102821060c010b200a28020020042009102c21060b2006450deb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9802200441017422082005200820054b1b22084100480d98020240024020040d002008102821050c010b200628020020042008102c21050b2005450dea0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a413f3a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d9802200441017422082005200820054b1b22084100480d98020240024020040d002008102821050c010b200628020020042008102c21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9702200441017422082005200820054b1b22084100480d97020240024020040d002008102821050c010b200628020020042008102c21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c0003a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d9702200441017422082005200820054b1b22084100480d97020240024020040d002008102821050c010b200628020020042008102c21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9602200441017422072005200720054b1b22074100480d96020240024020040d002007102821050c010b200228020420042007102c21050b2005450dec0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c1003a000020032006200210eb042003210420032d0000411f470def020c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9502200441017422062005200620054b1b22064100480d95020240024020040d002006102821050c010b200228020420042006102c21050b2005450dec0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c2003a00002003200c200210ec042003210420032d0000411f470dee020c7d0b200241046a2106200141046a280200210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9402200441017422082005200820054b1b22084100480d94020240024020040d002008102821050c010b200628020020042008102c21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c3003a000002400240200241086a2802002205200828020022046b4104490d00200628020021050c010b200441046a22082004490d9402200541017422042008200420084b1b22044100480d94020240024020050d002004102821050c010b200628020020052004102c21050b2005450ded0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441046a360200200520046a20073600000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d9302200441017422072005200720054b1b22074100480d93020240024020040d002007102821050c010b200628020020042007102c21050b2005450ded0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a41c4003a000002400240200241086a2802002205200728020022046b4108490d00200628020021050c010b200441086a22072004490d9302200541017422042007200420074b1b22044100480d93020240024020050d002004102821050c010b200628020020052004102c21050b2005450dee0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441086a360200200520046a200c3700000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9202200441017422062005200620054b1b22064100480d92020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c5003a00000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9102200441017422062005200620054b1b22064100480d91020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c6003a00000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9002200441017422062005200620054b1b22064100480d90020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c7003a00000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f02200441017422062005200620054b1b22064100480d8f020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c8003a00000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e02200441017422062005200620054b1b22064100480d8e020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c9003a00000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d02200441017422062005200620054b1b22064100480d8d020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ca003a00000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c02200441017422062005200620054b1b22064100480d8c020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cb003a00000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b02200441017422062005200620054b1b22064100480d8b020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cc003a00000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a02200441017422062005200620054b1b22064100480d8a020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cd003a00000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8902200441017422062005200620054b1b22064100480d89020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ce003a00000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8802200441017422062005200620054b1b22064100480d88020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cf003a00000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8702200441017422062005200620054b1b22064100480d87020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d0003a00000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8602200441017422062005200620054b1b22064100480d86020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d1003a00000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8502200441017422062005200620054b1b22064100480d85020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d2003a00000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8402200441017422062005200620054b1b22064100480d84020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d3003a00000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8302200441017422062005200620054b1b22064100480d83020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d4003a00000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8202200441017422062005200620054b1b22064100480d82020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d5003a00000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8102200441017422062005200620054b1b22064100480d81020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d6003a00000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8002200441017422062005200620054b1b22064100480d80020240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d7003a00000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff01200441017422062005200620054b1b22064100480dff010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d8003a00000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe01200441017422062005200620054b1b22064100480dfe010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d9003a00000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd01200441017422062005200620054b1b22064100480dfd010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41da003a00000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc01200441017422062005200620054b1b22064100480dfc010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41db003a00000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb01200441017422062005200620054b1b22064100480dfb010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dc003a00000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa01200441017422062005200620054b1b22064100480dfa010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dd003a00000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df901200441017422062005200620054b1b22064100480df9010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41de003a00000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df801200441017422062005200620054b1b22064100480df8010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41df003a00000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e0003a00000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e1003a00000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df501200441017422062005200620054b1b22064100480df5010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e2003a00000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df401200441017422062005200620054b1b22064100480df4010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e3003a00000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df301200441017422062005200620054b1b22064100480df3010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e4003a00000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e5003a00000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e6003a00000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df001200441017422062005200620054b1b22064100480df0010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e7003a00000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490def01200441017422062005200620054b1b22064100480def010240024020040d002006102821050c010b200228020420042006102c21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e8003a00000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dba02200441017422062005200620054b1b22064100480dba020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e9003a00000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db902200441017422062005200620054b1b22064100480db9020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ea003a00000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db802200441017422062005200620054b1b22064100480db8020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41eb003a00000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db702200441017422062005200620054b1b22064100480db7020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ec003a00000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db602200441017422062005200620054b1b22064100480db6020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ed003a00000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db502200441017422062005200620054b1b22064100480db5020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ee003a00000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db402200441017422062005200620054b1b22064100480db4020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ef003a00000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db302200441017422062005200620054b1b22064100480db3020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f0003a00000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db202200441017422062005200620054b1b22064100480db2020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f1003a00000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db102200441017422062005200620054b1b22064100480db1020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f2003a00000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db002200441017422062005200620054b1b22064100480db0020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f3003a00000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daf02200441017422062005200620054b1b22064100480daf020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f4003a00000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dae02200441017422062005200620054b1b22064100480dae020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f5003a00000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad02200441017422062005200620054b1b22064100480dad020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f6003a00000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac02200441017422062005200620054b1b22064100480dac020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f7003a00000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dab02200441017422062005200620054b1b22064100480dab020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f8003a00000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daa02200441017422062005200620054b1b22064100480daa020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f9003a00000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da902200441017422062005200620054b1b22064100480da9020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fa003a00000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da802200441017422062005200620054b1b22064100480da8020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fb003a00000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da702200441017422062005200620054b1b22064100480da7020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fc003a00000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da602200441017422062005200620054b1b22064100480da6020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fd003a00000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da502200441017422062005200620054b1b22064100480da5020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fe003a00000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da402200441017422062005200620054b1b22064100480da4020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ff003a00000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da302200441017422062005200620054b1b22064100480da3020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4180013a00000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da202200441017422062005200620054b1b22064100480da2020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4181013a00000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da102200441017422062005200620054b1b22064100480da1020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4182013a00000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da002200441017422062005200620054b1b22064100480da0020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4183013a00000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f02200441017422062005200620054b1b22064100480d9f020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4184013a00000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9e02200441017422062005200620054b1b22064100480d9e020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4185013a00000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9d02200441017422062005200620054b1b22064100480d9d020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4186013a00000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9c02200441017422062005200620054b1b22064100480d9c020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4187013a00000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9b02200441017422062005200620054b1b22064100480d9b020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4188013a00000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9a02200441017422062005200620054b1b22064100480d9a020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4189013a00000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9902200441017422062005200620054b1b22064100480d99020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418a013a00000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9802200441017422062005200620054b1b22064100480d98020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418b013a00000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9702200441017422062005200620054b1b22064100480d97020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418c013a00000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9602200441017422062005200620054b1b22064100480d96020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418d013a00000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9502200441017422062005200620054b1b22064100480d95020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418e013a00000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9402200441017422062005200620054b1b22064100480d94020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418f013a00000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9302200441017422062005200620054b1b22064100480d93020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4190013a00000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9202200441017422062005200620054b1b22064100480d92020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4191013a00000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9102200441017422062005200620054b1b22064100480d91020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4192013a00000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9002200441017422062005200620054b1b22064100480d90020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4193013a00000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f02200441017422062005200620054b1b22064100480d8f020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4194013a00000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e02200441017422062005200620054b1b22064100480d8e020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4195013a00000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d02200441017422062005200620054b1b22064100480d8d020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4196013a00000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c02200441017422062005200620054b1b22064100480d8c020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4197013a00000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b02200441017422062005200620054b1b22064100480d8b020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4198013a00000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a02200441017422062005200620054b1b22064100480d8a020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4199013a00000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8902200441017422062005200620054b1b22064100480d89020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419a013a00000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8802200441017422062005200620054b1b22064100480d88020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419b013a00000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8702200441017422062005200620054b1b22064100480d87020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419c013a00000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8602200441017422062005200620054b1b22064100480d86020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419d013a00000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8502200441017422062005200620054b1b22064100480d85020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419e013a00000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8402200441017422062005200620054b1b22064100480d84020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419f013a00000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8302200441017422062005200620054b1b22064100480d83020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a0013a00000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8202200441017422062005200620054b1b22064100480d82020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a1013a00000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8102200441017422062005200620054b1b22064100480d81020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a2013a00000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8002200441017422062005200620054b1b22064100480d80020240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a3013a00000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff01200441017422062005200620054b1b22064100480dff010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a4013a00000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe01200441017422062005200620054b1b22064100480dfe010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a5013a00000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd01200441017422062005200620054b1b22064100480dfd010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a6013a00000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc01200441017422062005200620054b1b22064100480dfc010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a7013a00000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb01200441017422062005200620054b1b22064100480dfb010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a8013a00000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa01200441017422062005200620054b1b22064100480dfa010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a9013a00000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df901200441017422062005200620054b1b22064100480df9010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41aa013a00000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df801200441017422062005200620054b1b22064100480df8010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ab013a00000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ac013a00000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ad013a00000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df501200441017422062005200620054b1b22064100480df5010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ae013a00000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df401200441017422062005200620054b1b22064100480df4010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41af013a00000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df301200441017422062005200620054b1b22064100480df3010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b0013a00000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b1013a00000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b2013a00000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df001200441017422062005200620054b1b22064100480df0010240024020040d002006102821050c010b200228020420042006102c21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b3013a00000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc01200441017422062005200620054b1b22064100480dfc010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b4013a00000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb01200441017422062005200620054b1b22064100480dfb010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b5013a00000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa01200441017422062005200620054b1b22064100480dfa010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b6013a00000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df901200441017422062005200620054b1b22064100480df9010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b7013a00000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df801200441017422062005200620054b1b22064100480df8010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b8013a00000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df701200441017422062005200620054b1b22064100480df7010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b9013a00000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df601200441017422062005200620054b1b22064100480df6010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ba013a00000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df501200441017422062005200620054b1b22064100480df5010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bb013a00000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df401200441017422062005200620054b1b22064100480df4010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bc013a00000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df301200441017422062005200620054b1b22064100480df3010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bd013a00000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df201200441017422062005200620054b1b22064100480df2010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41be013a00000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df101200441017422062005200620054b1b22064100480df1010240024020040d002006102821050c010b200228020420042006102c21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bf013a00000b2000411f3a000020012d00004109470df1010240200141046a280200220228020441ffffffff0371450d002002280200102a200128020421020b2002102a0cf1010b200641011037000b200641011037000b200841011037000b200841011037000b200841011037000b200841011037000b200841011037000b200841011037000b200641011037000b200641011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200641011037000b200a41011037000b200641011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200641011037000b200641011037000b200641011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200741011037000b200a41011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b1031000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200b41011037000b200941011037000b200841011037000b200841011037000b200841011037000b200841011037000b200741011037000b200641011037000b200841011037000b200441011037000b200741011037000b200441011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b1031000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b1031000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b200641011037000b1031000b20002004290200370200200041086a200441086a29020037020020012d00004109470d000240200141046a280200220228020441ffffffff0371450d002002280200102a200128020421020b2002102a0b200341106a24000bfb07030e7f017e017f200241086a2103200241046a210420012802002205210602400240024002400240034002400240200428020020032802002207460d00200228020021080c010b200741016a22082007490d02200741017422092008200920084b1b22094100480d020240024020070d002009102821080c010b200228020020072009102c21080b2008450d032002200836020020042009360200200328020021070b2003200741016a360200200820076a200641807f72200641ff0071200641077622071b3a00002007210620070d000b2001280204220a2001410c6a2802002206410c6c6a210b200141086a280200210c200a21072006450d03200a21072005450d03200b41746a210d200241086a210841002107200a210e02400340200e2103024003402003280200220f0d01200741016a2107200b2003410c6a2203470d000c080b0b2003410c6a210e200741016a21102005417f6a2105200341046a290200211102400240034002400240200241046a220428020020082802002206460d00200228020021090c010b200641016a22092006490d06200641017422012009200120094b1b22014100480d060240024020060d002001102821090c010b200228020020062001102c21090b2009450d022002200936020020042001360200200828020021060b2008200641016a360200200920066a200741807f72200741ff0071200741077622061b3a0000200621072006450d020c000b0b200141011037000b2011422088a7221221060240034002400240200428020020082802002207460d00200228020021090c010b200741016a22092007490d05200741017422012009200120094b1b22014100480d050240024020070d002001102821090c010b200228020020072001102c21090b2009450d022002200936020020042001360200200828020021070b2008200741016a360200200920076a200641807f72200641ff0071200641077622071b3a00002007210620070d000b0240024020042802002206200828020022076b2012490d00200228020021060c010b200720126a22092007490d04200641017422072009200720094b1b22074100480d040240024020060d002007102821060c010b200228020020062007102c21060b2006450d032002200636020020042007360200200828020021070b2008200720126a360200200620076a200f2012109a051a02402011a7450d00200f102a0b200d2003460d052010210720050d010c050b0b200141011037000b200741011037000b1031000b200941011037000b2003410c6a21070b2007200b460d000340024020072802002206450d00200741046a280200450d002006102a0b2007410c6a2207200b470d000b0b0240200c450d00200a102a0b2000411f3a00000bcb0401067f200441046a2105024002400240024002400240200441086a2802002004410c6a2802002206460d00200528020021070c010b200641016a22072006490d04200641017422082007200820074b1b22084100480d040240024020060d002008102821070c010b200528020020062008102c21070b2007450d0120042007360204200441086a20083602002004410c6a28020021060b2004410c6a2208200641016a360200200720066a20024101463a0000200441086a2109034002400240200928020020082802002206460d00200528020021070c010b200641016a22072006490d052006410174220a2007200a20074b1b220a4100480d050240024020060d00200a102821070c010b20052802002006200a102c21070b2007450d03200420073602042009200a360200200828020021060b2008200641016a360200200720066a200141807f72200141ff0071200141077622061b3a00002006210120060d000b024020024101470d002004410c6a2107200441086a2108034002400240200828020020072802002206460d00200528020021010c010b200641016a22012006490d06200641017422092001200920014b1b22094100480d060240024020060d002009102821010c010b200528020020062009102c21010b2001450d052004200136020420082009360200200728020021060b2007200641016a360200200120066a200341807f72200341ff0071200341077622061b3a00002006210320060d000b0b2000411f3a00000f0b200841011037000b200a41011037000b200941011037000b1031000bb007010a7f230041d0006b2202240002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490d02200320054f0d0120052003103c000b200241013a001f200241cc006a41013602002002420137023c200241a4e2c500360238200241263602342002200241306a36024820022002411f6a360230200241206a200241386a10332002411b6a200241286a28020036000020022002290320370013200220022900103703002002200241176a290000370007200041053a0004200020022903003700052000410c6a2002290007370000200041013602000c040b2001280200220620046a2d000021072001200536020c024020074102490d00200041173a000420004101360200200041056a20073a00000c040b410120036b2108200441026a2104410021054100210902400240034002402005411f4d0d00410f21050c020b02400240200820046a4102460d002004450d06200320044f0d0120042003103c000b200241013a0000200241cc006a41013602002002420137023c200241a4e2c500360238200241263602342002200241306a36024820022002360230200241106a200241386a1033410521050c020b200620046a417f6a2d0000210a2001200436020c200a41ff00712005411f71742009722109200441016a2104200541076a2105200a418001710d000b20054120490d01410d2105200a4110490d010b2000200536020420004101360200200041086a2002290210370200200041106a200241106a41086a2802003602000c040b4100210502402007410171450d002004417f6a2104410021054100210b02400240034002402005411f4d0d00410f21040c020b0240024020032004460d002004417f460d082003200441016a22084f0d01200441016a2003103c000b200241013a0000200241cc006a41013602002002420137023c200241a4e2c500360238200241263602342002200241306a36024820022002360230200241106a200241386a1033410521040c020b200620046a2d0000210a2001200836020c200a41ff00712005411f7174200b72210b200541076a210520082104200a418001710d000b20054120490d01410d2104200a4110490d010b2000200436020420004101360200200041086a2002290210370200200041106a200241106a41086a2802003602000c050b410121050b20002009360204200041003602002000410c6a200b360200200041086a20053602000c030b417f20051044000b417f20041044000b417f200441016a1044000b200241d0006a24000bee0201067f230041c0006b2202240041002103410021040240024003400240024002402003411f4b0d002001280204220520012802082206460d01200641016a22072006490d04200520074f0d0220072005103c000b200041013602002000410f3a00040c040b200241013a000f200241346a410136020020024201370224200241a4e2c5003602202002412636023c2002200241386a36023020022002410f6a360238200241106a200241206a10332002410b6a200241186a28020036000020022002290310370003200041053a0004200020022900003700052000410c6a200241076a290000370000200041013602000c030b200128020020066a2d0000210620012007360208200641ff00712003411f71742004722104200341076a21032006418001710d000b0240024020034120490d002006410f4b0d010b20004100360200200020043602040c020b200041013602002000410d3a00040c010b417f20071044000b200241c0006a24000bd806010a7f20012802042103200128020021044100210541002106410021074101210820012802082209210a02400240024002400340024020062007470d002005200641016a220b2005200b4b1b22074100480d050240024020060d002007102821080c010b200820062007102c21080b2008450d020b200820066a200a41807f72200a41ff0071200a410776220b1b3a0000200541026a2105200641016a2106200b210a200b0d000b0240200720066b20094f0d00200620096a220a2006490d0420074101742205200a2005200a4b1b220a4100480d040240024020070d00200a102821080c010b20082007200a102c21080b2008450d02200a21070b200820066a20042009109a051a02402003450d002004102a0b200128020c210c0240200720096b20066b200141146a280200220a490d002009200a6a20066a21030c030b200920066a2205200a6a22032005490d03200741017422052003200520034b1b22054100480d030240024020070d002005102821080c010b200820072005102c21080b02402008450d00200521070c030b200541011037000b200741011037000b200a41011037000b200820096a20066a200c200a109a051a200241086a210b200241046a21092003210a024002400340024002402009280200200b2802002206460d00200228020021050c010b200641016a22052006490d04200641017422042005200420054b1b22044100480d040240024020060d002004102821050c010b200228020020062004102c21050b2005450d022002200536020020092004360200200b28020021060b200b200641016a360200200520066a200a41807f72200a41ff0071200a41077622061b3a00002006210a20060d000b02400240200241046a280200220a200241086a28020022066b2003490d002002280200210a0c010b200620036a22052006490d03200a41017422062005200620054b1b22064100480d0302400240200a0d0020061028210a0c010b2002280200200a2006102c210a0b200a450d022002200a360200200241046a2006360200200241086a28020021060b200241086a200620036a360200200a20066a20082003109a051a02402007450d002008102a0b2000411f3a00000240200141106a280200450d00200c102a0b0f0b200441011037000b200641011037000b1031000bf20103027f017e057f024020002802082201200028020c460d00034020002001411c6a36020820012802102202450d01200141146a2902002103024020012802042204450d00200141086a280200210502402001410c6a2802002201450d0020014104742106200421010340024020012d00004109470d000240200141046a2207280200220828020441ffffffff0371450d002008280200102a200728020021080b2008102a0b200141106a2101200641706a22060d000b0b2005450d002004102a0b02402003a7450d002002102a0b20002802082201200028020c470d000b0b02402000280204450d002000280200102a0b0be50101067f024020002802082201200028020c460d0003402000200141186a36020820012802002202450d01200141146a2802002103200141106a2802002104200128020c210502402001280204450d002002102a0b02402003450d0020034104742103200521010340024020012d00004109470d000240200141046a2206280200220228020441ffffffff0371450d002002280200102a200628020021020b2002102a0b200141106a2101200341706a22030d000b0b02402004450d002005102a0b20002802082201200028020c470d000b0b02402000280204450d002000280200102a0b0bf20103027f017e057f024020002802082201200028020c460d00034020002001411c6a36020820012802102202450d01200141146a2902002103024020012802042204450d00200141086a280200210502402001410c6a2802002201450d0020014104742106200421010340024020012d00004109470d000240200141046a2207280200220828020441ffffffff0371450d002008280200102a200728020021080b2008102a0b200141106a2101200641706a22060d000b0b2005450d002004102a0b02402003a7450d002002102a0b20002802082201200028020c470d000b0b02402000280204450d002000280200102a0b0bce0101057f024020002802082201450d00200028020022022001411c6c6a21030340024020022802042200450d0002402002410c6a2802002201450d00200141047421010340024020002d00004109470d000240200041046a2204280200220528020441ffffffff0371450d002005280200102a200428020021050b2005102a0b200041106a2100200141706a22010d000b0b200241086a280200450d002002280204102a0b2002411c6a21000240200241146a280200450d002002280210102a0b2000210220002003470d000b0b0b90d20106067f017e057f017e117f027e2300419081046b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280204220320012802082204460d00200441016a22052004490d02200320054f0d0120052003103c000b200241013a0030200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a103320022802f88004210420022802fc8004210120004101360200200041003a00042001450d2b2004102a0c2b0b200128020020046a2d00002104200120053602082004410c4b0d03024002400240024020040e0d0001161514131211060d0c0b05000b200241e8006a200110f40441012106200228026c2107024020022802684101470d0020074108762101200241f8006a2802002104200241e8006a41086a29030021080c270b41002109200241e8006a4100418080011099051a410021034100210a2007450d20410021054100210a410121064100210b0340024002402001280204220c200128020822036b2007200b6b220441808001200441808001491b2204490d00200320046a220d2003490d05200c200d4f0d01200d200c103c000b200241013a00e880042002418c81046a4101360200200242013702fc8004200241a4e2c5003602f880042002412636021c2002200241186a36028881042002200241e880046a360218200241306a200241f880046a10332002290330210820022802382104410521070240200a450d002006102a0b0c280b200241e8006a200128020020036a2004109a051a2001200d36020802400240200a20056b2004490d00200520046a21030c010b200520046a22032005490d23200a410174220d2003200d20034b1b220d4100480d2302400240200a0d00200d102821060c010b2006200a200d102c21060b2006450d03200d210a0b200620056a200241e8006a2004109a051a2003210520072004200b6a220b4b0d000c210b0b200241e8006a200110fb04024020022802684101470d00200228026c22044108762105200241e8006a41086a2903002208422088210e200241f8006a28020021030c1f0b200241fc006a280200210f200241f8006a2802002101200241f4006a2802002103200241f0006a2802002110200228026c210b4100210441002109024002400240034002402004411f4d0d00410f21040c020b0240024020032001460d002001417f460d052003200141016a22054f0d01200141016a2003103c000b200241013a0030200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241c8006a200241e8006a1033410521040c020b200b20016a2d0000220641ff00712004411f71742009722109200441076a2104200521012006418001710d000b20044120490d01410d210420064110490d010b200241f880046a41086a200241c8006a41086a28020022033602002002200229034822083703f880042008422088a721092008a721060c1f0b200241003602602002420437035802400240024020090d00410421010c010b410020036b2111200b41026a2112410120036b21134100210a410421014100211441002115410021160340201621170240024020032005460d000240200541016a22042005490d000240024020032004490d000240200b20056a2d0000220441e000460d00411821050c250b201741016a211641022118200541026a210441002106410321192012211a4100211b024002400340201a21072019210c2018210d02402006411f4d0d00410f21050c020b02400240201320046a4102460d002004450d06200320044f0d0120042003103c000b200241013a00302002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a1033200241206a41086a200241f880046a41086a280200360200200220022903f88004370320410521050c020b200b20046a417f6a2d0000221c41ff00712006411f7174201b72211b200d41016a2118200c41016a2119200741016a211a200441016a2104200641076a2106201c418001710d000b20064120490d01201c4110490d01410d21050b200241e880046a41086a200241206a41086a28020022033602002002200229032022083703e880042008a721064100210420022802ec800421090c240b41002118200241003602382002420137033002400240201b0d002004417f6a21064101211c4100211a4100211d0c010b201120056a211e410021194101211c4100211a034002400240024002400240201e200d6a450d002005200c6a2204450d02200320044f0d0120042003103c000b200220193602342002201a3602382002201c360230200241013a00e880042002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a103320022802f88004210620022802fc80042109200228028081042103410521050c280b200720056a2c000022044100480d0102400240200441c00071450d00200441807f72220441ff017141fb014b0d010b200220193602342002201a3602382002201c360230410621050c270b0240201a2019460d002019211d201a21060c030b201941016a22062019490d2e2019410174221d2006201d20064b1b221d4100480d2e0240024020190d00201d1028211c0c010b201c2019201d102c211c0b0240201c450d0020192106201d21190c030b201d41011037000b417f20041044000b200220193602342002201a3602382002201c360230411921050c240b201c20066a2004417f733a0000200d41016a210d200c41016a210c200741016a2107201b201a41016a221a470d000b2002201d3602342002201a3602382002201c3602302005200d6a21060b201c411076411074221b201c41087641ff0171410874221972201c41ff0171221c72210c4100210d024003404100210402402018411f4d0d00410f21050c230b0240024020032006460d002006417f460d032003200641016a22054f0d01200641016a2003103c000b200241013a00302002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a103320022802f88004210620022802fc8004210920022d00808104210320022d00818104210720022f01828104210d410521050c230b200b20066a2d0000220741ff00712018411f7174200d72210d201841076a2118200521062007418001710d000b20184120490d052007410f4d0d05410d21050c210b417f200641016a1044000b20042003103c000b417f20041044000b417f20041044000b200241013a00302002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a103320022802f88004210620022802fc8004210920022d00808104210320022d00818104210720022f01828104210d410521050c200b0240200d41014d0d004104210541e885c6002106412421090c1b0b024002400240200d0e020001000b410421060c010b20032005460d1a024002400240200541016a220d2005490d002003200d490d010240200b20056a2c0000220441004e0d00411921050c200b41062105200441c00071450d02200441807f72220441ff017141fb014d0d022004417f732106200d21050c030b417f200541016a1044000b200541016a2003103c000b0c1c0b024020172015470d00024020142015460d00201421150c010b201441016a22042014490d252014410174220d2004200d20044b1b221541ffffffff00712015470d25201541047422044100480d250240024020140d002004102821010c010b200120144104742004102c21010b2001450d032002201536025c20022001360258201521140b200120174104746a2204201f4180807c71200641ff01714108747241e00072221f36020c2004201a3602082004201d36020420042019201c72201b72360200200a41106a210a2002201636026020162009470d000b0b2005200f462104200229025c2208422088210e02402010450d00200b102a0b200ea721052008a721092004450d1e2005ad4220862009ad842108410221030c2a0b200441041037000b417f200141016a1044000b200d41011037000b2003200d1044000b417f20051044000b200241e8006a200110fb04024020022802684101470d00200041013602002000200241e8006a41047222012902003702042000410c6a200141086a2902003702000c290b200241fc006a280200210d200241f8006a2802002104200241f4006a2802002105200241f0006a280200210a200228026c210b410021034100210102400240034002402003411f4d0d00410f21040c080b20052004460d062004417f460d012005200441016a2206490d02200b20046a2d0000220941ff00712003411f71742001722101200341076a2103200621042009418001710d000b20034120490d04410d21042009410f4b0d060c040b417f200441016a1044000b200441016a2005103c000b200241e8006a200110fb04024020022802684101470d00200041013602002000200241e8006a41047222012902003702042000410c6a200141086a2902003702000c280b200241fc006a280200210d200241f8006a2802002104200241f4006a2802002105200241f0006a280200210a200228026c210b410021034100210102400240034002402003411f4d0d00410f21040c0d0b20052004460d0b2004417f460d012005200441016a2206490d02200b20046a2d0000220941ff00712003411f71742001722101200341076a2103200621042009418001710d000b20034120490d09410d21042009410f4b0d0b0c090b417f200441016a1044000b200441016a2005103c000b200041123a000420004101360200200041056a20043a00000c260b200d20064621040240200a450d00200b102a0b02402004450d00410b21030c220b20024103410220041b3a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a10332002418381046a200241386a280200360000200220022903303700fb8004200041053a0004200020022900f880043700052000410c6a200241ff80046a290000370000200041013602000c250b200241013a0030200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a1033410521040b2000200436020420004101360200200041086a20022902f88004370200200041106a200241f880046a41086a280200360200200a450d23200b102a0c230b200241e8006a200110fb040240024020022802684101470d00200228026c22014108762106200241e8006a41086a2903002208422088210e200241f8006a280200210b0c010b200241c0006a200241fc006a280200360200200241386a200241f4006a2902003703002002200229026c37033041002101410021050240024002400240024002400240034002402001411f4d0d00410f210d0c020b0240024020022802382209200228023c2204460d00200441016a22032004490d05200920034f0d0120032009103c000b200241013a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241c8006a200241e8006a10334105210d0c020b200228023020046a2d000021042002200336023c200441ff00712001411f71742005722105200141076a21012004418001710d000b20014120490d01410d210d20044110490d010b200241f880046a41086a200241c8006a41086a280200220b3602002002200229034822083703f880042008422088a721072008a7210c410021060c040b200241003602502002420437034802400240024020050d00410421010c010b4100210d0340200d41016a210d41002101410021090240024002400240024002400240034002402001411f4d0d00410f210d0c030b20022802382206200228023c2204460d01200441016a22032004490d0420062003490d06200228023020046a2d000021042002200336023c200441ff00712001411f71742009722109200141076a21012004418001710d000b20014120490d022004410f4d0d02410d210d0c010b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241f880046a200241e8006a1033200241e880046a41086a200241f880046a41086a280200360200200220022903f8800422083703e880042008a7210c4105210d0b20022802f08004210b20022802ec80042107410021060c0a0b200241e8006a200241306a10ed04024020022802684101470d00200228026c220d41087621062002280278210b200228027421072002280270210c0c0a0b200228027421192002280270211c200228026c211a410021044100210b02400240034002402004411f4d0d00410f210d0c020b0240024020022802382206200228023c2203460d00200341016a22012003490d06200620014f0d0120012006103c000b200241013a00e880042002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a1033200241206a41086a200241f880046a41086a280200360200200220022903f8800422083703202008a7210c4105210d0c030b2002280230220a20036a2d000021032002200136023c200341ff00712004411f7174200b72210b200441076a21042003418001710d000b20044120490d0520034110490d05410d210d0b0b2002280228210b200228022421070c080b417f20031044000b417f20011044000b20032006103c000b4100211b200241e8006a4100418080041099051a02400240200b0d00410121184100210c0c010b4100211b41012118410021034100210702400240034002400240200620016b200b20076b220441808004200441808004491b2204490d00200120046a220c2001490d032006200c4f0d01200c2006103c000b200241013a00202002410136028c8104200242013702fc8004200241a4e2c5003602f880042002412636021c2002200241186a36028881042002200241206a360218200241e880046a200241f880046a103320022802e88004210c20022802ec8004210720022802f08004210b4105210d201b450d092018102a0c090b200241e8006a200a20016a2004109a051a2002200c36023c02400240201b20036b2004490d00200320046a210c0c010b200320046a220c2003490d24201b4101742201200c2001200c4b1b22014100480d2402400240201b0d002001102821180c010b2018201b2001102c21180b2018450d032001211b0b201820036a200241e8006a2004109a051a200b200420076a22074d0d03200228023c2101200228023821062002280230210a200c21030c000b0b2001200c1044000b200141011037000b024020022802502203200228024c470d00200341016a22012003490d20200341017422042001200420014b1b2204ad421c7e2208422088a70d202008a722064100480d200240024020030d002006102821010c010b20022802482003411c6c2006102c21010b2001450d032002200436024c200220013602480b200228024822012003411c6c6a2204200941087622063b0001200420183602102004201a360204200420093a0000200441036a20064110763a0000200441186a200c360200200441146a201b3602002004410c6a2019360200200441086a201c3602002002200341016a360250200d2005470d000b0b200228023c2002280240462104200229024c2208422088210e02402002280234450d002002280230102a0b20014108762105200ea721032008a7210a2004450d052005410874200141ff01717221012003ad422086200aad842108410d21030c250b200641041037000b417f20031044000b02402019450d0020194104742104201a21010340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b41002106201c450d00201a102a0b2002280248211b024020022802502201450d00201b2001411c6c6a210a201b21090340024020092802042201450d0002402009410c6a2802002204450d00200441047421040340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b200941086a280200450d002009280204102a0b2009411c6a21010240200941146a280200450d002009280210102a0b200121092001200a470d000b0b200228024c450d00201b102a0b2006410874200d41ff01717221012007ad220e422086200cad8421082002280234450d012002280230102a0c010b2005410874200141ff017172210d20024103410220041b3a00e88004200241e8006a41146a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a103320022903f88004210820022802808104210b02402003450d00200d2003411c6c6a2106200d21090340024020092802042201450d0002402009410c6a2802002204450d00200441047421040340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b200941086a280200450d002009280204102a0b2009411c6a21010240200941146a280200450d002009280210102a0b2001210920012006470d000b0b2008422088210e4105210141002106200a450d00200d102a0b20004101360200200041106a200b360200200041086a200e422086200842ffffffff0f838437020020002006410874200141ff0171723602040c220b200241e8006a200110fb040240024020022802684101470d00200228026c220a4108762104200241e8006a41086a2903002208422088210e200241f8006a280200210d0c010b200241fc006a280200211b200241f8006a2802002101200241f4006a2802002105200241f0006a2802002107200228026c210b410021044100210902400240024002400240024002400240024002400240034002402004411f4d0d00410f210a0c020b0240024020052001460d002001417f460d052005200141016a22034f0d01200141016a2005103c000b200241013a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a10334105210a0c020b200b20016a2d0000220641ff00712004411f71742009722109200441076a2104200321012006418001710d000b20044120490d01410d210a20064110490d010b200241306a41086a200241f880046a41086a280200220d360200200220022902f8800422083703302008422088a7210c2008a7211b0c080b2002410036026020024204370358024002400240024020090d00410421010c010b200241f1006a21104100211c0340201c41016a211c410021014100210602400240024002400240024002400240024002400240024002400240034002402001411f4d0d00410f210a0c020b0240024020052003460d002003417f460d062005200341016a22044f0d01200341016a2005103c000b200241013a00f880042002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241f880046a360218200241c8006a200241e8006a10334105210a2002280248211b0c030b200b20036a2d0000220a41ff00712001411f71742006722106200141076a210120042103200a418001710d000b20014120490d02200a4110490d02410d210a0b0b2002280250210d200228024c210c0c160b4100210c200241e8006a4100418080011099051a410121180240024020060d00200421034100211a4100210a0c010b4100210d4100211a41002119034002400240200520046b200620196b220141808001200141808001491b2201490d00200420016a22032004490d05200520034f0d0120032005103c000b200241013a00482002410136028c8104200242013702fc8004200241a4e2c5003602f880042002412636021c2002200241186a36028881042002200241c8006a360218200241e880046a200241f880046a103320022802e88004211b20022802ec8004210c20022802f08004210d4105210a201a450d182018102a0c180b200241e8006a200b20046a2001109a051a02400240201a200d6b2001490d00200d20016a210a0c010b200d20016a220a200d490d31201a4101742204200a2004200a4b1b22044100480d3102400240201a0d002004102821180c010b2018201a2004102c21180b2018450d052004211a0b2018200d6a200241e8006a2001109a051a20032104200a210d2006200120196a22194b0d000b0b2002200a3602402002410036023c2002200a3602382002201aad4220862018ad84370330410021014100210d02400240034002402001411f4d0d00410f210a0c020b02400240200a200c460d00200c417f460d08200a200c41016a22064f0d01200c41016a200a103c000b200241013a00482002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241f880046a200241e8006a1033200241206a41086a200241f880046a41086a280200360200200220022903f880043703204105210a0c020b2018200c6a2d000021042002200636023c200441ff00712001411f7174200d72210d200141076a21012006210c2004418001710d000b20014120490d0120044110490d01410d210a0b200241e880046a41086a200241206a41086a280200220d3602002002200229032022083703e880042008a7211b20022802ec8004210c0c150b41002119200241003602f08004200242043703e8800402400240200d0d004104210f41002118410021160c010b410021184104210f410021160340201821172016221d41016a2116410021014100210c024002400240034002402001411f4d0d00410f21040c020b0240024020022802382218200228023c2204460d00200441016a22062004490d0c201820064f0d0120062018103c000b200241013a00f880042002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241f880046a360218200241c8006a200241e8006a1033410521042002280248211b0c030b2002280230221a20046a2d0000210a2002200636023c200a41ff00712001411f7174200c72210c200141076a2101200a418001710d000b20014120490d02200a4110490d02410d21040b0b2002280250210d200228024c210c410021010c0c0b02400240024020182006460d00200441026a21042006417f460d0a20182004490d0c201a20066a2c000021012002200436023c0240200141004e0d00411921040c0f0b41062104200141c00071450d0d200141807f72220141ff017141fb014d0d0d201d2017460d0120172118201d21170c020b200241013a00482002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241f880046a200241e8006a103320022802f88004211b20022802fc8004210c20022802808104210d410521040c0d0b201741016a22042017490d31201741017422062004200620044b1b221841ffffffff01712018470d31201841037422044100480d310240024020170d0020041028210f0c010b200f20174103742004102c210f0b200f450d092002200f3602e880040b200f20174103746a2204201341807e712001417f7341ff01717222133a00042004200c3602002016200d470d000b200220183602ec8004200220163602f080040b200f20164103746a210d200f2101200f210602400340200d20066b41184d0d01201920012802006a22042019490d132004200141086a2802006a22062004490d132006200141106a2802006a22042006490d13200141186a210a200141206a220621012004200a2802006a22192004490d130c000b0b0340200d2001460d0b201920012802006a22042019492106200141086a21012004211920060d120c000b0b417f200341016a1044000b200420031044000b200441011037000b417f200c41016a1044000b417f20061044000b417f20041044000b200441041037000b20042018103c000b0b200220173602ec80042002201d3602f08004200141ff0171410874200472210a20170d090c0a0b4101210a410021044108211a410021060340200241e8006a200241306a10ee04024020022802684101470d002002280278210d2002280274210c2002280270211b200228026c210a0c070b200241f880046a41026a2201201041026a2d00003a0000200220102f00003b01f8800420022802742117200229037821080240024002400240024020022d0070220d4106470d00200a417f6a210a0c010b200d417e6a41034f0d00200a41016a220c200a4f2119200c210a20190d004115210c41c4fdc500211b4104210a200d4109460d010c0a0b200241e8006a41026a220c20012d00003a0000200220022f01f880043b016820062004460d01200421190c020b0240201728020441ffffffff0371450d002017280200102a0b2017102a0c080b200441016a22012004490d25200441017422062001200620014b1b221941ffffffff00712019470d25201941047422014100480d250240024020040d0020011028211a0c010b201a20044104742001102c211a0b201a450d0420042106201921040b201a20064104746a2201200d3a00002001200837030820012017360204200120022f01683b0001200141036a200c2d00003a0000200641016a2106200a0d000b200228023c200228024046210102402002280234450d002002280230102a0b0240024002402001450d002002280260220a200228025c470d02200a41016a2201200a490d26200a41017422042001200420014b1b220dad42187e2208422088a70d262008a7220441004e0d010c260b20024103410220011b3a00e880042002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a103320022802f88004211b20022802fc8004210c20022802808104210d02402006450d0020064104742104201a21010340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b02402019450d00201a102a0b4105210a2018450d0c200f102a0c0c0b02400240200a0d002004102821010c010b2002280258200a41186c2004102c21010b2001450d042002200d36025c200220013602580b20022802582201200a41186c6a2204201a36020c20042016360208200420183602042004200f360200200441146a2006360200200441106a20193602002002200a41016a360260201c2009470d000b0b2003201b462104200229025c2208422088210e02402007450d00200b102a0b200ea721032008a721072004450d0a2003ad4220862007ad842108410c21030c290b200141081037000b200441041037000b417f200141016a1044000b02402006450d0020064104742103201a21010340024020012d00004109470d000240200141046a2209280200220528020441ffffffff0371450d002005280200102a200928020021050b2005102a0b200141106a2101200341706a22030d000b0b2004450d01201a102a0c010b20022802808104210d20022802fc8004210c411c210a0b2018450d010b200f102a0b2002280234450d002002280230102a0b20022802582118024020022802602201450d002018200141186c6a21062018210903400240200941046a280200450d002009280200102a0b0240200941146a2802002204450d00200928020c2101200441047421040340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b200941186a21010240200941106a280200450d00200928020c102a0b2001210920012006470d000b0b200228025c450d002018102a0b200a4108762104200cad220e422086201bad8421082007450d01200b102a0c010b20024103410220041b3a0030200241e8006a41146a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a103320022903f88004210820022802808104210d02402003450d002001200341186c6a210b2001210603400240200641046a280200450d002006280200102a0b0240200641146a2802002203450d00200628020c2104200341047421030340024020042d00004109470d000240200441046a2209280200220528020441ffffffff0371450d002005280200102a200928020021050b2005102a0b200441106a2104200341706a22030d000b0b200641186a21040240200641106a280200450d00200628020c102a0b200421062004200b470d000b0b2008422088210e4105210a410021042007450d002001102a0b20004101360200200041106a200d360200200041086a200e422086200842ffffffff0f838437020020002004410874200a41ff0171723602040c210b200241e8006a200110fb040240024020022802684101470d00200228026c22044108762106200241e8006a41086a2903002208422088210e200241f8006a280200210b0c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a2902003703002002200229026c3703f880044100210141002105024002400240024002400240024002400240034002402001411f4d0d00410f210d0c020b02400240200228028081042209200228028481042204460d00200441016a22032004490d05200920034f0d0120032009103c000b200241013a0058200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200241e880046a41086a200241306a41086a280200360200200220022903303703e880044105210d0c020b20022802f8800420046a2d00002104200220033602848104200441ff00712001411f71742005722105200141076a21012004418001710d000b20014120490d01410d210d20044110490d010b200241c8006a41086a200241e880046a41086a280200220b360200200220022903e8800422083703482008422088a721072008a7210c410021060c060b200241003602f08004200242043703e880040240024020050d00410421010c010b4100210b0340200b41016a210b410021014100210902400240024002400240034002402001411f4d0d00410f210d0c030b200228028081042206200228028481042204460d01200441016a22032004490d0920062003490d0c20022802f8800420046a2d00002104200220033602848104200441ff00712001411f71742009722109200141076a21012004418001710d000b20014120490d022004410f4d0d02410d210d0c010b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200241206a41086a200241306a41086a2802003602002002200229033022083703202008a7210c4105210d0b2002280228210b20022802242107410021060c010b200241e8006a200241f880046a10ed04024020022802684101470d00200228026c220d41087621062002280278210b200228027421072002280270210c0c010b2002280274211b20022802702119200228026c2118200241e8006a200241f880046a10ef0420022802684101470d01200228026c210d2002280278210b200228027421072002280270210c0240201b450d00201b4104742104201821010340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b200d41087621062019450d002018102a0b20022802e88004211b024020022802f080042201450d00201b2001411c6c6a210a201b21090340024020092802042201450d0002402009410c6a2802002204450d00200441047421040340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b200941086a280200450d002009280204102a0b2009411c6a21010240200941146a280200450d002009280210102a0b200121092001200a470d000b0b20022802ec8004450d08201b102a0c080b4100210a2002280270210c200228026c2107024002402002280274220141027422030d004104210d410021060c010b2003410275220641ffffffff03712006470d1f200641027422044100480d1f20041028220d450d050b02402001450d002003417c6a210a200d210120072104034020012004280200360200200141046a2101200441046a21042003417c6a22030d000b200a41027641016a210a0b0240200c450d002007102a0b024020022802f08004220320022802ec8004470d00200341016a22012003490d1f200341017422042001200420014b1b2204ad421c7e2208422088a70d1f2008a722074100480d1f0240024020030d002007102821010c010b20022802e880042003411c6c2007102c21010b2001450d06200220043602ec8004200220013602e880040b20022802e8800422012003411c6c6a2204200941087622073b00012004200d36021020042018360204200420093a0000200441036a20074110763a0000200441186a200a360200200441146a20063602002004410c6a201b360200200441086a20193602002002200341016a3602f08004200b2005470d000b0b200228028481042002280288810446210420022902ec80042208422088210e024020022802fc8004450d0020022802f88004102a0b200ea721032008a7210d2004450d062003ad422086200dad842108410a21030c240b417f20031044000b417f20031044000b200441041037000b200741041037000b20032006103c000b2006410874200d41ff01717221042007ad220e422086200cad84210820022802fc8004450d0120022802f88004102a0c010b20024103410220041b3a00e88004200241e8006a41146a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a1033200229033021082002280238210b02402003450d0020012003411c6c6a210a200121060340024020062802042204450d0002402006410c6a2802002203450d00200341047421030340024020042d00004109470d000240200441046a2209280200220528020441ffffffff0371450d002005280200102a200928020021050b2005102a0b200441106a2104200341706a22030d000b0b200641086a280200450d002006280204102a0b2006411c6a21040240200641146a280200450d002006280210102a0b200421062004200a470d000b0b2008422088210e4105210441002106200d450d002001102a0b20004101360200200041106a200b360200200041086a200e422086200842ffffffff0f838437020020002006410874200441ff0171723602040c200b200d20064621040240200a450d00200b102a0b02402004450d00410921030c1c0b20024103410220041b3a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a10332002418381046a200241386a280200360000200220022903303700fb8004200041053a0004200020022900f880043700052000410c6a200241ff80046a290000370000200041013602000c1f0b200241013a0030200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a1033410521040b2000200436020420004101360200200041086a20022902f88004370200200041106a200241f880046a41086a280200360200200a450d1d200b102a0c1d0b200241e8006a200110fb040240024020022802684101470d00200228026c22034108762104200241e8006a41086a2903002208422088210e200241f8006a28020021090c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a2902003703002002200229026c3703f880044100210141002105024002400240024002400240024002400240024002400240024002400240024002400240034002402001411f4d0d00410f21030c020b02400240200228028081042209200228028481042204460d00200441016a22032004490d05200920034f0d0120032009103c000b200241013a0058200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200241206a41086a200241306a41086a28020036020020022002290330370320410521030c020b20022802f8800420046a2d00002104200220033602848104200441ff00712001411f71742005722105200141076a21012004418001710d000b20014120490d01410d210320044110490d010b200241e880046a41086a200241206a41086a28020022093602002002200229032022083703e880042008422088a721062008a7210b0c100b20024100360260200242043703584104210102402005450d004100211b4100210c4100211a0340200241e8006a200241f880046a10fc04024020022802684101470d002002200229027422083703e880042002280270210b200228026c21032008a721060c100b20022802702118200228026c211902400240200228028081042203200228028481042209460d00200941016a22042009490d05200320044f0d0120042003103c000b200241013a00482002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10330c0d0b2002280274211c20022802f88004220620096a2d000021072002200436028481040240200741034d0d00410a21040c0f0b0240024002400240024020070e0400010203000b410021074100210b4100210903400240200b411f4d0d00410f21040c140b20032004460d122004417f460d092003200441016a220d490d0e200620046a2d0000210a2002200d3602848104200a41ff0071200b411f71742009722109200b41076a210b200d2104200a418001710d000b41002107200b4120490d03200a410f4d0d03410d21040c120b4100210b410021090340200b411f4b0d0f0240024020032004460d002004417f460d0b2003200441016a220d4f0d01200441016a2003103c000b200241013a00482002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10330c110b200620046a2d0000210a2002200d3602848104200a41ff0071200b411f71742009722109200b41076a210b200d2104200a418001710d000b41012107200b4120490d02200a410f4d0d020c0d0b4100210b410021090340200b411f4b0d0e0240024020032004460d002004417f460d0b2003200441016a220d4f0d01200441016a2003103c000b200241013a00482002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10330c100b200620046a2d0000210a2002200d3602848104200a41ff0071200b411f71742009722109200b41076a210b200d2104200a418001710d000b41022107200b4120490d01200a410f4b0d0c0c010b4100210b410021090340200b411f4b0d0d0240024020032004460d002004417f460d0b2003200441016a220d4f0d01200441016a2003103c000b200241013a00482002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10330c0f0b200620046a2d0000210a2002200d3602848104200a41ff0071200b411f71742009722109200b41076a210b200d2104200a418001710d000b41032107200b4120490d00200a410f4b0d0b0b200220093602f08004200220073602ec800420022902ec8004210802400240200c201b460d00201b21030c010b201b41016a2204201b490d24201b41017422032004200320044b1b2203ad42147e220e422088a70d24200ea722044100480d2402400240201b0d002004102821010c010b2001201b41146c2004102c21010b2001450d0920022001360258201b210c2003211b0b2001200c41146c6a2204200837020c2004201c3602082004201836020420042019360200200c41016a210c201a41016a221a2005470d000b2002200336025c2002200c3602600b2002280284810420022802888104462104200229025c2208422088210e024020022802fc8004450d0020022802f88004102a0b200ea721032008a721052004450d0e2003ad4220862005ad842108410821030c290b417f20031044000b417f20041044000b417f200441016a1044000b417f200441016a1044000b417f200441016a1044000b417f200441016a1044000b200441041037000b200441016a2003103c000b410d2104410021070c030b410f2104410021070c020b2002280230210b2002290234210841052104410021070c010b200241013a00482002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10332002280230210b20022902342108410521040b20074108742004722103200220083703e880042008a721062018450d002019102a0b2002200c3602602002201b36025c20022802ec800421090240200c450d00200c41146c21052001210403400240200441046a280200450d002004280200102a0b200441146a21042005416c6a22050d000b0b201b450d012001102a0c010b20024103410220041b3a00e88004200241e8006a41146a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a1033200229033021082002280238210902402003450d00200341146c21032001210403400240200441046a280200450d002004280200102a0b200441146a21042003416c6a22030d000b0b2008422088210e41052103410021042005450d012001102a0c010b200341087621042006ad220e422086200bad84210820022802fc8004450d0020022802f88004102a0b20004101360200200041106a2009360200200041086a200e422086200842ffffffff0f838437020020002004410874200341ff0171723602040c1c0b200241e8006a200110fb040240024020022802684101470d00200228026c220b4108762104200241e8006a41086a2903002208422088210e200241f8006a28020021060c010b200241c0006a200241fc006a280200360200200241386a200241f4006a2902003703002002200229026c37033041002101410021090240024002400240024002400240024002400240024002400240034002402001411f4d0d00410f210b0c020b0240024020022802382205200228023c2204460d00200441016a22032004490d05200520034f0d0120032005103c000b200241013a0058200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241f880046a200241e8006a1033200241206a41086a200241f880046a41086a280200360200200220022903f880043703204105210b0c020b2002280230220620046a2d000021042002200336023c200441ff00712001411f71742009722109200141076a21012004418001710d000b20014120490d01410d210b20044110490d010b200241e880046a41086a200241206a41086a28020022063602002002200229032022083703e880042008422088a721072008a7210d0c0b0b20024100360260200242043703580240024020090d00410421010c010b2009417f6a211b4104210141042110410421094104211c4104211a4100210a4100210c03400240024020052003460d00200341016a220b2003490d052005200b4f0d01200b2005103c000b2002200a36025c2002200c360260200241013a0048200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241e880046a200241e8006a103320022802e88004210d20022802ec8004210720022802f080042106410521010c090b200620036a2c000021042002200b36023c20044100480d0402400240200441c00071450d00200441807f72220441ff017141fb014b0d010b2002200a36025c2002200c360260410621010c080b024002400240024002402005200b460d00200341026a210d200b417f460d0a2005200d4f0d01200d2005103c000b2002200a36025c2002200c360260200241013a0048200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241c8006a360218200241e880046a200241e8006a103320022802e88004210d20022802ec8004210720022802f080042106410521010c010b2006200b6a2d000021032002200d36023c0240200341014b0d004100210520030e020302030b2002200a36025c2002200c360260410c21010b2002418881046a20063602002002418481046a20073602002002418081046a200d360200200220033a00fd8004200220013a00fc80040c0b0b41800221050b200241e8006a200241306a10ed04200228027421072002280270210d200228026c210b024020022802684101470d002002200a36025c2002200c360260200241f8006a28020021060c0b0b02400240200c200a460d00200a2118200c210a0c010b200a41016a2201200a490d1e200a41017422032001200320014b1b221841ffffffff00712018470d1e201841047422034100480d1e02400240200a0d002003102821010c010b201c200a4104742003102c21010b2001450d072002200136025820012110200121092001211c2001211a0b201a200a4104746a220320194180807c712004417f7341ff017172200572221936020c200320073602082003200d3602042003200b360200200a41016a210c0240201b450d00201b417f6a211b200228023c210320022802382105200228023021062018210a0c010b0b2002201836025c2002200c3602600b200228023c2002280240462104200229025c2208422088210e02402002280234450d002002280230102a0b200ea721032008a7210d2004450d092003ad422086200dad842108410721030c230b417f20031044000b417f200b1044000b2002200a36025c2002200c360260411921010c020b417f200d1044000b200341041037000b0b2002418881046a20063602002002418481046a20073602002002418081046a200d360200200220043a00fd8004200220013a00fc80040b200241013a00f8800420022802fc8004210b0b0240200c450d002009200c4104746a210c0340024020092802082204450d0020092802002101200441047421040340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d002003280200102a200528020021030b2003102a0b200141106a2101200441706a22040d000b0b200941106a21010240200941046a280200450d002009280200102a0b200121092001200c470d000b0b200a450d012010102a0c010b20024103410220041b3a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a103320022903f88004210820022802808104210602402003450d00200120034104746a210a2001210b03400240200b2802082203450d00200b2802002104200341047421030340024020042d00004109470d000240200441046a2209280200220528020441ffffffff0371450d002005280200102a200928020021050b2005102a0b200441106a2104200341706a22030d000b0b200b41106a21040240200b41046a280200450d00200b280200102a0b2004210b2004200a470d000b0b2008422088210e4105210b41002104200d450d012001102a0c010b200b41087621042007ad220e422086200dad8421082002280234450d002002280230102a0b20004101360200200041106a2006360200200041086a200e422086200842ffffffff0f838437020020002004410874200b41ff0171723602040c1b0b200241e8006a200110fb040240024020022802684101470d00200228026c22034108762105200241e8006a41086a2903002208422088210e200241f8006a28020021040c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a29020022083703002002200229026c220e3703f88004200ea7210b2008a7210541002104200228028481042101410021030240024002400240024002400240024003402004411f4b0d010240024020052001460d002001417f460d072005200141016a22094f0d01200141016a2005103c000b200220053602848104200241013a0058200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200241206a41086a200241306a41086a280200360200200220022903303703204105210b0c030b200b20016a2d0000220641ff00712004411f71742003722103200441076a2104200921012006418001710d000b200220093602848104024020044120490d00410d210b2006410f4b0d020b200241003602382002420437033020030d02410421010c030b200220013602848104410f210b0b200241e880046a41086a200241206a41086a28020022043602002002200229032022083703e880042008422088a7210a2008a7210d410021090c040b4104210141002105410021060340200241e8006a200241f880046a10f30420022f006d20022d006f4110747221092002280274210a2002280270210d20022d006c210b024020022802684101470d002002200536023420022006360238200241f8006a28020021042005450d052001102a0c050b0240024020062005460d0020052107200621040c010b200541016a22042005490d16200541017422072004200720044b1b2207ad420c7e2208422088a70d162008a722044100480d160240024020050d002004102821010c010b20012005410c6c2004102c21010b2001450d042002200136023020052104200721050b20012004410c6c6a220420093b00012004200d3602042004200b3a0000200441036a20094110763a0000200441086a200a3602002003200641016a2206470d000b20022007360234200220063602380b200228028481042002280288810446210420022902342108024020022802fc8004450d0020022802f88004102a0b2008a721092004450d032008422088a7ad4220862009ad842108410621030c1b0b417f200141016a1044000b200441041037000b200941ffffff07712205410874200b41ff0171722103200aad220e422086200dad84210820022802fc8004450d0120022802f88004102a0c010b20024103410220041b3a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a103320022903302208422088210e2002280238210441052103410021052009450d002001102a0b20004101360200200041106a2004360200200041086a200e422086200842ffffffff0f838437020020002005410874200341ff0171723602040c1a0b200241e8006a200110fb040240024020022802684101470d00200228026c22034108762105200241e8006a41086a2903002208422088210e200241f8006a28020021040c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a29020022083703002002200229026c220e3703f88004200ea7210b2008a721034100210420022802848104210141002109024002400240024002400240024002400240024003402004411f4b0d010240024020032001460d002001417f460d072003200141016a22054f0d01200141016a2003103c000b200220033602848104200241013a0058200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200241206a41086a200241306a41086a280200360200200220022903303703204105210a0c030b200b20016a2d0000220641ff00712004411f71742009722109200441076a2104200521012006418001710d000b200220053602848104024020044120490d00410d210a2006410f4b0d020b41002107200241003602f08004200242043703e8800420090d02410421014100210d0c030b200220013602848104410f210a0b200241e880046a41086a200241206a41086a28020022043602002002200229032022083703e880042008a7210b4100210320022802ec8004210d0c060b4104210141012107410021060340024002400240024020032005460d00200541016a22042005490d0720032004490d09200b20056a2c000021032002200436028481040240200341004e0d004119210a0c020b4107210a0240200341c000710d000c020b200341807f7222034170470d02200241e8006a200241f880046a10f30420022f006d20022d006f41107472210320022d006c210a20022802684101470d0320034180feff07714108762105200228027821042002280274210d2002280270210b0c020b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10332002280230210b2002280234210d200228023821044105210a0b0b200220063602ec800420022007417f6a3602f080042005410874200341ff01717221032006450d072001102a0c070b200228027421052002280270210b024002402007417f6a22042006460d002006210d200421060c010b200641016a22042006490d172006410174220d2004200d20044b1b220dad420c7e2208422088a70d172008a722044100480d170240024020060d002004102821010c010b20012006410c6c2004102c21010b2001450d05200220013602e880040b20012006410c6c6a220420033b0001200420053602082004200b3602042004200a3a0000200441036a20034110763a0000024020092007460d00200741016a210720022802848104210520022802808104210320022802f88004210b200d21060c010b0b2002200d3602ec8004200220073602f080040b2002280284810420022802888104462104024020022802fc8004450d0020022802f88004102a0b2004450d052007ad422086200dad842108410521030c1c0b417f200141016a1044000b417f20041044000b200441041037000b20042003103c000b200341ffffff07712205410874200a41ff0171722103200dad220e422086200bad84210820022802fc8004450d0120022802f88004102a0c010b20024103410220041b3a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a103320022903302208422088210e200228023821044105210341002105200d450d002001102a0b20004101360200200041106a2004360200200041086a200e422086200842ffffffff0f838437020020002005410874200341ff0171723602040c190b200241e8006a200110fb040240024020022802684101470d00200228026c22044108762105200241e8006a41086a2903002208422088210e200241f8006a28020021030c010b200241fc006a280200210c200241f8006a2802002101200241f4006a2802002103200241f0006a2802002107200228026c210b41002104410021090240024002400240024002400240024002400240034002402004411f4d0d00410f21040c020b0240024020032001460d002001417f460d052003200141016a22054f0d01200141016a2003103c000b200241013a0030200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a1033200241206a41086a200241f880046a41086a280200360200200220022903f88004370320410521040c020b200b20016a2d0000220641ff00712004411f71742009722109200441076a2104200521012006418001710d000b20044120490d01410d210420064110490d010b200241e880046a41086a200241206a41086a28020022033602002002200229032022083703e880042008a7210520022802ec800421090c070b4100211b20024100360238200242043703300240024020090d0041042101410021060c010b41042101410021064100211b034020062118201b221941016a211b20052104410021064100210a03402006411f4b0d050240024020032004460d002004417f460d062003200441016a22054f0d01200441016a2003103c000b2002201836023420022019360238200241013a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a103320022802f88004210520022802fc80042109200228028081042103410521040c090b200b20046a2d0000220d41ff00712006411f7174200a72210a200641076a210620052104200d418001710d000b024020064120490d00200d410f4d0d002002201836023420022019360238410d21040c070b0240024020192018460d0020182106201921180c010b201841016a22042018490d18201841017422062004200620044b1b220641ffffffff03712006470d18200641027422044100480d180240024020180d002004102821010c010b200120184102742004102c21010b2001450d06200220013602300b200120184102746a200a360200201b2009470d000b200220063602342002201b3602380b2005200c46210402402007450d00200b102a0b2004450d07201bad4220862006ad842108410421030c1d0b417f200141016a1044000b417f200441016a1044000b2002201836023420022019360238410f21040c010b200441041037000b0b2018450d002001102a0b2009ad220e4220862005ad842108410021052007450d01200b102a0c010b20024103410220041b3a0030200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a103320022903f880042208422088210e20022802808104210341052104410021052006450d002001102a0b20004101360200200041106a2003360200200041086a200e422086200842ffffffff0f838437020020002005410874200441ff0171723602040c180b200241e8006a200110fb040240024020022802684101470d00200228026c22034108762105200241e8006a41086a2903002208422088210e200241f8006a28020021040c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a2902003703002002200229026c3703f8800441002101410021050240024002400240024002400240024002400240034002402001411f4d0d00410f21030c020b02400240200228028081042209200228028481042204460d00200441016a22032004490d05200920034f0d0120032009103c000b200241013a0058200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200241206a41086a200241306a41086a28020036020020022002290330370320410521030c020b20022802f8800420046a2d00002104200220033602848104200441ff00712001411f71742005722105200141076a21012004418001710d000b20014120490d01410d210320044110490d010b200241e880046a41086a200241206a41086a28020022043602002002200229032022083703e880042008422088a721092008a721060c080b200241003602f08004200242043703e8800402400240024020050d00410421010c010b20022802ec8004210720022802f08004210d410021100340200241e8006a200241f880046a10fc042002280274210920022802702118200228026c211a024020022802684101470d002002280278210420182106201a21030c090b200241e8006a200241f880046a10fc042002280274211320022802702119200228026c211c024020022802684101470d00200228027821042019210620132109201c21030c080b0240024002400240024002400240024002400240024002400240024002400240200228028081042203200228028481042206460d00200641016a22012006490d02200320014f0d0120012003103c000b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200228023021062002290234210e4105210a4100211b410021030c150b20022802f88004220c20066a2d000021042002200136028481044100211b0240200441034d0d004109210a410021030c150b024002400240024020040e0400010203000b4100211b410021044100210a034002402004411f4d0d00410f210a0c170b0240024020032001460d002001417f460d072003200141016a220b4f0d01200141016a2003103c000b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200228023021062002290234210e4105210a4100211b0c180b200c20016a2d000021062002200b3602848104200641ff00712004411f7174200a72210a200441076a2104200b21012006418001710d000b4100211b20044120490d0f2006410f4d0d0f410d210a0c150b0240024020032001460d00200641026a21042001417f460d0620032004490d07200c20016a2c0000210120022004360284810402402001417f4a0d00411921030c0e0b200141c000710d010c0c0b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10332002290330210820022802382104410521030c0c0b200141807f7222014170470d0a200241e8006a200241f880046a10f30420022903702108200228026c210a024020022802684101470d00200228027821040c0d0b4101211b0c0f0b200241e8006a200241f880046a10f30420022903702108200228026c210a024020022802684101460d004102211b0c0f0b20022002280278360270200a418080807871211b200a4180807c712103200a41087621040c0c0b0240024020032001460d00200641026a210b2001417f460d062003200b490d08200c20016a2c000021042002200b36028481040240200441004e0d004119210a410021030c170b200441c000710d010c090b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10334105210a2002290234210e20022802302106410021030c150b200441807f72220441ff017141fc01490d07024002402003200b460d00200641036a2101200b417f460d07200320014f0d0120012003103c000b200241013a00582002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a1033200228023021062002290234210e4105210a410021030c150b200c200b6a2d0000210b200220013602848104410021030240200b41014d0d00410c210a4100211b200b21040c150b2004417f7321064103211b0240200b0e020e000e0b410121030c0d0b417f20011044000b417f200141016a1044000b417f20041044000b20042003103c000b417f200b1044000b417f20011044000b200b2003103c000b4106210a410021030c0c0b410721030b200141ff0171410874200372210a0b20022004360270200a418080807871211b200a4180807c712103200a41087621040b20022008370368200229026c210e2008a721060c080b0b02400240200d2007460d002007210b0c010b200741016a22012007490d18200741017422042001200420014b1b220bad42287e220e422088a70d18200ea722044100480d180240024020070d002004102821010c010b20022802e88004200741286c2004102c21010b2001450d03200220013602e880042007210d200b21070b20022802e880042201200d41286c6a2204201c36020c20042009360208200420183602042004201a360200200441206a20083702002004411c6a200a3602002004411a6a20033a0000200441196a20063a0000200441186a201b3a0000200441146a2013360200200441106a2019360200200d41016a210d201041016a22102005470d000b2002200b3602ec80042002200d3602f080040b200228028481042002280288810446210420022902ec80042208422088210e024020022802fc8004450d0020022802f88004102a0b200ea721032008a721092004450d072003ad4220862009ad842108410321030c1d0b200441041037000b417f20031044000b0b41002103410021040b200a41ff0171200441ff0171410874722003418080fc077172201b722103200e422088a72104200ea721092019450d00201c102a0b2018450d00201a102a0b200220073602ec80042002200d3602f0800420022802e88004210b0240200d450d00200d41286c2105200b210103400240200141046a280200450d002001280200102a0b0240200141106a280200450d002001410c6a280200102a0b200141286a2101200541586a22050d000b0b2007450d01200b102a0c010b20024103410220041b3a00e88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a1033200229033021082002280238210402402003450d00200341286c21052001210303400240200341046a280200450d002003280200102a0b0240200341106a280200450d002003410c6a280200102a0b200341286a2103200541586a22050d000b0b2008422088210e41052103410021052009450d012001102a0c010b200341087621052009ad220e4220862006ad84210820022802fc8004450d0020022802f88004102a0b20004101360200200041106a2004360200200041086a200e422086200842ffffffff0f838437020020002005410874200341ff0171723602040c170b200241013a00302002410136027c2002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a103320022802f88004210620022802fc8004210920022d00808104210320022d00818104210720022f01828104210d410521050b0b201d450d03200c102a0c030b0b2019450d00201c102a0b2003411076210d200341087621070b200741ff0171410874200341ff0171722103200d411074210d200441ff0171410874210702402017450d002001210403400240200441046a280200450d002004280200102a0b200441106a2104200a41706a220a0d000b0b2003200d722103200720057221042014450d012001102a0c010b20024103410220041b3a0030200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a103320022903f88004210820022802808104210302402005450d00200541047421052001210403400240200441046a280200450d002004280200102a0b200441106a2104200541706a22050d000b0b2008422088210e41052104410021052009450d012001102a0c010b200441087621052009ad220e4220862006ad8421082010450d00200b102a0b20004101360200200041106a2003360200200041086a200e422086200842ffffffff0f838437020020002005410874200441ff0171723602040c0d0b41002101410021040240024002400340024020094105470d00410f21070c020b0240024020032009460d00200320094b0d01200941016a2003103c000b200241013a00f88004200241fc006a41013602002002420137026c200241a4e2c5003602682002412636021c2002200241186a3602782002200241f880046a360218200241206a200241e8006a103341052107200229032021080c030b200620096a2d0000220541ff00712001411f71742004722104200141076a2101200941016a220b21092005418001710d000b20014120490d0220054110490d02410d21070b0b2008422088a72109200228022821042008a7210d0c050b024020040d00410021054101211b410021094100210d0c080b200241e8006a41004180081099051a410021054100210d4101211b410021070340024002402003200b6b200420076b22014180082001418008491b2201490d00200b20016a220c200b490d042003200c4f0d01200c2003103c000b200241013a00e880042002418c81046a4101360200200242013702fc8004200241a4e2c5003602f880042002412636021c2002200241186a36028881042002200241e880046a360218200241306a200241f880046a103320022903302208422088a72109200228023821042008a72101410521070240200d450d00201b102a0b2001210d0c060b200241e8006a2006200b6a2001109a051a02400240200d20056b2001490d00200520016a21090c010b200520016a22092005490d02200d410174220b2009200b20094b1b220b4100480d0202400240200d0d00200b1028211b0c010b201b200d200b102c211b0b201b450d04200b210d0b201b20056a200241e8006a2001109a051a20092105200c210b2004200120076a22074d0d040c000b0b1031000b200b200c1044000b200b41011037000b200241e8006a201b2009105420022802684101470d02410821070240200d450d00201b102a0b0b2009ad422086200dad84210841002101200a450d002006102a0b20004101360200200041106a2004360200200041086a200837020020002001410874200741ff0171723602040c060b201b4108762105200c210b0b2003200b490d012003200b6b2201417f4c0d020240024020010d00410121040c010b200110282204450d040b2009ad4220862108200dad210e20042006200b6a2001109a051a2001ad222042208621210240200a450d002006102a0b2008200e8421082021202084210e2005410874201b41ff0171722101410121030b200020033a000420004100360200200041056a20022f00153b0000200041186a200e370200200041146a20043602002000410c6a2008370200200041086a2001360200200041206a2002290200370200200041076a200241176a2d00003a0000200041286a200241086a290200370200200041306a200241106a2802003602000c030b200b20031044000b1036000b200141011037000b2002419081046a24000bf304010b7f230041c080016b220224002002200110f404410121030240024020022802004101470d0020002002290204370204200041013602002000410c6a2002410c6a2902003702000c010b2002280204210420024100418080011099052105410021064100210702400240024002402004450d00410021084100210641012103410021090340024002402001280204220a200128020822076b200420096b220b41808001200b41808001491b220b490d002007200b6a220c2007490d04200a200c4f0d01200c200a103c000b200541013a008f8001200541b480016a4101360200200542013702a48001200541a4e2c5003602a08001200541263602bc80012005200541b880016a3602b0800120052005418f80016a3602b880012005419080016a200541a080016a10332005418b80016a2005419880016a2802003600002005200529039080013700838001200041053a00042000200529008080013700052000410c6a2005418780016a290000370000200041013602002006450d062003102a0c060b2005200128020020076a200b109a05210a2001200c36020802400240200620086b200b490d002008200b6a21070c010b2008200b6a22072008490d052006410174220c2007200c20074b1b220c4100480d050240024020060d00200c102821030c010b20032006200c102c21030b2003450d04200c21060b200320086a200a200b109a051a200721082004200b20096a22094b0d000b0b2000200336020420004100360200200041146a2007360200200041106a41003602002000410c6a2007360200200041086a20063602000c030b2007200c1044000b200c41011037000b1031000b200241c080016a24000b8607010b7f230041d0086b22022400410021034100210402400240024002400240024002400240034002402003411f4d0d00410f21030c020b0240024020012802082205200128020c2206460d00200641016a22072006490d05200520074f0d0120072005103c000b200241013a0089082002411c6a41013602002002420137020c200241a4e2c5003602082002412636029c08200220024198086a360218200220024189086a36029808200241b8086a200241086a1033410521030c020b2001280200220820066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b20034120490d01410d210320064110490d010b2000200336020420004101360200200041086a20022902b808370200200041106a200241b8086a41086a2802003602000c060b024020040d002000428080808010370200200041086a42003702000c060b200241086a41004180081099051a41002106410021094101210a4100210b034002400240200520076b2004200b6b22034180082003418008491b2203490d00200720036a220c2007490d042005200c4f0d01200c2005103c000b200241013a00a708200241cc086a4101360200200242013702bc08200241a4e2c5003602b8082002412636029c08200220024198086a3602c8082002200241a7086a36029808200241a8086a200241b8086a103320024194086a200241b0086a280200360000200220022903a80837008c08200041053a000420002002290089083700052000410c6a20024190086a290000370000200041013602002009450d07200a102a0c070b200241086a200820076a2003109a051a2001200c36020c02400240200920066b2003490d00200620036a210c0c010b200620036a220c2006490d0520094101742207200c2007200c4b1b22074100480d050240024020090d0020071028210a0c010b200a20092007102c210a0b200a450d04200721090b200a20066a200241086a2003109a051a20042003200b6a220b4d0d05200128020c21072001280208210520012802002108200c21060c000b0b417f20071044000b2007200c1044000b200741011037000b1031000b200241086a200a200c1054024020022802084101470d0002402009450d00200a102a0b200041083a0004200041013602000c010b2000200a3602042000410c6a200c360200200041086a2009360200200041003602000b200241d0086a24000b881f03127f017e037f23004180026b220524000240024020014115490d00410121064101210702400240034020012108200021092006200771410173210a024002400240034002400240024002402004450d00024020064101710d002000200110fe042004417f6a21040b2001410276220741036c210b2007410174210c4100210d20014132490d03200741016a210e200020074103746a220f28020020002007417f6a220d4103746a2210280200201041046a2802002210200f41046a280200220f200f20104b1b109c052211450d01417f410120114100481b21100c020b2000200110ff040c0b0b417f200f201047200f2010491b21100b2007200d2010417f4622101b210f024002402000200e4103746a22112802002000200d200720101b22124103746a2207280200200741046a2802002207201141046a280200220d200d20074b1b109c052211450d00417f410120114100481b21070c010b417f200d200747200d2007491b21070b4102410120101b20102007417f4622071b210d024002402000200e201220071b22114103746a22102802002000200f4103746a2207280200200741046a2802002207201041046a2802002210201020074b1b109c05220e450d00417f4101200e4100481b21100c010b417f201020074720102007491b21100b200c4101722107200d2010417f4622126a2113024002402000200c4103746a220d2802002000200c417f6a22104103746a220e280200200e41046a280200220e200d41046a280200220d200d200e4b1b109c052214450d00417f410120144100481b210e0c010b417f200d200e47200d200e491b210e0b200c2010200e417f46220e1b210d2013200e6a211302400240200020074103746a221428020020002010200c200e1b220e4103746a220c280200200c41046a280200220c201441046a28020022102010200c4b1b109c052214450d00417f410120144100481b210c0c010b417f2010200c472010200c491b210c0b2013200c417f46220c6a21100240024020002007200e200c1b22134103746a220c2802002000200d4103746a2207280200200741046a2802002207200c41046a280200220c200c20074b1b109c05220e450d00417f4101200e4100481b210c0c010b417f200c200747200c2007491b210c0b200b41016a21072010200c417f4622146a2115024002402000200b4103746a220e2802002000200b417f6a220c4103746a2210280200201041046a2802002210200e41046a280200220e200e20104b1b109c052216450d00417f410120164100481b21100c010b417f200e201047200e2010491b21100b200b200c2010417f4622101b210e201520106a211502400240200020074103746a22162802002000200c200b20101b22104103746a220c280200200c41046a280200220c201641046a280200220b200b200c4b1b109c052216450d00417f410120164100481b210c0c010b417f200b200c47200b200c491b210c0b2015200c417f46220c6a211502400240200020072010200c1b220b4103746a220c2802002000200e4103746a2207280200200741046a2802002207200c41046a280200220c200c20074b1b109c052210450d00417f410120104100481b21100c010b417f200c200747200c2007491b21100b200f201120121b2107200d201320141b210c200e200b2010417f4622101b210b201520106a210d0b024002402000200c4103746a220e280200200020074103746a2210280200201041046a2802002210200e41046a280200220e200e20104b1b109c05220f450d00417f4101200f4100481b21100c010b417f200e201047200e2010491b21100b200c20072010417f46220e1b2110200d200e6a210d024002402000200b4103746a220f28020020002007200c200e1b220e4103746a2207280200200741046a2802002207200f41046a280200220c200c20074b1b109c05220f450d00417f4101200f4100481b21070c010b417f200c200747200c2007491b21070b200d2007417f46220c6a2107024002400240024002402000200b200e200c1b220d4103746a220b280200200020104103746a220c280200200c41046a280200220c200b41046a280200220b200b200c4b1b109c05220e450d00200e4100480d010c020b200b200c4f0d010b200741016a2207410c490d0102402001410176220b450d00200020014103746a41786a21072000210c0340200c2902002117200c200729020037020020072017370200200c41086a210c200741786a2107200b417f6a220b0d000b0b20012010417f736a2110410121070c020b200d21100b20074521070b0240200745200a724101710d00200020011080050d090b2003450d010240201020014f0d00024002402003280200200020104103746a2207280200200741046a280200220c200341046a280200220b200b200c4b1b109c05220e450d00200e41004e0d010c050b200b200c490d040b200029020021172000200729020037020020072017370200200041786a21122000410c6a2113200041086a2114200028020421072000280200210d4100210b2001210e0340024002400240200b200e417f6a22114f0d002013200b4103746a210c034002400240200d200c417c6a280200200c28020022102007200720104b1b109c05220f450d00200f4100480d030c010b20072010490d020b200c41086a210c2011200b41016a220b470d000c020b0b0240200b20114f0d002012200e4103746a210c2011210e034002400240200d200c280200200c41046a28020022102007200720104b1b109c05220f450d00200f4100480d010c050b200720104f0d040b200c41786a210c200b200e417f6a220e490d000b0b200b21110b200020073602042000200d36020002402001201141016a2207490d00200020074103746a2100200120076b220141154f0d040c0b0b200720011044000b2014200b4103746a221029020021172010200c290200370200200c2017370200200b41016a210b0c000b0b0b41f483c600201020011034000b20080d0141bc83c600410041001034000b20002109200121080b201020084f0d02200929020021172009200920104103746a2207290200370200200720173702002009280204210c2009280200211241002100410021184100211902402008417f6a220e450d002009410c6a21074100211803400240024002402007417c6a2802002012200c2007280200220b200b200c4b1b109c052210450d00201041004e0d010c020b200b200c490d010b200e21190240200e20184d0d00200920084103746a41786a2107200e211903400240024020072802002012200c200741046a280200220b200b200c4b1b109c052210450d00201041004e0d010c030b200b200c490d020b200741786a21072019417f6a221920184b0d000b0b0240024020192018490d00200e2019490d010c040b201820191044000b2019200e103c000b200741086a2107200e201841016a2218470d000b200e2118200e21190b200941086a220720194103746a210e41800121144100211141002110410021014180012106200720184103746a221a210d03400240200e200d6b22074187104b220a0d002007410376220741807f6a200720112000492001201049220b72220f1b21070240200f450d0020062007200b1b210620072014200b1b21140c010b2007200741017622066b21140b024020012010470d00024020060d002005221021010c010b4100210720052110200d210b0340201020073a0000200741016a210702400240200b2802002012200c200b41046a280200220f200f200c4b1b109c052201450d00417f410120014100481b210f0c010b417f200f200c47200f200c491b210f0b200b41086a210b2010200f417f476a211020062007470d000b200521010b024020112000470d00024020140d0020054180016a220021110c010b200e41786a21074100210b20054180016a210003402000200b3a0000200b41016a210b0240024020072802002012200c200741046a280200220f200f200c4b1b109c052211450d00417f410120114100481b210f0c010b417f200f200c47200f200c491b210f0b200741786a21072000200f417f466a21002014200b470d000b20054180016a21110b0240200020116b2207201020016b220b200b20074b1b2213450d00200d20012d00004103746a22072802042115200728020021162007200e20112d0000417f734103746a290200370200024020134101460d00410021070340200e201120076a220b2d0000417f734103746a200d200120076a41016a220f2d00004103746a290200370200200d200f2d00004103746a200e200b41016a2d0000417f734103746a290200370200200741026a210b200741016a220f2107200b2013490d000b2011200f6a21112001200f6a21010b200e20112d0000417f734103746a2207201536020420072016360200201141016a2111200141016a21010b200e20144103746b200e20112000461b210e200d20064103746a200d20012010461b210d200a0d000b02400240200120104f0d00200e21070340200d2010417f6a22102d00004103746a220b2902002117200b200741786a22072902003702002007201737020020012010490d000c020b0b200d2107201120004f0d000340200729020021172007200e2000417f6a22002d0000417f734103746a220b290200370200200b2017370200200741086a210720112000490d000b0b2009200c36020420092012360200024020082007201a6b41037620186a22014d0d00200929020021172009200920014103746a220729020037020020072017370200200820016b220c450d02200c20012001200c4b1b210b20084103762110200741086a2100024002402001200c417f6a220c490d002000200c20022007200410fd04200921000c010b2009200120022003200410fd0420072103200c21010b200b20104f2106201920184d2107200141154f0d010c040b0b41cc83c600200120081034000b41dc83c6001032000b41cc83c600201020081034000b20014102490d00200041786a211341002114410121120340201241037421072012417f6a2110201241016a2112024002400240200020076a22072802002211200020104103746a220f280200200f41046a280200220c200741046a280200220b200b200c4b1b109c05220e450d00200e4100480d010c020b200b200c4f0d010b2007200f29020037020002402010450d002014210c20132107024003400240024020112007280200200741046a280200220e200b200b200e4b1b109c05220d450d00200d4100480d010c030b200b200e4f0d030b20002010417f6a22104103746a210f200741086a2007290200370200200741786a2107200c41016a220e200c49210d200e210c200d450d000b0b200741086a210f0b200f200b360204200f20113602000b2014417f6a2114201341086a211320122001470d000b0b20054180026a24000bf50202057f017e02400240024020014108490d00200141017641feffffff07712202417f6a220320014f0d022001410d74200173220441117620047322044105742004732205417f2001417f6a677622067122044100200120042001491b6b220420014f0d01200020034103746a220329020021072003200020044103746a220429020037020020042007370200024020022001490d00200221030c030b2005410d7420057322044111762004732204410574200473220520067122044100200120042001491b6b220420014f0d01200020024103746a220329020021072003200020044103746a2204290200370200200420073702002002410172220320014f0d022005410d742005732204411176200473220441057420047320067122044100200120042001491b6b220420014f0d01200020034103746a220129020021072001200020044103746a2200290200370200200020073702000b0f0b41cc83c600200420011034000b41bc83c600200320011034000bb20102037f017e024020014101762202450d00200020012002417f6a1081052002417e6a210203402002417f460d012000200120021081052002417f6a21020c000b0b0240024020014102490d00200141037420006a41786a21022001210303402003417f6a220420014f0d02200029020021052000200229020037020020022005370200200020044100108105200241786a210220042103200441014b0d000b0b0f0b41cc83c6002003417f6a20011034000b9a06050a7f017e017f017e037f200041686a2102200041786a2103200141324921044101210541002106024003400240024020052001490d00410021070c010b200320054103746a210841012107034002400240200841086a22092802002008280200200841046a280200220a2008410c6a28020022082008200a4b1b109c05220b450d00200b4100480d030c010b2008200a490d020b4101210a200541016a220520014921072009210820012005470d000c030b0b2005200146210a20040d0120052001460d01024002400240024002402005417f6a220820014f0d002007410171450d01200020084103746a2208290200210c200820002005410374220d6a220b290200220e370200200b200c37020020054102490d0402400240200ea7220f20002005417e6a220a4103746a2210280200201041046a2802002207200841046a2802002209200920074b1b109c052211450d0020114100480d010c060b200920074f0d050b20082010290200370200200a450d032002200d6a2108034002400240200f2008280200200841046a28020022072009200920074b1b109c05220d450d00200d4100480d010c050b200920074f0d050b2000200a417f6a220a4103746a2110200841086a2008290200370200200841786a2108200a0d000c030b0b41bc83c600200820011034000b41cc83c600200520011034000b200841086a21100b201020093602042010200f3602000b200641016a21060240200120056b220d4102490d0002400240200b280208200b280200220f200b41046a2802002209200b410c6a2802002208200820094b1b109c05220a450d00200a4100480d010c020b200820094f0d010b200b41086a2111200b200b2902083702000240200d4103490d004103210a41022107034002400240200b20074103746a2208280200200f2009200841046a2802002207200720094b1b109c052210450d00201041004e0d030c010b200720094f0d020b200841786a20082902003702000240200a200d4f0d00200a2107200a41016a210a200821110c010b0b200821110b2011200f360200201120093602040b20064105470d000b4100210a0b200a0bb60202057f017e03402002410174220341017221040240024002400240200341026a220320014f0d00200420014f0d0102400240200020044103746a2205280200200020034103746a2206280200200641046a2802002206200541046a2802002205200520064b1b109c052207450d00417f410120074100481b21060c010b417f200520064720052006491b21060b200320042006417f461b21040b0240200420014f0d00200220014f0d020240200020024103746a2202280200200020044103746a2203280200200341046a2802002206200241046a2802002205200520064b1b109c052207450d00200741004e0d010c040b20052006490d030b0f0b41c885c600200420011034000b41d885c600200220011034000b200229020021082002200329020037020020032008370200200421020c000b0b1500200120002802002200280200200028020810450bf30201037f230041c0006b22022400200141086a2802002103200128020421042002200128020022013602100240024002402001418080044b0d0002402004450d0020022003360214200120034b0d022003418080044d0d002002413c6a41013602002002420237022c200241f8a7c6003602282002410136021c200241d4a7c6003602182002200241186a3602382002200241286a10330c030b200241003602000c020b2002413c6a41013602002002420237022c200241d8a7c6003602282002410136021c200241d4a7c6003602182002200241186a3602382002200241286a10330c010b200241246a41013602002002413c6a41023602002002420237022c200241e8a7c6003602282002410136021c2002200241186a3602382002200241106a3602202002200241146a3602182002200241286a10330b024002402002280200450d0020002002290300370200200041086a200241086a2802003602000c010b200041003602000b200241c0006a24000bf80501037f230041f0006b2204240002400240024002400240024020012802084102460d00412e10282201450d01200041013a0000200141266a41002900eca946370000200141206a41002900e6a946370000200141186a41002900dea946370000200141106a41002900d6a946370000200141086a41002900cea946370000200141002900c6a946370000200041086a42ae808080e005370200200041046a20013602000c050b02400240024002400240200128020022052d0000416e6a2201411e4b0d004100210620010e1f03000000000000000000000000000000000000000000000000000008040102030b412010282201450d05200041013a0000200141186a410029008caa46370000200141106a4100290084aa46370000200141086a41002900fca946370000200141002900f4a946370000200041086a42a08080808004370200200041046a20013602000c080b410221060c060b410321060c050b20042005280204220136020c0240024020012003490d004194aac6002105200441e8006a2103200441d0006a2101200441c0006a21020c010b200220014101746a22012d0001450d0441a4aac6002105200441386a2103200441206a2101200441106a21020b20034101360204200141146a410136020020012003360210200142023702042001200536020020032004410c6a360200200220011033200041013a00002000410c6a200241086a280200360200200041046a20022902003702000c050b410121060c030b412e41011037000b412041011037000b20012d000021060b0240200541106a2d00004106470d00200041003a0000200020063a00010c010b0240412910282201450d00200041013a0000200141286a41002d00dcaa463a0000200141206a41002900d4aa46370000200141186a41002900ccaa46370000200141106a41002900c4aa46370000200141086a41002900bcaa46370000200141002900b4aa46370000200041086a42a98080809005370200200041046a20013602000c010b412941011037000b200441f0006a24000b86c30103087f027e017f230041f0006b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00000eac0100e1010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01000b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810282200450dab012003421837025c20032000360258200341d8006a4100411810870520032003280260220041186a3602602000200328025822016a41184196adc60041181088052003200329025c37025c200320013602584193a2c600413b200341d8006a41d0a2c6001038000b02400240200128022820044103746a22052802002204200141206a220628020022024b0d00200421010c010b024002402001411c6a280200220720026b200420026b2208490d0020012802182107200221010c010b200220086a22092002490de0012007410174220a2009200a20094b1b22094100480de0010240024020070d002009102821070c010b200128021820072009102c21070b2007450dad01200120073602182001411c6a2009360200200141206a28020021010b200720016a21090240024020084102490d002009410420042002417f736a22021099051a2007200220016a22016a21090c010b2008450d010b200941043a0000200141016a21010b20062001360200200541013a00060ce0010b0240200141306a2802002204200141346a22052802004f0d002002310001210b200141206a350200210c024020042001412c6a280200470d00200441016a22022004490ddf01200441017422052002200520024b1b220241ffffffff01712002470ddf01200241037422054100480ddf010240024020040d002005102821040c010b200128022820044103742005102c21040b2004450dad01200120043602282001412c6a2002360200200141306a28020021040b200128022820044103746a200b422886200c84370200200141306a2201200128020041016a3602000ce0010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450ddf012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450ddf012000200329023c370204200020013602000ce0010b0240200141306a2802002204200141346a22052802004f0d002002310001210b200141206a350200210c024020042001412c6a280200470d00200441016a22022004490dde01200441017422052002200520024b1b220241ffffffff01712002470dde01200241037422054100480dde010240024020040d002005102821040c010b200128022820044103742005102c21040b2004450dad01200120043602282001412c6a2002360200200141306a28020021040b200128022820044103746a200b422886200c8442808080803084370200200141306a2201200128020041016a3602000cdf010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450dde012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450dde012000200329023c370204200020013602000cdf010b2002310001210b200341d8006a200141186a200141286a22044100108905024020032d00584101470d002000200329025c370200200041086a200341e4006a2802003602000cdf010b0240200141306a2802002202200141346a22052802004f0d00200141206a350200210c024020022001412c6a280200470d00200241016a22052002490ddd01200241017422062005200620054b1b220541ffffffff01712005470ddd01200541037422064100480ddd010240024020020d002006102821020c010b200428020020024103742006102c21020b2002450dad01200120023602282001412c6a2005360200200141306a28020021020b200128022820024103746a200b422886200c8442808080801084370200200141306a2201200128020041016a3602000cde010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450ddd012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450ddd012000200329023c370204200020013602000cde010b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810282200450dac012003421837025c20032000360258200341d8006a4100411810870520032003280260220041186a3602602000200328025822016a41184196adc60041181088052003200329025c37025c2003200136025841e0a2c6004134200341d8006a41d0a2c6001038000b02400240200141286a220228020020044103746a22042d00044101470d002004310005210b200341d8006a200141186a2002108a052003280258450d0120002003290358370200200041086a200341d8006a41086a2802003602000cdf010b411a10282201450dad01200141186a41002f00aca3463b0000200141106a41002900a4a346370000200141086a410029009ca34637000020014100290094a3463700002000429a808080a003370204200020013602000cde010b0240200141306a2802002204200141346a22052802004f0d00200141206a350200210c024020042001412c6a280200470d00200441016a22052004490ddc01200441017422062005200620054b1b220541ffffffff01712005470ddc01200541037422064100480ddc010240024020040d002006102821020c010b200228020020044103742006102c21020b2002450daf01200120023602282001412c6a2005360200200141306a28020021040b200128022820044103746a200b422886200c8442808080802084370200200141306a2201200128020041016a3602000cdd010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450ddc012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450ddc012000200329023c370204200020013602000cdd010b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810282200450dae012003421837025c20032000360258200341d8006a4100411810870520032003280260220041186a3602602000200328025822016a41184196adc60041181088052003200329025c37025c2003200136025841e0a2c6004134200341d8006a41d0a2c6001038000b200141286a220628020020044103746a22042d00052105024020042d00044101470d00200541ff01714104470daf010b0240024020024101460d00200341d8006a200141186a22022006108a052003280258450d0120002003290358370200200041086a200341d8006a41086a2802003602000cde010b20012d003822024104460ddb01200341d8006a200141186a2205200620021089050240024020032d00584101460d000240200141206a2802002204200141246a22072802004f0d00024020042001411c6a280200470d00200441016a22072004490dde01200441017422082007200820074b1b22074100480dde010240024020040d002007102821040c010b200528020020042007102c21040b2004450db401200120043602182001411c6a2007360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cde010b200341ec006a220241013602002003420137025c20034190aec600360258200341013602042003200736020020032003360268200341106a200341d8006a103320032802102204450ddd012003200329021437021420032004360210200241013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382202450ddd01200329023c210b0c010b200328025c2202450ddc01200341e0006a290300210b0b2000200b370204200020023602000cdd010b200541ff01714104460ddb010240200141206a2802002204200141246a22062802004f0d00024020042001411c6a280200470d00200441016a22062004490ddb01200441017422072006200720064b1b22064100480ddb010240024020040d002006102821020c010b200228020020042006102c21020b2002450db201200120023602182001411c6a2006360200200141206a28020021040b200128021820046a20053a0000200141206a2201200128020041016a3602000cdc010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200636020020032003360268200341106a200341d8006a103320032802102202450ddb012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450ddb012000200329023c370204200020013602000cdc010b2003200241046a280200220236024802400240200141306a280200220420024d0d0020042002417f736a22022004490d0141f2adc600411d1050000b200341ec006a220241023602002003411c6a41013602002003420237025c200341b0adc60036025820034101360214200320043602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a1033200328023821042003200329023c37021420032004360210200241013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a10332003280214450dd1012003280210102a0cd1010b200141286a220428020020024103746a22022d00044103460dd10120022d0005220241ff01714104460dd101200341d8006a200141186a220520042002108905024020032d00584101460d000240200141206a2802002204200141246a22062802004f0d00024020042001411c6a280200470d00200441016a22062004490ddb01200441017422072006200720064b1b22064100480ddb010240024020040d002006102821040c010b200528020020042006102c21040b2004450db301200120043602182001411c6a2006360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cd3010b200341ec006a220241013602002003420137025c20034190aec600360258200341013602042003200636020020032003360268200341106a200341d8006a103320032802102204450dd2012003200329021437021420032004360210200241013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a10332003280214450dd1012003280210102a0cd1010b200328025c2202450dd101200341e0006a290300210b0cd2010b200241046a2802002102200341d8006a200141186a2206200141286a220541001089050240024020032d00584101470d00200341e0006a290300210b200328025c22010d010cdb010b200141306a28020021042003200236024802400240200420024d0d0020042002417f736a22022004490d0141f2adc600411d1050000b200341ec006a220141023602002003411c6a41013602002003420237025c200341b0adc60036025820034101360214200320043602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a1033200328023821022003200329023c37021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b200329023c210b200328023822010d010cdb010b200528020020024103746a22022d00044103460dda0120022d0005220241ff01714104460dda01200341d8006a200620052002108905024020032d00584101460d000240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490ddb01200441017422072005200720054b1b22054100480ddb010240024020040d002005102821040c010b200628020020042005102c21040b2004450db401200120043602182001411c6a2005360200200141206a28020021040b200128021820046a20023a0000200141206a2201200128020041016a3602000cdc010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450ddb012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450ddb01200329023c210b0c010b200328025c2201450dda01200341e0006a290300210b0b2000200b370204200020013602000cda010b200241046a280200220228020421062002280200210420032002280208220536024802400240200141306a280200220220054d0d0020022005417f736a22052002490d0141f2adc600411d1050000b200341ec006a220441023602002003411c6a41013602002003420237025c200341b0adc60036025820034101360214200320023602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a1033200328023821022003200329023c37021420032002360210200441013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b2003200329023c370204200320032802383602000ccd010b410421090240200141286a220d280200220720054103746a22052d00044103460d0020052d000521090b200320093a00302006450dc801200941ff0171220a4104460dc701200641027421060340200320042802002205360248200220054d0dca0120022005417f736a220520024f0dce01200720054103746a22052d00044103460dcb0120052d000522084104460dcb01200a2008470dcb01200441046a21042006417c6a22060d000cc9010b0b20012d003822024104460dc501200341d8006a200141186a2205200141286a20021089050240024020032d00584101460d000240200141206a2802002204200141246a22062802004f0d00024020042001411c6a280200470d00200441016a22062004490dd901200441017422072006200720064b1b22064100480dd9010240024020040d002006102821040c010b200528020020042006102c21040b2004450db301200120043602182001411c6a2006360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cc8010b200341ec006a220241013602002003420137025c20034190aec600360258200341013602042003200636020020032003360268200341106a200341d8006a103320032802102204450dc7012003200329021437021420032004360210200241013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382202450dc701200329023c210b0c010b200328025c2202450dc601200341e0006a290300210b0b2000200b370204200020023602000cd8010b200128020021042003200241046a2802002202360254024002400240200441386a28020020024b0d00200341ec006a41013602002003420237025c200341e4abc600360258200341013602342003200341306a3602682003200341d4006a360230200341386a200341d8006a1033200341186a200329023c370300200341013602102003200328023822043602140c010b2003200428023020024102746a2802002202360200024002402004412c6a28020020024b0d0041012105200341ec006a41013602002003420237025c20034188acc6003602582003410136024c2003200341c8006a36026820032003360248200341386a200341d8006a1033200341186a200329023c220b370300200b422088a7210720032802382104200ba721020c010b2003411c6a200428022420024104746a22042d000d22073a0000200341186a2004280208220236020020042802002104410021050b20032005360210200320043602142005450d010b200341186a21010cc3010b02402002450d002004417f6a2104200141286a2105200141186a21060340200341d8006a20062005200420026a2d0000108905024020032d00584101470d00200341e0006a2101200328025c21040cc5010b2002417f6a22020d000b0b200741ff01714104460dd6010240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490dd601200241017422052004200520044b1b22044100480dd6010240024020020d002004102821020c010b200128021820022004102c21020b2002450db101200120023602182001411c6a2004360200200141206a28020021020b200128021820026a20073a0000200141206a2201200128020041016a3602000cd7010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200436020020032003360268200341106a200341d8006a103320032802102202450dd6012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382204450dd601200329023c210b0cc3010b200241046a28020021062001280200210220034100360238024002400240200241146a2802000d00200341d8006a41146a41013602002003420237025c200341c4abc60036025820034101360204200320033602682003200341386a360200200341106a200341d8006a10330c010b200341d8006a200141186a2204200141286a22054100108905024020032d00584101470d00200341e0006a290300210b0cc2010b20012802002207412c6a280200210220032006360238200220064b0d01200341ec006a41013602002003420237025c20034188acc60036025820034101360204200320033602682003200341386a360200200341106a200341d8006a10330b2003290214210b200328021022010dc1010cd6010b200728022420064104746a22062d000d2107024020062802082202450d002006280200417f6a21060340200341d8006a20042005200620026a2d0000108905024020032d00584101470d00200341e0006a290300210b0cc2010b2002417f6a22020d000b0b200741ff01714104460dd5010240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490dd501200241017422062005200620054b1b22054100480dd5010240024020020d002005102821020c010b200428020020022005102c21020b2002450db101200120023602182001411c6a2005360200200141206a28020021020b200128021820026a20073a0000200141206a2201200128020041016a3602000cd6010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450dd5012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450dd501200329023c210b0cc0010b200341d8006a200141186a200141286a410410890520032d00584101470dd401200328025c2201450dd4012000200341e0006a290300370204200020013602000cd5010b200341d8006a200141186a2204200141286a22054100108905200341d8006a21020240024020032d00584101460d00200341d8006a200420054104108905200341d8006a210220032d00584101460d00200341d8006a2004200520032d00592206108905200341d8006a210220032d00584101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490dd501200241017422072005200720054b1b22054100480dd5010240024020020d002005102821020c010b200428020020022005102c21020b2002450db201200120023602182001411c6a2005360200200141206a28020021020b200128021820026a20063a0000200141206a2201200128020041016a3602000cd6010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450dd5012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450dd501200329023c210b0c010b200241046a2802002201450dd401200241086a290200210b0b2000200b370204200020013602000cd4010b200341d8006a200141046a200241046a280200108b050240024020032d00584101460d000240200141206a2802002202200141246a22042802004f0d0020032d00592104024020022001411c6a280200470d00200241016a22052002490dd401200241017422062005200620054b1b22054100480dd4010240024020020d002005102821020c010b200128021820022005102c21020b2002450db201200120023602182001411c6a2005360200200141206a28020021020b200128021820026a20043a0000200141206a2201200128020041016a3602000cd5010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200436020020032003360268200341106a200341d8006a103320032802102202450dd4012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450dd401200329023c210b0c010b200328025c2201450dd301200341e0006a290300210b0b2000200b370204200020013602000cd3010b2003200241046a2802002202360200200341d8006a200141046a2002108b05024020032d00584101470d002003200328025c22013602382003200341e0006a290300220b37023c0cbb010b200320032d005922023a0030200341d8006a200141186a200141286a4104108905024020032d00584101470d00200341c0006a200341e4006a2802003602002003200329025c3703380cba010b200320032d005922013a004820014104460dd101200241ff01712001460dd101200341106a41146a41303602002003411c6a4127360200200341d8006a41146a41033602002003420337025c200341d0a3c600360258200341013602142003200341106a3602682003200341c8006a3602202003200341306a36021820032003360210200341386a200341d8006a10330cb9010b200341d8006a200141046a200241046a280200108b050240024020032d00584101460d00200341d8006a200141186a2205200141286a20032d00592204108905024020032d00584101460d000240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490dd301200241017422072006200720064b1b22064100480dd3010240024020020d002006102821020c010b200528020020022006102c21020b2002450db201200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20043a0000200141206a2201200128020041016a3602000cd4010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200636020020032003360268200341106a200341d8006a103320032802102202450dd3012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450dd301200329023c210b0c020b200328025c2201450dd201200341e0006a290300210b0c010b200328025c2201450dd101200341e0006a290300210b0b2000200b370204200020013602000cd1010b200128020021042003200241046a280200220236023802400240200441206a28020020024d0d000240200141206a2802002205200141246a22062802004f0d00200428021820024101746a2d00002102024020052001411c6a280200470d00200541016a22042005490dd101200541017422062004200620044b1b22044100480dd1010240024020050d002004102821050c010b200128021820052004102c21050b2005450db101200120053602182001411c6a2004360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000cd2010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200636020020032003360268200341106a200341d8006a103320032802102202450dd1012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450dd101200329023c210b0c010b200341ec006a41013602002003420237025c200341a8acc6003602582003410136024c2003200341c8006a3602682003200341386a360248200341106a200341d8006a103320032802102201450dd0012003290214210b0b2000200b370204200020013602000cd0010b2003200241046a28020022023602282001280200210420032002360254024002400240200441206a28020020024b0d00200341ec006a41013602002003420237025c200341a8acc6003602582003410136024c2003200341c8006a3602682003200341d4006a360248200341106a200341d8006a10330c010b200428021820024101746a22022d00010d01200341ec006a41013602002003420237025c200341b8acc60036025820034101360204200320033602682003200341d4006a360200200341106a200341d8006a10330b2003280210210120032003290214220b37023c200320013602380cb6010b200320022d000022023a002f200341d8006a200141186a200141286a4104108905024020032d00584101470d00200341c0006a200341e4006a2802003602002003200329025c3703380cb5010b200320032d005922013a00002001200241ff0171460dce0120014104460dce01200341106a41146a41303602002003411c6a4130360200200341d8006a41146a41033602002003420337025c200341e8a3c600360258200341013602142003200341106a3602682003200336022020032003412f6a3602182003200341286a360210200341386a200341d8006a10330cb4010b200341d8006a2001200241046a28020041044100108d052003280258450dcd0120002003290358370200200041086a200341d8006a41086a2802003602000cce010b200341d8006a2001200241046a28020041084101108d052003280258450dcc0120002003290358370200200041086a200341d8006a41086a2802003602000ccd010b200341d8006a2001200241046a28020041044102108d052003280258450dcb0120002003290358370200200041086a200341d8006a41086a2802003602000ccc010b200341d8006a2001200241046a28020041084103108d052003280258450dca0120002003290358370200200041086a200341d8006a41086a2802003602000ccb010b200341d8006a2001200241046a28020041014100108d052003280258450dc90120002003290358370200200041086a200341d8006a41086a2802003602000cca010b200341d8006a2001200241046a28020041014100108d052003280258450dc80120002003290358370200200041086a200341d8006a41086a2802003602000cc9010b200341d8006a2001200241046a28020041024100108d052003280258450dc70120002003290358370200200041086a200341d8006a41086a2802003602000cc8010b200341d8006a2001200241046a28020041024100108d052003280258450dc60120002003290358370200200041086a200341d8006a41086a2802003602000cc7010b200341d8006a2001200241046a28020041014101108d052003280258450dc50120002003290358370200200041086a200341d8006a41086a2802003602000cc6010b200341d8006a2001200241046a28020041014101108d052003280258450dc40120002003290358370200200041086a200341d8006a41086a2802003602000cc5010b200341d8006a2001200241046a28020041024101108d052003280258450dc30120002003290358370200200041086a200341d8006a41086a2802003602000cc4010b200341d8006a2001200241046a28020041024101108d052003280258450dc20120002003290358370200200041086a200341d8006a41086a2802003602000cc3010b200341d8006a2001200241046a28020041044101108d052003280258450dc10120002003290358370200200041086a200341d8006a41086a2802003602000cc2010b200341d8006a2001200241046a28020041044101108d052003280258450dc00120002003290358370200200041086a200341d8006a41086a2802003602000cc1010b200341d8006a2001200241046a28020041044100108e052003280258450dbf0120002003290358370200200041086a200341d8006a41086a2802003602000cc0010b200341d8006a2001200241046a28020041084101108e052003280258450dbe0120002003290358370200200041086a200341d8006a41086a2802003602000cbf010b200341d8006a2001200241046a28020041044102108e052003280258450dbd0120002003290358370200200041086a200341d8006a41086a2802003602000cbe010b200341d8006a2001200241046a28020041084103108e052003280258450dbc0120002003290358370200200041086a200341d8006a41086a2802003602000cbd010b200341d8006a2001200241046a28020041014100108e052003280258450dbb0120002003290358370200200041086a200341d8006a41086a2802003602000cbc010b200341d8006a2001200241046a28020041024100108e052003280258450dba0120002003290358370200200041086a200341d8006a41086a2802003602000cbb010b200341d8006a2001200241046a28020041014101108e052003280258450db90120002003290358370200200041086a200341d8006a41086a2802003602000cba010b200341d8006a2001200241046a28020041024101108e052003280258450db80120002003290358370200200041086a200341d8006a41086a2802003602000cb9010b200341d8006a2001200241046a28020041044101108e052003280258450db70120002003290358370200200041086a200341d8006a41086a2802003602000cb8010b20012802002102200341003602380240024020022802080d00200341ec006a41013602002003420237025c20034194abc60036025820034101360204200320033602682003200341386a360200200341106a200341d8006a103320032802102202450d002003290214210b0c010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db701200241017422052004200520044b1b22044100480db7010240024020020d002004102821020c010b200128021820022004102c21020b2002450d9801200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb8010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200436020020032003360268200341106a200341d8006a103320032802102202450db7012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382202450db701200329023c210b0b2000200b370204200020023602000cb7010b20012802002102200341003602380240024020022802080d00200341ec006a41013602002003420237025c20034194abc60036025820034101360204200320033602682003200341386a360200200341106a200341d8006a103320032802102202450d002003290214210b0c010b200341d8006a200141186a2204200141286a4100108905024020032d00584101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490db701200241017422062005200620054b1b22054100480db7010240024020020d002005102821020c010b200428020020022005102c21020b2002450d9901200120023602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb8010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102202450db7012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382202450db701200329023c210b0c010b200328025c2202450db601200341e0006a290300210b0b2000200b370204200020023602000cb6010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db401200241017422052004200520044b1b22044100480db4010240024020020d002004102821020c010b200128021820022004102c21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb5010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200436020020032003360268200341106a200341d8006a103320032802102202450db4012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450db4012000200329023c370204200020013602000cb5010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db301200241017422052004200520044b1b22044100480db3010240024020020d002004102821020c010b200128021820022004102c21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000cb4010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200436020020032003360268200341106a200341d8006a103320032802102202450db3012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450db3012000200329023c370204200020013602000cb4010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db201200241017422052004200520044b1b22044100480db2010240024020020d002004102821020c010b200128021820022004102c21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000cb3010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200436020020032003360268200341106a200341d8006a103320032802102202450db2012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450db2012000200329023c370204200020013602000cb3010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db101200241017422052004200520044b1b22044100480db1010240024020020d002004102821020c010b200128021820022004102c21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000cb2010b200341ec006a220141013602002003420137025c20034190aec600360258200341013602042003200436020020032003360268200341106a200341d8006a103320032802102202450db1012003200329021437021420032002360210200141013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382201450db1012000200329023c370204200020013602000cb2010b200341d8006a20014100108f052003280258450db00120002003290358370200200041086a200341d8006a41086a2802003602000cb1010b200341d8006a200141001090052003280258450daf0120002003290358370200200041086a200341d8006a41086a2802003602000cb0010b200341d8006a200141001090052003280258450dae0120002003290358370200200041086a200341d8006a41086a2802003602000caf010b200341d8006a200141001090052003280258450dad0120002003290358370200200041086a200341d8006a41086a2802003602000cae010b200341d8006a200141001090052003280258450dac0120002003290358370200200041086a200341d8006a41086a2802003602000cad010b200341d8006a200141001090052003280258450dab0120002003290358370200200041086a200341d8006a41086a2802003602000cac010b200341d8006a200141001090052003280258450daa0120002003290358370200200041086a200341d8006a41086a2802003602000cab010b200341d8006a200141001090052003280258450da90120002003290358370200200041086a200341d8006a41086a2802003602000caa010b200341d8006a200141001090052003280258450da80120002003290358370200200041086a200341d8006a41086a2802003602000ca9010b200341d8006a200141001090052003280258450da70120002003290358370200200041086a200341d8006a41086a2802003602000ca8010b200341d8006a200141001090052003280258450da60120002003290358370200200041086a200341d8006a41086a2802003602000ca7010b200341d8006a20014101108f052003280258450da50120002003290358370200200041086a200341d8006a41086a2802003602000ca6010b200341d8006a200141011090052003280258450da40120002003290358370200200041086a200341d8006a41086a2802003602000ca5010b200341d8006a200141011090052003280258450da30120002003290358370200200041086a200341d8006a41086a2802003602000ca4010b200341d8006a200141011090052003280258450da20120002003290358370200200041086a200341d8006a41086a2802003602000ca3010b200341d8006a200141011090052003280258450da10120002003290358370200200041086a200341d8006a41086a2802003602000ca2010b200341d8006a200141011090052003280258450da00120002003290358370200200041086a200341d8006a41086a2802003602000ca1010b200341d8006a200141011090052003280258450d9f0120002003290358370200200041086a200341d8006a41086a2802003602000ca0010b200341d8006a200141011090052003280258450d9e0120002003290358370200200041086a200341d8006a41086a2802003602000c9f010b200341d8006a200141011090052003280258450d9d0120002003290358370200200041086a200341d8006a41086a2802003602000c9e010b200341d8006a200141011090052003280258450d9c0120002003290358370200200041086a200341d8006a41086a2802003602000c9d010b200341d8006a200141011090052003280258450d9b0120002003290358370200200041086a200341d8006a41086a2802003602000c9c010b200341d8006a200141021090052003280258450d9a0120002003290358370200200041086a200341d8006a41086a2802003602000c9b010b200341d8006a200141021090052003280258450d990120002003290358370200200041086a200341d8006a41086a2802003602000c9a010b200341d8006a200141021090052003280258450d980120002003290358370200200041086a200341d8006a41086a2802003602000c99010b200341d8006a200141021090052003280258450d970120002003290358370200200041086a200341d8006a41086a2802003602000c98010b200341d8006a200141021090052003280258450d960120002003290358370200200041086a200341d8006a41086a2802003602000c97010b200341d8006a200141021090052003280258450d950120002003290358370200200041086a200341d8006a41086a2802003602000c96010b200341d8006a200141031090052003280258450d940120002003290358370200200041086a200341d8006a41086a2802003602000c95010b200341d8006a200141031090052003280258450d930120002003290358370200200041086a200341d8006a41086a2802003602000c94010b200341d8006a200141031090052003280258450d920120002003290358370200200041086a200341d8006a41086a2802003602000c93010b200341d8006a200141031090052003280258450d910120002003290358370200200041086a200341d8006a41086a2802003602000c92010b200341d8006a200141031090052003280258450d900120002003290358370200200041086a200341d8006a41086a2802003602000c91010b200341d8006a200141031090052003280258450d8f0120002003290358370200200041086a200341d8006a41086a2802003602000c90010b200341d8006a200141001091052003280258450d8e0120002003290358370200200041086a200341d8006a41086a2802003602000c8f010b200341d8006a200141001091052003280258450d8d0120002003290358370200200041086a200341d8006a41086a2802003602000c8e010b200341d8006a200141001091052003280258450d8c0120002003290358370200200041086a200341d8006a41086a2802003602000c8d010b200341d8006a200141001092052003280258450d8b0120002003290358370200200041086a200341d8006a41086a2802003602000c8c010b200341d8006a200141001092052003280258450d8a0120002003290358370200200041086a200341d8006a41086a2802003602000c8b010b200341d8006a200141001092052003280258450d890120002003290358370200200041086a200341d8006a41086a2802003602000c8a010b200341d8006a200141001092052003280258450d880120002003290358370200200041086a200341d8006a41086a2802003602000c89010b200341d8006a200141001092052003280258450d870120002003290358370200200041086a200341d8006a41086a2802003602000c88010b200341d8006a200141001092052003280258450d860120002003290358370200200041086a200341d8006a41086a2802003602000c87010b200341d8006a200141001092052003280258450d850120002003290358370200200041086a200341d8006a41086a2802003602000c86010b200341d8006a200141001092052003280258450d840120002003290358370200200041086a200341d8006a41086a2802003602000c85010b200341d8006a200141001092052003280258450d830120002003290358370200200041086a200341d8006a41086a2802003602000c84010b200341d8006a200141001092052003280258450d820120002003290358370200200041086a200341d8006a41086a2802003602000c83010b200341d8006a200141001092052003280258450d810120002003290358370200200041086a200341d8006a41086a2802003602000c82010b200341d8006a200141001092052003280258450d800120002003290358370200200041086a200341d8006a41086a2802003602000c81010b200341d8006a200141001092052003280258450d7f20002003290358370200200041086a200341d8006a41086a2802003602000c80010b200341d8006a200141001092052003280258450d7e20002003290358370200200041086a200341d8006a41086a2802003602000c7f0b200341d8006a200141001092052003280258450d7d20002003290358370200200041086a200341d8006a41086a2802003602000c7e0b200341d8006a200141011091052003280258450d7c20002003290358370200200041086a200341d8006a41086a2802003602000c7d0b200341d8006a200141011091052003280258450d7b20002003290358370200200041086a200341d8006a41086a2802003602000c7c0b200341d8006a200141011091052003280258450d7a20002003290358370200200041086a200341d8006a41086a2802003602000c7b0b200341d8006a200141011092052003280258450d7920002003290358370200200041086a200341d8006a41086a2802003602000c7a0b200341d8006a200141011092052003280258450d7820002003290358370200200041086a200341d8006a41086a2802003602000c790b200341d8006a200141011092052003280258450d7720002003290358370200200041086a200341d8006a41086a2802003602000c780b200341d8006a200141011092052003280258450d7620002003290358370200200041086a200341d8006a41086a2802003602000c770b200341d8006a200141011092052003280258450d7520002003290358370200200041086a200341d8006a41086a2802003602000c760b200341d8006a200141011092052003280258450d7420002003290358370200200041086a200341d8006a41086a2802003602000c750b200341d8006a200141011092052003280258450d7320002003290358370200200041086a200341d8006a41086a2802003602000c740b200341d8006a200141011092052003280258450d7220002003290358370200200041086a200341d8006a41086a2802003602000c730b200341d8006a200141011092052003280258450d7120002003290358370200200041086a200341d8006a41086a2802003602000c720b200341d8006a200141011092052003280258450d7020002003290358370200200041086a200341d8006a41086a2802003602000c710b200341d8006a200141011092052003280258450d6f20002003290358370200200041086a200341d8006a41086a2802003602000c700b200341d8006a200141011092052003280258450d6e20002003290358370200200041086a200341d8006a41086a2802003602000c6f0b200341d8006a200141011092052003280258450d6d20002003290358370200200041086a200341d8006a41086a2802003602000c6e0b200341d8006a200141011092052003280258450d6c20002003290358370200200041086a200341d8006a41086a2802003602000c6d0b200341d8006a200141011092052003280258450d6b20002003290358370200200041086a200341d8006a41086a2802003602000c6c0b200341d8006a200141021091052003280258450d6a20002003290358370200200041086a200341d8006a41086a2802003602000c6b0b200341d8006a200141021091052003280258450d6920002003290358370200200041086a200341d8006a41086a2802003602000c6a0b200341d8006a200141021091052003280258450d6820002003290358370200200041086a200341d8006a41086a2802003602000c690b200341d8006a200141021091052003280258450d6720002003290358370200200041086a200341d8006a41086a2802003602000c680b200341d8006a200141021091052003280258450d6620002003290358370200200041086a200341d8006a41086a2802003602000c670b200341d8006a200141021091052003280258450d6520002003290358370200200041086a200341d8006a41086a2802003602000c660b200341d8006a200141021091052003280258450d6420002003290358370200200041086a200341d8006a41086a2802003602000c650b200341d8006a200141021092052003280258450d6320002003290358370200200041086a200341d8006a41086a2802003602000c640b200341d8006a200141021092052003280258450d6220002003290358370200200041086a200341d8006a41086a2802003602000c630b200341d8006a200141021092052003280258450d6120002003290358370200200041086a200341d8006a41086a2802003602000c620b200341d8006a200141021092052003280258450d6020002003290358370200200041086a200341d8006a41086a2802003602000c610b200341d8006a200141021092052003280258450d5f20002003290358370200200041086a200341d8006a41086a2802003602000c600b200341d8006a200141021092052003280258450d5e20002003290358370200200041086a200341d8006a41086a2802003602000c5f0b200341d8006a200141021092052003280258450d5d20002003290358370200200041086a200341d8006a41086a2802003602000c5e0b200341d8006a200141031091052003280258450d5c20002003290358370200200041086a200341d8006a41086a2802003602000c5d0b200341d8006a200141031091052003280258450d5b20002003290358370200200041086a200341d8006a41086a2802003602000c5c0b200341d8006a200141031091052003280258450d5a20002003290358370200200041086a200341d8006a41086a2802003602000c5b0b200341d8006a200141031091052003280258450d5920002003290358370200200041086a200341d8006a41086a2802003602000c5a0b200341d8006a200141031091052003280258450d5820002003290358370200200041086a200341d8006a41086a2802003602000c590b200341d8006a200141031091052003280258450d5720002003290358370200200041086a200341d8006a41086a2802003602000c580b200341d8006a200141031091052003280258450d5620002003290358370200200041086a200341d8006a41086a2802003602000c570b200341d8006a200141031092052003280258450d5520002003290358370200200041086a200341d8006a41086a2802003602000c560b200341d8006a200141031092052003280258450d5420002003290358370200200041086a200341d8006a41086a2802003602000c550b200341d8006a200141031092052003280258450d5320002003290358370200200041086a200341d8006a41086a2802003602000c540b200341d8006a200141031092052003280258450d5220002003290358370200200041086a200341d8006a41086a2802003602000c530b200341d8006a200141031092052003280258450d5120002003290358370200200041086a200341d8006a41086a2802003602000c520b200341d8006a200141031092052003280258450d5020002003290358370200200041086a200341d8006a41086a2802003602000c510b200341d8006a200141031092052003280258450d4f20002003290358370200200041086a200341d8006a41086a2802003602000c500b200341d8006a2001410141001093052003280258450d4e20002003290358370200200041086a200341d8006a41086a2802003602000c4f0b200341d8006a2001410241001093052003280258450d4d20002003290358370200200041086a200341d8006a41086a2802003602000c4e0b200341d8006a2001410241001093052003280258450d4c20002003290358370200200041086a200341d8006a41086a2802003602000c4d0b200341d8006a2001410341001093052003280258450d4b20002003290358370200200041086a200341d8006a41086a2802003602000c4c0b200341d8006a2001410341001093052003280258450d4a20002003290358370200200041086a200341d8006a41086a2802003602000c4b0b200341d8006a2001410041011093052003280258450d4920002003290358370200200041086a200341d8006a41086a2802003602000c4a0b200341d8006a2001410041011093052003280258450d4820002003290358370200200041086a200341d8006a41086a2802003602000c490b200341d8006a2001410241011093052003280258450d4720002003290358370200200041086a200341d8006a41086a2802003602000c480b200341d8006a2001410241011093052003280258450d4620002003290358370200200041086a200341d8006a41086a2802003602000c470b200341d8006a2001410341011093052003280258450d4520002003290358370200200041086a200341d8006a41086a2802003602000c460b200341d8006a2001410341011093052003280258450d4420002003290358370200200041086a200341d8006a41086a2802003602000c450b200341d8006a2001410041021093052003280258450d4320002003290358370200200041086a200341d8006a41086a2802003602000c440b200341d8006a2001410041021093052003280258450d4220002003290358370200200041086a200341d8006a41086a2802003602000c430b200341d8006a2001410141021093052003280258450d4120002003290358370200200041086a200341d8006a41086a2802003602000c420b200341d8006a2001410141021093052003280258450d4020002003290358370200200041086a200341d8006a41086a2802003602000c410b200341d8006a2001410341021093052003280258450d3f20002003290358370200200041086a200341d8006a41086a2802003602000c400b200341d8006a2001410041031093052003280258450d3e20002003290358370200200041086a200341d8006a41086a2802003602000c3f0b200341d8006a2001410041031093052003280258450d3d20002003290358370200200041086a200341d8006a41086a2802003602000c3e0b200341d8006a2001410141031093052003280258450d3c20002003290358370200200041086a200341d8006a41086a2802003602000c3d0b200341d8006a2001410141031093052003280258450d3b20002003290358370200200041086a200341d8006a41086a2802003602000c3c0b200341d8006a2001410241031093052003280258450d3a20002003290358370200200041086a200341d8006a41086a2802003602000c3b0b200341d8006a2001410241001093052003280258450d3920002003290358370200200041086a200341d8006a41086a2802003602000c3a0b200341d8006a2001410341011093052003280258450d3820002003290358370200200041086a200341d8006a41086a2802003602000c390b200341d8006a2001410041021093052003280258450d3720002003290358370200200041086a200341d8006a41086a2802003602000c380b200341d8006a20014101410310930520032802580d1b0c360b411841011037000b200941011037000b200541041037000b200541041037000b200641041037000b411841011037000b411a41011037000b200641041037000b411841011037000b200341ec006a41013602002003420237025c200341b0a3c6003602582003413136023c2003200441056a3602382003200341386a360268200341106a200341d8006a1033200041086a200341106a41086a280200360200200020032903103702000c2d0b200741011037000b200641011037000b200641011037000b200541011037000b200641011037000b200441011037000b200541011037000b200541011037000b200541011037000b200641011037000b200441011037000b200441011037000b200541011037000b200441011037000b200441011037000b200441011037000b200441011037000b20002003290358370200200041086a200341d8006a41086a2802003602000c1b0b200329023c210b200328023821010b2001450d182000200b370204200020013602000c190b200329023c210b200328023821010b2001450d162000200b370204200020013602000c170b200328025c2201450d150b2000200b370204200020013602000c150b2004450d132001290200210b0b2000200b370204200020043602000c130b02400240024002400240200141306a2802002202417f6a220420024f0d00200420024b0d00200128022820044103746a22052802002204200141206a220628020022024b0d01200421010c020b411810282200450d022003421837025c20032000360258200341d8006a4100411810870520032003280260220041186a3602602000200328025822016a41184196adc60041181088052003200329025c37025c200320013602584193a2c600413b200341d8006a41d0a2c6001038000b024002402001411c6a280200220720026b200420026b2208490d0020012802182107200221010c010b200220086a22092002490d132007410174220a2009200a20094b1b22094100480d130240024020070d002009102821070c010b200128021820072009102c21070b2007450d03200120073602182001411c6a2009360200200141206a28020021010b200720016a21090240024020084102490d002009410420042002417f736a22021099051a2007200220016a22016a21090c010b2008450d010b200941043a0000200141016a21010b20062001360200200541013a00060c130b411841011037000b200941011037000b200641027421060340200320042802002205360248200220054d0d0220022005417f736a220520024f0d060240200720054103746a22052d00044103460d0020052d00054104470d040b200441046a21042006417c6a22060d000b410421090b200341d8006a200141186a2202200d410010890520032d00584101470d02200341086a200341e4006a2802003602002003200329025c3703000c030b200341ec006a220441023602002003411c6a41013602002003420237025c200341b0adc60036025820034101360214200320023602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a1033200328023821022003200329023c37021420032002360210200441013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b2003200329023c370204200320032802383602000c020b2003411c6a4131360200200341ec006a41023602002003420237025c200341c0a3c6003602582003200541056a360218200341313602142003200341106a3602682003200341306a3602102003200341d8006a10330c010b0240200941ff01714104460d00200341d8006a2002200d200910890502400240024020032d00584101460d000240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490d10200441017422062005200620054b1b22054100480d100240024020040d002005102821020c010b200228020020042005102c21020b2002450d04200120023602182001411c6a2005360200200141206a28020021040b200128021820046a20093a0000200141206a2202200228020041016a3602000c040b200341ec006a220241013602002003420137025c20034190aec600360258200341013602042003200536020020032003360268200341106a200341d8006a103320032802102204450d032003200329021437021420032004360210200241013602002003420137025c200341c4a7c60036025820034128360204200320033602682003200341106a360200200341386a200341d8006a103302402003280214450d002003280210102a0b20032802382202450d03200329023c210b0c010b200328025c2202450d02200341e0006a290300210b0b2003200b370204200320023602000c020b200541011037000b200341003602000b024020032802002202450d0020002003290204370204200020023602000c0d0b0240024002400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810282200450d012003421837025c20032000360258200341d8006a4100411810870520032003280260220041186a3602602000200328025822016a41184196adc60041181088052003200329025c37025c200320013602584193a2c600413b200341d8006a41d0a2c6001038000b02400240200128022820044103746a22052802002204200141206a220628020022024b0d00200421010c010b024002402001411c6a280200220720026b200420026b2208490d0020012802182107200221010c010b200220086a22092002490d0d2007410174220a2009200a20094b1b22094100480d0d0240024020070d002009102821070c010b200128021820072009102c21070b2007450d03200120073602182001411c6a2009360200200141206a28020021010b200720016a21090240024020084102490d002009410420042002417f736a22021099051a2007200220016a22016a21090c010b2008450d010b200941043a0000200141016a21010b20062001360200200541013a00060c0d0b411841011037000b200941011037000b41f2adc600411d1050000b20032802382202450d00200329023c210b0c010b200141306a2802002202417f6a220420024f0d01200420024b0d01200128022820044103746a22052802002204200141206a220628020022024b0d02200421010c030b2000200b370204200020023602000c080b411810282200450d022003421837025c20032000360258200341d8006a4100411810870520032003280260220041186a3602602000200328025822016a41184196adc60041181088052003200329025c37025c200320013602584193a2c600413b200341d8006a41d0a2c6001038000b024002402001411c6a280200220720026b200420026b2208490d0020012802182107200221010c010b200220086a22092002490d042007410174220a2009200a20094b1b22094100480d040240024020070d002009102821070c010b200128021820072009102c21070b2007450d03200120073602182001411c6a2009360200200141206a28020021010b200720016a21090240024020084102490d002009410420042002417f736a22021099051a2007200220016a22016a21090c010b2008450d010b200941043a0000200141016a21010b20062001360200200541013a00060c040b411841011037000b200941011037000b1031000b200341d8006a200141186a2006108a052003280258450d0020002003290358370200200041086a200341d8006a41086a2802003602000c010b200041003602000b200341f0006a24000b6401017f230041206b2202240020024132360204200220003602002001411c6a2802002100200128021821012002411c6a41013602002002420137020c200241b0aec6003602082002200236021820012000200241086a10352101200241206a240020010b810101017f024002400240200041046a280200220320016b20024f0d00200120026a22022001490d02200341017422012002200120024b1b22014100480d020240024020030d002001102821020c010b200028020020032001102c21020b2002450d0120002002360200200041046a20013602000b0f0b200141011037000b1031000bd90101017f230041e0006b22042400200420013602082004200336020c024020012003470d00200020022001109a051a200441e0006a24000f0b200441286a41146a4108360200200441346a4125360200200441106a41146a410336020020044203370214200441c8afc6003602102004412536022c2004200441086a36024020042004410c6a360244200442043703582004420137024c2004419cb0c6003602482004200441286a3602202004200441c8006a3602382004200441c4006a3602302004200441c0006a360228200441106a41d8b0c600103e000bb90601037f230041d0006b22042400200420033a000f0240024002400240024020022802082205417f6a220620054f0d00200620054d0d010b411810282202450d012004421837023420042002360230200441306a4100411810870520042004280238220241186a3602382002200428023022056a41184196adc6004118108805200420042902343702342004200536023041e0a2c6004134200441306a41d0a2c6001038000b200141086a2802002105200228020020064103746a2206280200210202400240024020062d0006450d0020052002460d010b024002400240200520024d0d00200141086a2005417f6a2202360200200128020020026a2d00002205417c6a220241014b0d02024020020e020400040b4118102822020d01411841011037000b412b10282202450d05200041013a0000200241276a41002800fea646360000200241206a41002900f7a646370000200241186a41002900efa646370000200241106a41002900e7a646370000200241086a41002900dfa646370000200241002900d7a646370000200041086a42ab808080b005370200200041046a20023602000c060b200241106a41002900a6ad46370000200241086a410029009ead4637000020024100290096ad4637000020044298808080800337022420042002360220200441c4006a410136020020044201370234200441c4a7c6003602302004412836024c2004200441c8006a3602402004200441206a360248200441106a200441306a103302402004280224450d002004280220102a0b200041013a0000200041046a20042903103702002000410c6a200441106a41086a2802003602000c050b0240200341ff017122024104460d0020052002470d020b200041003a0000200020053a00010c040b20004180083b01000c030b200420053a0048200441c4006a4102360200200441206a410c6a41303602002004420237023420044184a7c600360230200441303602242004200441206a3602402004200441c8006a36022820042004410f6a360220200441106a200441306a10332000410c6a200441186a280200360200200041046a2004290310370200200041013a00000c020b411841011037000b412b41011037000b200441d0006a24000bbd0502047f017e230041d0006b22032400024002400240024002400240200241086a2802002204417f6a220520044f0d00200520044d0d010b411810282202450d01200241106a41002900a6ad46370000200241086a410029009ead4637000020024100290096ad4637000020034298808080800337022420032002360220200341cc006a41013602002003420137023c200341c4a7c600360238200341283602142003200341106a3602482003200341206a3602102000200341386a10332003280224450d042003280220102a0c040b0240024002402002280200220620054103746a2d000522054104460d00200341386a200120022005108905024020032d00384101470d002000200329023c370200200041086a200341c4006a2802003602000c070b200241086a2802002204450d01200228020021060b200241086a2004417f6a2202360200200620024103746a290200220742808080808080c0ff0083428080808080808001520d010b411810282202450d02200241106a41002900a6ad46370000200241086a410029009ead4637000020024100290096ad4637000020034298808080800337022420032002360220200341cc006a41013602002003420137023c200341c4a7c600360238200341283602142003200341106a3602482003200341206a3602102000200341386a10332003280224450d042003280220102a0c040b200141086a28020021022003200737030820022007a7470d02200041003602000c030b411841011037000b411841011037000b200341cc006a41023602002003412c6a41013602002003420237023c200341a4a6c60036023820034101360224200320023602342003200341206a3602482003200341086a3602282003200341346a360220200341106a200341386a1033200041086a200341106a41086a280200360200200020032903103702000b200341d0006a24000bac0301057f230041c0006b2203240020032002360200024002402001280204220420024b0d002001280208417c6a21052001410c6a280200410374210102400340024020010d00200320043602042003412c6a4102360200200341306a410c6a41013602002003420337021c200341f0aec600360218200341013602342003200341306a3602282003200341046a36023820032003360230200341086a200341186a10332000410c6a200341106a280200360200200041046a2003290308370200200041013a00000c040b02402004200541046a2802006a220620044f0d00412010282204450d02200041013a0000200441186a41002900e8ae46370000200441106a41002900e0ae46370000200441086a41002900d8ae46370000200441002900d0ae46370000200041086a42a08080808004370200200041046a20043602000c040b200141786a2101200541086a2105200420024b21072006210420070d0020062104200620024d0d000b20052d00002104200041003a0000200020043a00010c020b412041011037000b200041003a00002000200128020020026a2d00003a00010b200341c0006a24000bbd0201037f230041106b220224000240024020002d00004104470d00200220012802184181a5c60041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b200220012802184184a5c60041082001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a418ca5c600105d210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841f4afc00041012004411c6a28020028020c1100000d010b2001280200220028021841c8a4c60041012000411c6a28020028020c11000021000b200120003a00080b200241106a2400200041ff01714100470bfe0501037f230041d0006b22052400200520023602082005200336020c024002400240417f41012002411f71742002411f4b1b20034b0d00200541386a200141186a2203200141286a410010890520052d00384101470d012000200529023c370200200041086a200541c4006a2802003602000c020b200541cc006a41023602002005411c6a41013602002005420337023c20054180a4c600360238200541013602142005200541106a36024820052005410c6a3602182005200541086a360210200541206a200541386a1033200041086a200541206a41086a280200360200200020052903203702000c010b2001280200210220054100360220024020022802080d00200541cc006a41013602002005420237023c20054194abc600360238200541013602342005200541306a3602482005200541206a360230200541106a200541386a103320052802102202450d0020002005290214370204200020023602000c010b0240024002400240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490d03200241017422072006200720064b1b22064100480d030240024020020d002006102821020c010b200328020020022006102c21020b2002450d02200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20043a0000200141206a2202200228020041016a3602000c030b200541cc006a220241013602002005420137023c20054190aec60036023820054101360234200520063602302005200541306a360248200541106a200541386a103320052802102201450d022005200529021437021420052001360210200241013602002005420137023c200541c4a7c600360238200541283602342005200541306a3602482005200541106a360230200541206a200541386a103302402005280214450d002005280210102a0b20052802202202450d0220002005290224370204200020023602000c030b200641011037000b1031000b200041003602000b200541d0006a24000bae0301017f230041d0006b22052400200520023602082005200336020c024002400240417f41012002411f71742002411f4b1b20034b0d00200128020021022005410036023420022802080d01200541cc006a41013602002005420237023c20054194abc600360238200541013602142005200541106a3602482005200541346a360210200541206a200541386a103320052802202202450d0120002005290224370204200020023602000c020b200541cc006a41023602002005412c6a41013602002005420337023c20054180a4c600360238200541013602242005200541206a36024820052005410c6a3602282005200541086a360220200541106a200541386a1033200041086a200541106a41086a280200360200200020052903103702000c010b200541386a200141186a2202200141286a22032004108905024020052d00384101470d002000200529023c370200200041086a200541c4006a2802003602000c010b200541386a200220034100108905024020052d00384101470d002000200529023c370200200041086a200541c4006a2802003602000c010b200041003602000b200541d0006a24000be50301047f230041c0006b22032400200341286a200141186a2204200141286a20021089050240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d03200241017422062005200620054b1b22054100480d030240024020020d002005102821020c010b200428020020022005102c21020b2002450d02200120023602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c20034190aec60036022820034101360214200320053602102003200341106a360238200341186a200341286a103320032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341c4a7c600360228200341283602142003200341106a3602382003200341186a3602102003200341286a10330240200328021c450d002003280218102a0b20032802002201450d0220002003290204370204200020013602000c030b200541011037000b1031000b200041003602000b200341c0006a24000b9e0401047f230041c0006b22032400200341286a200141186a2204200141286a220520021089050240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b200341286a200420052002108905024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d03200241017422062005200620054b1b22054100480d030240024020020d002005102821020c010b200428020020022005102c21020b2002450d02200120023602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c20034190aec60036022820034101360214200320053602102003200341106a360238200341186a200341286a103320032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341c4a7c600360228200341283602142003200341106a3602382003200341186a3602102003200341286a10330240200328021c450d002003280218102a0b20032802002201450d0220002003290204370204200020013602000c030b200541011037000b1031000b200041003602000b200341c0006a24000be50301057f230041c0006b22032400200341286a200141186a2204200141286a20021089050240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002205200141246a22062802004f0d00024020052001411c6a280200470d00200541016a22062005490d03200541017422072006200720064b1b22064100480d030240024020050d002006102821050c010b200428020020052006102c21050b2005450d02200120053602182001411c6a2006360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c20034190aec60036022820034101360214200320063602102003200341106a360238200341186a200341286a103320032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341c4a7c600360228200341283602142003200341106a3602382003200341186a3602102003200341286a10330240200328021c450d002003280218102a0b20032802002201450d0220002003290204370204200020013602000c030b200641011037000b1031000b200041003602000b200341c0006a24000b9e0401057f230041c0006b22032400200341286a200141186a2204200141286a220520021089050240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b200341286a200420052002108905024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002205200141246a22062802004f0d00024020052001411c6a280200470d00200541016a22062005490d03200541017422072006200720064b1b22064100480d030240024020050d002006102821040c010b200428020020052006102c21040b2004450d02200120043602182001411c6a2006360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c20034190aec60036022820034101360214200320063602102003200341106a360238200341186a200341286a103320032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341c4a7c600360228200341283602142003200341106a3602382003200341186a3602102003200341286a10330240200328021c450d002003280218102a0b20032802002201450d0220002003290204370204200020013602000c030b200641011037000b1031000b200041003602000b200341c0006a24000be50301047f230041c0006b22042400200441286a200141186a2205200141286a20021089050240024020042d00284101470d002000200429022c370200200041086a200441346a2802003602000c010b0240024002400240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490d03200241017422072006200720064b1b22064100480d030240024020020d002006102821020c010b200528020020022006102c21020b2002450d02200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20033a0000200141206a2201200128020041016a3602000c030b2004413c6a220141013602002004420137022c20044190aec60036022820044101360214200420063602102004200441106a360238200441186a200441286a103320042802182202450d022004200429021c37021c20042002360218200141013602002004420137022c200441c4a7c600360228200441283602142004200441106a3602382004200441186a3602102004200441286a10330240200428021c450d002004280218102a0b20042802002201450d0220002004290204370204200020013602000c030b200641011037000b1031000b200041003602000b200441c0006a24000b02000b17000240200041046a280200450d002000280200102a0b0b15002000280200220028020020002802082001105f0b100020012000280200200028020810450bfb0101027f230041106b220224002002200128021841b8aec60041052001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41c0aec600105d1a20022d00082101024020022802042203450d00200141ff0171210041012101024020000d00024020034101470d0020022d000941ff0171450d00200228020022002d00004104710d0041012101200028021841f4afc00041012000411c6a28020028020c1100000d010b2002280200220128021841c8a4c60041012001411c6a28020028020c11000021010b200220013a00080b200241106a2400200141ff01714100470b2c01017f02402002450d00200021030340200320013a0000200341016a21032002417f6a22020d000b0b20000b3601017f02402002450d00200021030340200320012d00003a0000200341016a2103200141016a21012002417f6a22020d000b0b20000b7101017f0240024020012000490d002002450d01200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000c020b0b2002450d002001417f6a21012000417f6a21030340200320026a200120026a2d00003a00002002417f6a22020d000b0b20000b4a01037f4100210302402002450d000240034020002d0000220420012d00002205470d01200141016a2101200041016a21002002417f6a2202450d020c000b0b200420056b21030b20030b5701017e02400240200341c000710d002003450d012001410020036b413f71ad8820022003413f71ad220486842102200120048621010c010b20012003413f71ad862102420021010b20002001370300200020023703080b5701017e02400240200341c000710d002003450d0120012003413f71ad2204882002410020036b413f71ad86842101200220048821020c010b20022003413f71ad882101420021020b20002001370300200020023703080b7501027e200020034220882205200142208822067e200320027e7c200420017e7c200342ffffffff0f832203200142ffffffff0f8322017e2204422088200320067e7c22034220887c200342ffffffff0f83200520017e7c22034220887c37030820002003422086200442ffffffff0f83843703000b3e01017f230041106b2205240020052001200220032004410010a205200529030021012000200541086a29030037030820002001370300200541106a24000b4c01017f230041206b22052400200542003703182005420037031020052001200220032004200541106a10a205200529031021012000200529031837030820002001370300200541206a24000be20502037f067e230041306b2206240002400240024002400240024002400240024002402002500d002003500d012004500d02200479a7200279a76b2207413f4b0d0341ff0020076b2108200741016a21070c080b02402004500d0020050d040c060b024002402005450d0020034200510d0620054200370308200520012003823703000c010b20034200510d050b200120038021010c060b2004500d030240024002402001500d0020047b4201510d01200479a7200279a76b2207413e4b0d0241ff0020076b2108200741016a21070c090b02402005450d0020054200370300200520022004823703080b200220048021010c070b02402005450d002005200137030020052004427f7c2002833703080b200220047a423f838821010c060b2005450d040c020b024020037b4201510d0041bf7f200379a7200279a76b22076b2108200741c1006a21070c060b02402005450d002005420037030820052003427f7c2001833703000b20034201510d06200641206a2001200220037aa7109e05200641286a2903002102200629032021010c060b2005450d020b2005200137030020052002370308420021010c020b00000b420021010b420021020c010b200620012002200841ff0071109d05200641106a20012002200741ff0071109e05200641086a2903002102200641106a41086a2903002109200629030021012006290310210a0240024020070d004200210b4200210c0c010b4200210c4200210d03402009420186200a423f8884220b200b427f8520047c200a4201862002423f8884220a427f85220b20037c200b54ad7c423f87220b2004837d200a200b200383220e54ad7d2109200a200e7d210a420020024201862001423f8884842102200d2001420186842101200b420183220b210d2007417f6a22070d000b0b02402005450d002005200a370300200520093703080b200c20024201862001423f8884842102200b20014201868421010b2000200137030020002002370308200641306a24000b0b9bb1060200418080c0000b80b1061800100011000000187f11001700000009030000050000006361706163697479206f766572666c6f77000000a00010004600000063010000130000003300000004000000040000003400000035000000360000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f72003700000000000000010000003800000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f666d742f6d6f642e72730101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020202020202020202020202020202020202020202020202020202020202030303030303030303030303030303030404040404000000000000000000000000000802100020000000280210001200000037000000000000000100000039000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e646578206973203030303130323033303430353036303730383039313031313132313331343135313631373138313932303231323232333234323532363237323832393330333133323333333433353336333733383339343034313432343334343435343634373438343935303531353235333534353535363537353835393630363136323633363436353636363736383639373037313732373337343735373637373738373938303831383238333834383538363837383838393930393139323933393439353936393739383939000024031000060000002a031000220000006898110018000000170a000005000000696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e677468206c03100016000000820310000d00000068981100180000001d0a000005000000736c69636520696e64657820737461727473206174202062757420656e6473206174206030785b2e2e2e5d00560410000b00000002171000160000008f0310000100000040041000160000000308000009000000e01610000e000000ee16100004000000f2161000100000008f0310000100000040041000160000000708000005000000a01610002b000000cb161000150000007a01000015000000560410000b000000610410002600000087041000080000008f041000060000008f03100001000000400410001600000014080000050000007372632f6c6962636f72652f7374722f6d6f642e72736279746520696e64657820206973206e6f742061206368617220626f756e646172793b20697420697320696e7369646520202862797465732029206f662060000000d604100002000000c0041000160000006204000011000000c00410001600000056040000280000007372632f6c6962636f72652f666d742f6d6f642e72732e2e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000f8030000000000000000000000000000000000000000000000000000000000000000feffffffffbfb6000000000000000000ff070000000000f8ffff0000010000000000000000000000c09f9f3d0000000002000000ffffff0700000000000000000000c0ff01000000000000f80f20801010004a000000d012100000020000d01410003a00000000010203040506070809080a0b0c0d0e0f10111213140215161718191a1b1c1d1e1f2002020202020202020202210202020202020202020202020202222324252602270228020202292a2b022c2d2e2f300202310202023202020202020202023302023402020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023502360237020202020202020238023902020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023a3b3c020202023d02023e3f4041424344454602020247020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202024802020202020202020202024902020202023b020001020202020302020202040205060202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020207020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200010305050606030706080809110a1c0b190c140d120e0d0f0410031212130916011705180219031a071c021d011f1620032b042c022d0b2e01300331023201a702a902aa04ab08fa02fb05fd04fe03ff09ad78798b8da23057588b8c901c1ddd0e0f4b4cfbfc2e2f3f5c5d5fb5e2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d112945495764658d91a9b4babbc5c9dfe4e5f0040d1145496465808184b2bcbebfd5d7f0f183858ba4a6bebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff800d6d71dedf0e0f1f6e6f1c1d5f7d7eaeafbbbcfa16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f747596972f5f262e2fa7afb7bfc7cfd7df9a409798308f1fc0c1ceff4e4f5a5b07080f10272feeef6e6f373d3f42459091feff536775c8c9d0d1d8d9e7feff00205f2282df048244081b04061181ac0e80ab351e1580e003190801042f043404070301070607110a500f1207550802041c0a090308030703020303030c0405030b06010e15053a0311070605100757070207150d500443032d03010411060f0c3a041d255f206d046a2580c80582b0031a0682fd035907150b1709140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a061f414c042d0374083c030f033c0738082b0582ff1118082f112d032010210f808c048297190b158894052f053b07020e180980b030740c80d61a0c0580ff0580b605240c9bc60ad23010848d033709815c1480b80880c73035040a06380846080c06740b1e035a0459098083181c0a16094808808a06aba40c170431a10481da26070c050580a511816d1078282a064c04808d0480be031b030f0d0006010103010402080809020a050b02100111041205131114021502170219041c051d0824016a036b02bc02d102d40cd509d602d702da01e005e102e802ee20f004f906fa020c273b3e4e4f8f9e9e9f060709363d3e56f3d0d104141836375657bd35cecfe01287898e9e040d0e11122931343a4546494a4e4f64655a5cb6b71b1ca8a9d8d909379091a8070a3b3e66698f926f5feeef5a629a9b2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a22253e3fc5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d00c72a3a4cbcc6e6f5e227b0503042d036504012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b018090813709160a088098390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a81261f808128082a808617094e041e0f430e19070a0647092709750b3f412a063b050a0651060105100305808b602048080a80a65e22450b0a060d1339070a362c041080c03c64530c0180a0451b4808531d398107460a1d03474937030e080a0639070a81361980c7320d839b66750b80c48abc842f8fd18247a1b98239072a040260260a460a28051382b05b654b0439071140041c97f80882f3a50d811f3103110408818c89046b050d03090710936080f60a73086e1746809a140c570919808781470385420f1585502b80d52d031a040281703a0501850080d7294c040a04028311444c3d80c23c06010455051b3402810e2c04640c560a0d035d033d391d0d2c040907020e06809a83d60a0d030b05740c59070c140c0438080a0628081e527703310380a60c14040305030d06856a000000601010002000000027000000190000006010100020000000280000002000000060101000200000002a0000001900000060101000200000002b0000001800000060101000200000002c0000002000000000000000000000007372632f6c6962636f72652f756e69636f64652f626f6f6c5f747269652e72730000c0fbef3e00000000000e0000000000000000000000000000f8fffbffffff0700000000000014fe21fe000c00000002000000000000501e2080000c00004006000000000000108639020000002300be2100000c0000fc02000000000000d01e20c0000c0000000400000000000040012080000000000011000000000000c0c13d60000c0000000200000000000090443060000c00000003000000000000581e2080000c00000000845c8000000000000000000000f207807f000000000000000000000000f21f003f000000000000000000030000a002000000000000fe7fdfe0fffeffffff1f40000000000000000000000000e0fd66000000c301001e006420002000000000000000e00000000000001c0000001c0000000c0000000c00000000000000b03f40fe0f200000000000380000000000006000000000020000000000008701040e00008009000000000000407fe51ff89f000000000000ff7f0f0000000000f0170400000000f80f00030000003c3b00000000000040a303000000000000f0cf000000f7fffd211003fffffffffffffffb00100000000000000000ffffffff01000000000000800300000000000000008000000000ffffffff0000000000fc00000000000600000000000000000080f73f000000c0000000000000000000000300440800006000000030000000ffff038000000000c03f000080ff030000000000070000000000c833000000002000000000000000007e660008100000000000100000000000009dc1020000000030400000000000202100000000004000000000ffff0000ffff00000000000000000001000000020003000000000000000000000000000000000000000000000000000004000005000000000000000006000000000000000007000008090a000b0c0d0e0f000010111200001314151600001718191a1b001c0000001d0000000000001e1f202100000000002200230024252600000000270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002829000000000000000000000000000000002a2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000002d2e00002f0000000000000000000000000000000000000000000000000000000000003031320000000000000000000000000000000000000000003300000029000000000000340000000000000000000000000000000000000000000000350036000000000000000000000000000000000000000000000000000037380000383838390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000001000000000000000000c0076ef0000000000087000000006000000000000000f0000000c0ff01000000000002000000000000ff7f0000000000008003000000000078060700000080ef1f000000000000000800030000000000c07f001e000000000000000000000080d34000000080f8070000030000000000005801008000c01f1f0000000000000000ff5c00004000000000000000000000f9a50d000000000000000000000000803cb00100003000000000000000000000f8a70100000000000000000000000028bf00000000e0bc0f0000000000000080ff060000f00c01000000fe0700000000f87980007e0e0000000000fc7f03000000000000000000007fbf0000fcfffffc6d000000000000007eb4bf000000000000000000a3000000000000000000000018000000000000001f000000000000007f0000800000000000000080070000000000000000600000000000000000a0c307f8e70f0000003c00001c00000000000000ffffffffffff7ff8ffffffffff1f2000100000f8feff00007ffffff9db0700000000000000f0000000007f0000000000f00700000000000000000000ffffffffffffffffffffffffffffffffffff000063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c75657372632f6c6962636f72652f6f7074696f6e2e7273626567696e203c3d20656e642028203c3d2029207768656e20736c6963696e672060206973206f7574206f6620626f756e6473206f66206066616c736574727565426f72726f774572726f72426f72726f774d75744572726f7270616e69636b6564206174200000711710000100000072171000030000003897110000000000701710000100000070171000010000003a27272c20000000cb16100015000000a60400000500000098171000150000008d040000050000007372632f6c6962636f72652f726573756c742e72735b5d0a3a0000000c000000040000003b0000003c0000003d0000002c0a2c203300000004000000040000003e0000003f0000004000000020202020207b20207b0a207d7d28280a2c0000003300000004000000040000004100000033000000040000000400000042000000557466384572726f7276616c69645f75705f746f6572726f725f6c656e00000033000000040000000400000043000000370000000000000001000000440000004500000046000000370000000000000001000000440000004500000046000000901810001e0000005074110013000000b903000009000000617373657274696f6e206661696c65643a20696e646578203c3d206c656e0000c81810001d0000005074110013000000e103000009000000617373657274696f6e206661696c65643a20696e646578203c206c656e0000000019100043000000f60a00003000000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962616c6c6f632f7665632e7273000019100043000000020b00002c0000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d312e302e352f7372632f636f6d706163742e72736865616420697320736574207768656e20666972737420656c656d656e7420697320696e7365727465640a090909090909616e6420756e736574207768656e206c61737420656c656d656e742069732072656d6f7665643b0a0909090909096966206865616420697320536f6d65207468656e20697420706f696e747320746f206578697374696e67206b65793b2071656470726576696f75732f6e657874206f6e6c7920636f6e7461696e206578697374696e6720656e74697265733b0a090909090909776520656e756d6572617465207573696e67206e6578743b20656e747279206578697374733b207165646f766572666c6f77206d756c7469706c79696e6720676173206c696d69742062792070726963650000003700000000000000010000004700000048000000490000004a0000004b0000004c0000000c1b1000330000003f1b10004b000000f600000005000000636f6e74726163742073756273797374656d20726573756c74696e6720696e20706f73697469766520696d62616c616e6365212f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f6163636f756e745f64622e72734f6666656e636573205265706f7274730000c01b100019000000e01b100048000000bb0100002d000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f6f70732f61726974682e7273616c726561647920626f72726f776564616c7265616479206d757461626c7920626f72726f7765643700000000000000010000004d0000003700000000000000010000004e000000387d110028000000881c10004300000055000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f6f6666656e6365732f7372632f6c69622e727300881c1000430000005500000001000000551d10003600000054191000630000005e01000005000000000000000000000000000000181d10003d00000054191000630000006501000005000000736869667465642073756666696369656e74206269747320726967687420746f206c656164206f6e6c79206c656164696e67207a65726f733b2071656450726576696f7573206d617463682061726d206d61746368657320616e7974696e67206c657373207468616e20325e33303b2071656400551d10003600000054191000630000008a0100000500000000000000000000000000000000000000000000005419100063000000910100000500000053657373696f6e20486973746f726963616c53657373696f6e734c696e6b616765206973207570646174656420696e206361736520656e7472792069732072656d6f7665643b0a0909090909697420616c7761797320706f696e747320746f206578697374696e67206b6579733b20716564000000000000441f10000700000001010000000000004b1f10000d00000000000000581f10003400000000000000000000000000000000000000389711008c1f100000000000000000009c1f100001000000000000000000000000000000a41f10001600000002010100000000006f8c11000400000000000000738c11000e00000000000000ba1f1000120000000000000038971100cc1f10000000000000000000dc1f100001000000000000000100000000000000e41f10001200000001010000000000006f8c11000400000000000000e7ea1000070000000000000000000000000000000000000038971100f81f10000000000000000000082010000600000000000000010000005265706f7274735265706f727449644f663c543e4f6666656e636544657461696c733c543a3a4163636f756e7449642c20543a3a4964656e74696669636174696f6e5475706c653e3700000000000000010000004f000000a121100052000000436f6e63757272656e745265706f727473496e6465785665633c5265706f727449644f663c543e3e37000000000000000100000050000000572110004a0000005265706f72747342794b696e64496e646578000037000000000000000100000051000000382010004400000038971100000000007c2010002f0000003897110000000000ab20100052000000fd2010005a00000020456e756d65726174657320616c6c207265706f727473206f662061206b696e6420616c6f6e672077697468207468652074696d6520746865792068617070656e65642e20416c6c207265706f7274732061726520736f72746564206279207468652074696d65206f66206f6666656e63652e204e6f74652074686174207468652061637475616c2074797065206f662074686973206d617070696e6720697320605665633c75383e602c207468697320697320626563617573652076616c756573206f6620646966666572656e7420747970657320617265206e6f7420737570706f7274656420617420746865206d6f6d656e7420736f2077652061726520646f696e6720746865206d616e75616c2073657269616c697a6174696f6e2e204120766563746f72206f66207265706f727473206f66207468652073616d65206b696e6420746861742068617070656e6564206174207468652073616d652074696d6520736c6f742e20546865207072696d61727920737472756374757265207468617420686f6c647320616c6c206f6666656e6365207265636f726473206b65796564206279207265706f7274206964656e746966696572732e72656163686564206d6178696d756d2064657074682c2063616e6e6f7420696e7374616e7469617465520000001800000004000000530000005400000055000000560000005700000058000000696e73756666696369656e742072656d61696e696e672062616c616e6365416c69766520636f6e7472616374206f7220746f6d6273746f6e6520616c7265616479206578697374736e6f7420656e6f7567682067617320746f20706179206261736520696e7374616e7469617465206665656e6f7420656e6f7567682067617320746f20706179207472616e736665722066656572656163686564206d6178696d756d2064657074682c2063616e6e6f74206d616b6520612063616c6c6e6f7420656e6f7567682067617320746f2070617920626173652063616c6c20666565636f6e747261637420686173206265656e2065766963746564636f6e74726163742063616e6e6f742062652064657374726f79656420647572696e672072656375727369766520657865637574696f6e61206e657374656420657865637574696f6e20636f6e74657874206d7573742068617665206120706172656e743b20716564696d2d6f6e6c696e653a6f66666c696e4f6666656e63657320436f6e63757272656e745265706f727473496e6465780000005900000008000000040000005a0000007375627374726174652d6e6f64650000df6acb689907609b0200000037e397fc7c91f5e40100000040fe3ad401f8959a03000000d2bc9897eed08f1501000000f78b278be53f454c01000000ed99c5acb25eedf502000000cbca25e39f14238701000000687ad44ad37f03c201000000bc9d89904f5b923f0100000068b66ba122c93fa701000000ab3c0572291feb8b010000006772616e62616265696d6f6e0000000040787d010065cd1d00e1f505d85aae1ec0542205b0508f1f38e4750488467020d853e903603c5121d0bf760338323222a8591903402013236039cd02480ef423a82a8f0268f8d42470955c02b8dab525c05a3302d8c4962648bd1102e0b27727a855f601e8a05828e8fedf0180773929c0cacd01586d1a2af8f1be019053fb2a50d8b201d00edc2be0fca80138edbc2c48f2a001e06d9d2d80669a01c80d7e2e500f9501c0575e2f08b6900140323f30e0278d0148202031b0418a0108a3ff3120e8870120bedf32f0fb85013856c03398698401f0fda03478218301b8d87f35d8178201d8c26036183d8101b8223e37508d800188d21c38c8fc7f0168b5f93898877f01a829d139d8297f0120d6ab3ab8db7e0168ae803b389d7e0100ca9a3b68957e0100000000d3bc100006000000000000005b000000000000000000000000000000000000000000000000000000000000005c0000000000000000000000000000005d0000000000000000000000000000005e0000000000000000000000000000003fa7100004000000000000005f000000000000000000000000000000000000000000000000000000000000005e0000000000000000000000020000000000000000000000000000000000000060000000000000000000000000000000e7df10000900000000000000610000000000000000000000000000000000000000000000000000000000000062000000000000000000000002000000000000000000000000000000000000006300000000000000000000000000000095a410000a00000000000000640000000000000000000000000000000000000000000000000000000000000065000000000000000000000002000000000000000000000000000000000000005e00000000000000000000000000000045db1000070000000000000066000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000670000000000000000000000000000005e000000000000000000000000000000b239100008000000000000006800000000000000000000000000000000000000000000000000000000000000690000000000000000000000000000006a0000000000000000000000000000006b000000000000000000000000000000d92d110007000000000000006c000000000000000000000000000000000000000000000000000000000000006d0000000000000000000000000000006e0000000000000000000000000000006f000000000000000000000000000000158b1000070000000000000070000000000000000000000000000000000000000000000000000000000000007100000000000000000000000000000072000000000000000000000000000000730000000000000000000000000000007955110009000000000000007400000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000007600000000000000000000000000000077000000000000000000000000000000fe65100007000000000000007800000000000000000000000000000000000000000000000000000000000000790000000000000000000000000000007a0000000000000000000000000000005e000000000000000000000000000000382d100012000000000000007b00000000000000000000000000000000000000000000000000000000000000790000000000000000000000000000007a0000000000000000000000000000005e0000000000000000000000000000004a2d100009000000000000007c000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000000007e0000000000000000000000000000007f000000000000000000000000000000532d10001300000000000000800000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000820000000000000000000000000000005e000000000000000000000000000000662d10000f000000020000000000000000000000000000000000000000000000000000000000000000000000830000000000000000000000020000000000000000000000000000000000000084000000000000000000000000000000752d10000700000000000000850000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000870000000000000000000000000000005e0000000000000000000000000000000596100008000000000000008800000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000008a0000000000000000000000000000008b0000000000000000000000000000007c2d100009000000000000008c000000000000000000000000000000000000000000000000000000000000008d0000000000000000000000000000008e0000000000000000000000000000008f000000000000000000000000000000161311000400000000000000900000000000000000000000000000000000000000000000000000000000000091000000000000000000000000000000920000000000000000000000000000005e000000000000000000000000000000314610000800000000000000930000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000950000000000000000000000000000005e000000000000000000000000000000852d1000120000000200000000000000000000000000000000000000000000000000000000000000000000005e000000000000000000000002000000000000000000000000000000000000005e000000000000000000000000000000972d1000080000000000000096000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000970000000000000000000000000000005e0000000000000000000000546563686e6963616c436f6d6d6974746565456c656374696f6e73546563686e6963616c4d656d6265727368697046696e616c697479547261636b65724772616e647061436f6e747261637473417574686f72697479446973636f766572794f6666656e6365735365656420697320616e207574663820737472696e67000000e02d1000480000009b0a00000a000000e02d100048000000a10a00000e00000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000ac2e10000a00000000000000e0151100020000000000000000000000b82e1000010000000000000000000000c02e10000d00000000000000a8431100010000000000000000000000d02e100001000000000000000000000000ea10000800000000000000d82e1000040000000000000000000000f82e100001000000000000004e65774163636f756e740000432f10001b0000005265617065644163636f756e740000002c2f100017000000d043110009000000d04311000900000011441100070000001144110007000000002f10002c000000205472616e7366657220737563636565646564202866726f6d2c20746f2c2076616c75652c2066656573292e20416e206163636f756e7420776173207265617065642e2041206e6577206163636f756e742077617320637265617465642e76657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c75656163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c62656e6566696369617279206163636f756e74206d757374207072652d6578697374746f6f2066657720667265652066756e647320696e206163636f756e747061796d656e7420776f756c64206b696c6c206163636f756e740000000000003c3010001100000000000000503010000100000000000000000000005830100001000000000000004865617274626561745265636569766564000000903010000b00000060301000300000002041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f72697479496460417574686f726974794964496d4f6e6c696e6520476f73736970417442616c616e63657320546f74616c49737375616e6365496d4f6e6c696e65204b65797342616c616e636573204672656542616c616e636542616c616e63657320526573657276656442616c616e636542616c616e636573204c6f636b7342616c616e6365732056657374696e6700000000000000a03110000800000000000000a8311000020000000000000000000000d8311000170000000000000000000000903210000b000000000000009c321000030000000000000000000000e43210000d00000000000000000000004c3310000e000000000000005c331000030000000000000000000000a433100002000000000000007472616e736665720000000046f1100004000000000000004b22110023000000000000005f55110005000000000000001934100013000000ed35100036000000389711000000000023361000420000006536100048000000ad36100045000000f23610002d00000038971100000000001f371000460000003897110000000000c54d11000b000000653710004c000000b137100033000000e43710005a00000038971100000000003e3810001300000038971100000000005138100054000000a53810004b000000f03810003500000025391000370000005c391000560000003897110000000000d84d11000c0000007365745f62616c616e636500000000005712110003000000000000004b2211002300000000000000d93510000800000000000000193410001300000000000000e13510000c0000000000000019341000130000002c34100025000000389711000000000051341000480000009934100042000000db34100046000000213510003a00000038971100000000005b3510002d0000003897110000000000c54d11000b0000008835100020000000a835100031000000d84d11000c000000666f7263655f7472616e736665720000000000001334100006000000000000004b221100230000000000000046f1100004000000000000004b22110023000000000000005f55110005000000000000001934100013000000b433100054000000083410000b0000002045786163746c7920617320607472616e73666572602c2065786365707420746865206f726967696e206d75737420626520726f6f7420616e642074686520736f75726365206163636f756e74206d6179206265207370656369666965642e736f75726365436f6d706163743c543a3a42616c616e63653e20536574207468652062616c616e636573206f66206120676976656e206163636f756e742e20546869732077696c6c20616c74657220604672656542616c616e63656020616e642060526573657276656442616c616e63656020696e2073746f726167652e2069742077696c6c20616c736f2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d202860546f74616c49737375616e636560292e20496620746865206e65772066726565206f722072657365727665642062616c616e63652069732062656c6f7720746865206578697374656e7469616c206465706f7369742c2069742077696c6c20726573657420746865206163636f756e74206e6f6e636520286073797374656d3a3a4163636f756e744e6f6e636560292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e202d20496e646570656e64656e74206f662074686520617267756d656e74732e202d20436f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e64207772697465732e6e65775f667265656e65775f7265736572766564205472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e20607472616e73666572602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e2049742077696c6c2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d2062792074686520605472616e73666572466565602e204966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74206f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e202d20446570656e64656e74206f6e20617267756d656e747320627574206e6f7420637269746963616c2c20676976656e2070726f70657220696d706c656d656e746174696f6e7320666f72202020696e70757420636f6e6669672074797065732e205365652072656c617465642066756e6374696f6e732062656c6f772e202d20497420636f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e642077726974657320696e7465726e616c6c7920616e64206e6f20636f6d706c657820636f6d7075746174696f6e2e2052656c617465642066756e6374696f6e733a2020202d2060656e737572655f63616e5f77697468647261776020697320616c776179732063616c6c656420696e7465726e616c6c792062757420686173206120626f756e64656420636f6d706c65786974792e2020202d205472616e7366657272696e672062616c616e63657320746f206163636f756e7473207468617420646964206e6f74206578697374206265666f72652077696c6c20636175736520202020202060543a3a4f6e4e65774163636f756e743a3a6f6e5f6e65775f6163636f756e746020746f2062652063616c6c65642e2020202d2052656d6f76696e6720656e6f7567682066756e64732066726f6d20616e206163636f756e742077696c6c2074726967676572202020202060543a3a4475737452656d6f76616c3a3a6f6e5f756e62616c616e6365646020616e642060543a3a4f6e4672656542616c616e63655a65726f3a3a6f6e5f667265655f62616c616e63655f7a65726f602e42616c616e636573000000000000743b10000d0000000000000000000000813b10000a0000000000000000000000000000000000000000000000000000000000000038971100543c100000000000000000008c3b100001000000000000000100000000000000943b10000700000001010000000000000b4e11000c000000000000009b3b10002b0000000000000000000000000000000000000038971100c83b10000000000000000000d83b100001000000000000000000000000000000e03b10000b00000001010000000000000b4e11000c00000000000000813b10000a0000000000000000000000000000000000000038971100543c10000000000000000000ec3b10000b000000000000000100000000000000443c10000f00000001010000000000000b4e11000c00000000000000813b10000a0000000000000000000000000000000000000038971100543c10000000000000000000643c10000b000000000000000100000000000000bc3c10000500000001010000000000000b4e11000c00000000000000c13c10002c0000000000000000000000000000000000000038971100f03c10000000000000000000003d1000010000000000000001000000546f74616c49737375616e6365543a3a42616c616e636500314210002600000056657374696e6756657374696e675363686564756c653c543a3a42616c616e63652c20543a3a426c6f636b4e756d6265723e00003700000000000000010000004f000000fb411000360000004672656542616c616e636500813f1000270000003897110000000000a83f100050000000f83f10005d0000005540100055000000aa4010004f000000f9401000510000004a4110001500000038971100000000005f41100057000000b641100045000000526573657276656442616c616e63650037000000000000000100000098000000363d10005d000000933d1000270000003897110000000000ba3d10005b000000153e10004900000038971100000000005e3e10005d000000bb3e10002d0000003897110000000000e83e1000530000003b3f1000460000004c6f636b735665633c42616c616e63654c6f636b3c543a3a42616c616e63652c20543a3a426c6f636b4e756d6265723e3e00000037000000000000000100000050000000083d10002e00000020416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e2054686520616d6f756e74206f66207468652062616c616e6365206f66206120676976656e206163636f756e7420746861742069732065787465726e616c6c792072657365727665643b20746869732063616e207374696c6c2067657420736c61736865642c20627574206765747320736c6173686564206c617374206f6620616c6c2e20546869732062616c616e63652069732061202772657365727665272062616c616e63652074686174206f746865722073756273797374656d732075736520696e206f7264657220746f2073657420617369646520746f6b656e73207468617420617265207374696c6c20276f776e65642720627920746865206163636f756e7420686f6c6465722c20627574207768696368206172652073757370656e6461626c652e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e2074686973202772657365727665206163636f756e74272069732064656c657465643a207370656369666963616c6c792c2060526573657276656442616c616e6365602e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c6574656420696620604672656542616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e2920546865202766726565272062616c616e6365206f66206120676976656e206163636f756e742e205468697320697320746865206f6e6c792062616c616e63652074686174206d61747465727320696e207465726d73206f66206d6f7374206f7065726174696f6e73206f6e20746f6b656e732e20497420616c6f6e65206973207573656420746f2064657465726d696e65207468652062616c616e6365207768656e20696e2074686520636f6e747261637420657865637574696f6e20656e7669726f6e6d656e742e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e20746865202763757272656e74206163636f756e74272069732064656c657465643a207370656369666963616c6c7920604672656542616c616e6365602e20467572746865722c2074686520604f6e4672656542616c616e63655a65726f602063616c6c6261636b20697320696e766f6b65642c20676976696e672061206368616e636520746f2065787465726e616c206d6f64756c657320746f20636c65616e2075702064617461206173736f6369617465642077697468207468652064656c65746564206163636f756e742e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c657465642069662060526573657276656442616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e20496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e2054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e0000000000704310001200000000000000813b10000a000000000000003897110084431000000000000000000094431000010000000000000000000000000011000b00000000000000813b10000a00000000000000389711009c43100000000000000000000c001100010000000000000000000000140011000b00000000000000813b10000a00000000000000389711009c431000000000000000000020001100010000000000000000000000280011001200000000000000813b10000a00000000000000389711009c43100000000000000000003c001100010000000000000000000000440011001200000000000000813b10000a0000000000000038971100ac43100000000000000000006800110001000000000000004578697374656e7469616c4465706f736974000037000000000000000100000099000000bc431000350000003700000000000000010000009a0000003700000000000000010000009b00000020546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e776520676f74207468652076616c696461746f725f69642066726f6d2063757272656e745f76616c696461746f72733b0a09090909090963757272656e745f76616c696461746f727320697320736574206f662063757272656e746c7920616374696e672076616c696461746f72733b0a090909090909746865206d617070696e67206265747765656e207468652076616c696461746f7220696420616e64206974732066756c6c206964656e74696669636174696f6e2073686f756c642062652076616c69643b0a09090909090974687573206046756c6c4964656e74696669636174696f6e4f663a3a636f6e76657274602063616e27742072657475726e20604e6f6e65603b0a09090909090971656473726d6c2f696d2d6f6e6c696e652d776f726b65722d7374617475730030451000480000009b0a00000a0000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000a44510000900000000000000b045100002000000000000000000000038971100000000000000000068656172746265617400000000000000a44510000900000000000000e04510001900000000000000f94510000900000000000000024610002f0000004865617274626561743c543a3a426c6f636b4e756d6265723e7369676e61747572653c543a3a417574686f7269747949642061732052756e74696d654170705075626c69633e3a3a5369676e6174757265496d4f6e6c696e650000000000000044471000080000000000000000000000925111000e00000000000000000000000000000000000000000000000000000000000000389711004c47100000000000000000005c4710000100000000000000010000000000000064471000040000000000000000000000684710001300000000000000000000000000000000000000000000000000000000000000389711007c47100000000000000000008c47100001000000000000000100000000000000944710001200000002010100000000009f8d11000c00000000000000a64710000900000000000000e7ea1000070000000000000038971100b04710000000000000000000c0471000020000000000000001000000476f7373697041743700000000000000010000009c00000061481000280000004b6579735665633c543a3a417574686f7269747949643e00370000000000000001000000500000002d4810003400000052656365697665644865617274626561747341757468496e6465780037000000000000000100000051000000d04710003a0000000a4810002300000020466f7220656163682073657373696f6e20696e646578207765206b6565702061206d617070696e67206f662060417574686f7269747949646020746f20606f6666636861696e3a3a4f70617175654e6574776f726b5374617465602e205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e2054686520626c6f636b206e756d626572207768656e2077652073686f756c6420676f737369702e6e6f7420656e6f75676820667265652066756e64730000387d110028000000b84810004300000096010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f62616c616e6365732f7372632f6c69622e72734f75746461746564206865617274626561742072656365697665642e496e76616c696420686561727462656174207369676e61747572652e4475706c696361746564206865617274626561742e4e6f6e206578697374656e74207075626c6963206b65792eb8481000430000009601000001000000676f74206f766572666c6f7720616674657220616464696e6720612066656520746f2076616c756562616c616e636520746f6f206c6f7720746f2073656e642076616c756564657374696e6174696f6e2062616c616e636520746f6f206869676820746f20726563656976652076616c756576616c756520746f6f206c6f7720746f20637265617465206163636f756e7454696d657374616d702055706461746554696d657374616d7020526563656e7448696e74730000404a100031000000714a10004b0000007d0000000400000046696e616c2068696e74206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f66696e616c6974792d747261636b65722f7372632f6c69622e7273d44a100023000000714a10004b0000007e0000000400000046696e616c697a6564206865696768742061626f766520626c6f636b206e756d62657200104b100019000000304b100048000000bb0100002d000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f6f70732f61726974682e7273576974686472617720686173206265656e20636865636b65642061626f76653b0a090909647565735f6c696d69746564203c2072656e745f627564676574203c2062616c616e6365202d2073756273697374656e6365203c2062616c616e6365202d206578697374656e7469616c5f6465706f7369743b0a09090971656400005900000008000000040000009d00000054696d657374616d70204f72646572656448696e747354696d657374616d70204d656469616e616c77617973206174206c65617374206f6e6520726563656e742073616d706c653b20716564726563656e7420616e64206f72646572656420636f6e7461696e207468652073616d65206974656d733b2071656400003300000004000000040000009e000000084d100043000000714a10004b000000b600000004000000c04c1000480000009b0a00000a000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e72737072756e696e672064696374617465642062792077696e646f775f73697a6520776869636820697320616c776179732073617475726174656420617420313b207165640000000000784d10000a00000000000000844d10000100000000000000000000009c4d1000020000000000000066696e616c5f68696e74000000000000f26510000400000000000000de4e110017000000ac4d10003d000000e94d10001b0000002048696e7420746861742074686520617574686f72206f66207468697320626c6f636b207468696e6b732074686520626573742066696e616c697a656420626c6f636b2069732074686520676976656e206e756d6265722e00000000744e10000a00000000000000925111000e0000000000000038971100804e10000000000000000000904e1000010000000000000000000000984e10000d00000000000000925111000e0000000000000038971100a84e10000000000000000000b84e1000010000000000000057696e646f7753697a6500003700000000000000010000009f000000074f1000460000005265706f72744c6174656e6379000000370000000000000001000000a0000000c04e100047000000205468652064656c617920616674657220776869636820706f696e74207468696e6773206265636f6d6520737573706963696f75732e2044656661756c7420697320313030302e20546865206e756d626572206f6620726563656e742073616d706c657320746f206b6565702066726f6d207468697320636861696e2e2044656661756c74206973203130312e00000000000000005010000b000000000000008c4311000200000000000000000000000c501000010000000000000000000000145010001000000000000000a8431100010000000000000000000000245010000100000000000000000000002c5010000c0000000000000068ea100001000000000000000000000038501000010000000000000000000000405010000e0000000000000050501000020000000000000000000000605010000100000000000000566f74657252656170656400fe50100015000000426164526561706572536c6173686564ef5010000f00000054616c6c7953746172746564ba5010003500000054616c6c7946696e616c697a65640000184411000e000000184411000e000000685010005200000020412074616c6c792028666f7220617070726f76616c20766f746573206f662073656174287329292068617320656e646564202877697468206f6e65206f72206d6f7265206e6577206d656d62657273292e20412074616c6c792028666f7220617070726f76616c20766f746573206f662073656174287329292068617320737461727465642e20736c6173686564207265617065722072656170656420766f7465722c20726561706572436f756e63696c205265676973746572496e666f4f66436f756e63696c204d656d62657273436f756e63696c204e65787446696e616c697a6540521000480000009b0a00000a000000436f756e63696c205465726d4475726174696f6e436f756e63696c2050726573656e746174696f6e4475726174696f6e436f756e63696c204c6561646572626f617264004052100048000000a10a00000e000000436f756e63696c2043616e64696461746573436f756e63696c20566f746572496e666f4f6647757275206d656469746174696f6e66696e616c697a652063616e206f6e6c792062652063616c6c656420616674657220612074616c6c7920697320737461727465642e436f756e63696c20417070726f76616c734f66436f756e63696c20566f746572730000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000405410000d0000000000000050541000040000000000000000000000b05410001800000000000000000000007055100013000000000000005054100004000000000000000000000084551000060000000000000000000000b45510001300000000000000c8551000040000000000000000000000285610000c0000000000000000000000885610000d0000000000000098561000010000000000000000000000b05610000a000000000000000000000000571000100000000000000010571000010000000000000000000000285710000d0000000000000000000000905710000e00000000000000a0571000030000000000000000000000e8571000090000000000000000000000305810001100000000000000445810000100000000000000000000005c581000030000000000000000000000cce310000d00000000000000745810000100000000000000000000008c581000040000000000000000000000ac5810001900000000000000c8581000010000000000000000000000e0581000020000000000000000000000f05810001100000000000000c85810000100000000000000000000000459100002000000000000007365745f617070726f76616c7300000000000000e46510000500000000000000e96510000900000000000000e4cd10000500000000000000ac5c10001200000000000000f26510000400000000000000f665100008000000000000005f55110005000000000000007a6511000c0000009161100058000000e9611000100000003897110000000000f9611000530000004c6210003000000038971100000000007c62100035000000b162100055000000066310002a00000030631000530000008363100057000000da631000510000002b6410003b0000006664100057000000bd641000370000003897110000000000f46410005400000048651000340000003897110000000000c54d11000b000000d04d1100080000007c65100027000000a365100041000000d84d11000c00000070726f78795f7365745f617070726f76616c7300e060100059000000396110001c0000003897110000000000c54d11000b000000556110003c000000d84d11000c000000726561705f696e6163746976655f766f7465720000000000b76010000e00000000000000fa4e11000c000000000000005712110003000000000000004b2211002300000000000000c56010000900000000000000fa4e11000c00000000000000ce6010001200000000000000ac5c100012000000565f100058000000ae5f100056000000046010002e00000038971100000000003260100045000000389711000000000077601000400000003897110000000000c54d11000b000000d04d1100080000002f5f100027000000d84d11000c000000726574726163745f766f74657200000000000000e4cd10000500000000000000fa4e11000c000000535e10004b00000038971100000000009e5e1000420000003897110000000000e05e10004f0000003897110000000000c54d11000b000000d04d1100080000002f5f100027000000d84d11000c0000007375626d69745f63616e646964616379000000004f5e10000400000000000000fa4e11000c000000be5c10001e0000003897110000000000dc5c1000440000003897110000000000205d100048000000685d100051000000b95d10004c000000055e10001e0000003897110000000000c54d11000b000000235e1000180000003b5e100014000000d84d11000c00000070726573656e745f77696e6e65720000000000009e5c100009000000000000004b2211002300000000000000a75c10000500000000000000645511001500000000000000e4cd10000500000000000000ac5c1000120000007b5b100058000000d35b1000580000002b5c100057000000825c1000070000003897110000000000c54d11000b000000895c100015000000b712110011000000d84d11000c0000007365745f646573697265645f736561747300000000000000d65910000500000000000000fa4e11000c000000bb5a100059000000145b100052000000665b100015000000000000005712110003000000000000004b22110023000000db591000480000003897110000000000235a1000480000006b5a1000500000007365745f70726573656e746174696f6e5f6475726174696f6e00000000000000d65910000500000000000000de4e110017000000805910005600000068591000180000007365745f7465726d5f6475726174696f6e0000001459100054000000685910001800000020536574207468652070726573656e746174696f6e206475726174696f6e2e2049662074686572652069732063757272656e74206120766f7465206265696e672070726573656e74656420666f722c2077696c6c20696e766f6b65206066696e616c697a655f766f7465602e20536574207468652070726573656e746174696f6e206475726174696f6e2e2049662074686572652069732063757272656e746c79206120766f7465206265696e672070726573656e74656420666f722c2077696c6c636f756e742052656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c792e204e6f74653a20412074616c6c792073686f756c642068617070656e20696e7374616e746c7920286966206e6f7420616c726561647920696e20612070726573656e746174696f6e20706572696f642920746f2066696c6c2074686520736561742069662072656d6f76616c206d65616e732074686174207468652064657369726564206d656d6265727320617265206e6f74206d65742e20536574207468652064657369726564206d656d62657220636f756e743b206966206c6f776572207468616e207468652063757272656e7420636f756e742c207468656e2073656174732077696c6c206e6f7420626520757020656c656374696f6e207768656e2074686579206578706972652e204966206d6f72652c207468656e2061206e657720766f74652077696c6c2062652073746172746564206966206f6e65206973206e6f7420616c726561647920696e2070726f67726573732e20436c61696d2074686174206063616e64696461746560206973206f6e65206f662074686520746f70206063617272795f636f756e74202b20646573697265645f7365617473602063616e646964617465732e204f6e6c7920776f726b7320696666207468652070726573656e746174696f6e20706572696f64206973206163746976652e206063616e646964617465602073686f756c642068617665206174206c6561737420636f6c6c656374656420736f6d65206e6f6e2d7a65726f2060746f74616c6020766f74657320616e6420606f726967696e60206d757374206861766520656e6f7567682066756e647320746f2070617920666f72206120706f74656e7469616c20736c6173682e202d204f28766f746572732920636f6d707574652e63616e646964617465746f74616c436f6d706163743c566f7465496e6465783e205375626d6974206f6e6573656c6620666f722063616e6469646163792e204163636f756e74206d757374206861766520656e6f756768207472616e736665727261626c652066756e647320696e20697420746f207061792074686520626f6e642e204e4f54453a20696620606f726967696e602068617320616c72656164792061737369676e656420617070726f76616c7320766961205b607365745f617070726f76616c73605d2c2069742077696c6c204e4f54206861766520616e7920757361626c652066756e647320746f20706173732063616e64696461637920626f6e6420616e64206d75737420666972737420726574726163742e204e6f746520746861742073657474696e6720617070726f76616c732077696c6c206c6f636b2074686520656e746972652062616c616e6365206f662074686520766f74657220756e74696c2072657472616374696f6e206f72206265696e67207265706f727465642e202d20496e646570656e64656e74206f6620696e7075742e202d205468726565204442206368616e6765732e736c6f742052656d6f7665206120766f7465722e20416c6c20766f746573206172652063616e63656c6c656420616e642074686520766f746572206465706f7369742069732072657475726e65642e2054686520696e646578206d7573742062652070726f7669646564206173206578706c61696e656420696e205b60766f7465725f6174605d2066756e6374696f6e2e20416c736f2072656d6f76657320746865206c6f636b206f6e207468652062616c616e6365206f662074686520766f7465722e20536565205b60646f5f7365745f617070726f76616c732829605d2e202d2054776f20666577657220444220656e74726965732c206f6e65204442206368616e67652e2052656d6f7665206120766f7465722e20466f72206974206e6f7420746f206265206120626f6e642d636f6e73756d696e67206e6f2d6f702c20616c6c20617070726f7665642063616e64696461746520696e6469636573206d757374206e6f772062652065697468657220756e72656769737465726564206f72207265676973746572656420746f20612063616e646964617465207468617420726567697374657265642074686520736c6f742061667465722074686520766f7465722067617665207468656972206c61737420617070726f76616c207365742e20426f746820696e6469636573206d7573742062652070726f7669646564206173206578706c61696e656420696e205b60766f7465725f6174605d2066756e6374696f6e2e204d61792062652063616c6c656420627920616e796f6e652e2052657475726e732074686520766f746572206465706f73697420746f20607369676e6564602e7265706f727465725f696e64657877686f5f696e646578617373756d65645f766f74655f696e646578205365742063616e64696461746520617070726f76616c732066726f6d20612070726f78792e20417070726f76616c20736c6f747320737461792076616c6964206173206c6f6e672061732063616e6469646174657320696e2074686f736520736c6f74732061726520726567697374657265642e202d2053616d6520617320607365745f617070726f76616c73602077697468206f6e65206164646974696f6e616c2073746f7261676520726561642e205365742063616e64696461746520617070726f76616c732e20417070726f76616c20736c6f747320737461792076616c6964206173206c6f6e672061732063616e6469646174657320696e2074686f736520736c6f74732061726520726567697374657265642e204c6f636b73206076616c7565602066726f6d207468652062616c616e6365206f6620606f726967696e6020696e646566696e6974656c792e204f6e6c79205b60726574726163745f766f746572605d206f72205b60726561705f696e6163746976655f766f746572605d2063616e20756e6c6f636b207468652062616c616e63652e206068696e746020617267756d656e7420697320696e74657270726574656420646966666572656e746c79206261736564206f6e3a202d20696620606f726967696e602069732073657474696e6720617070726f76616c7320666f72207468652066697273742074696d653a2054686520696e6465782077696c6c20626520636865636b656420666f722020206265696e6720612076616c6964205f686f6c655f20696e2074686520766f746572206c6973742e2020202d206966207468652068696e7420697320636f72726563746c7920706f696e74696e6720746f206120686f6c652c206e6f206665652069732064656475637465642066726f6d20606f726967696e602e2020202d204f74686572776973652c207468652063616c6c2077696c6c2073756363656564206275742074686520696e6465782069732069676e6f72656420616e642073696d706c792061207075736820746f2074686520202020206c617374206368756e6b207769746820667265652073706163652068617070656e732e20496620746865206e65772070757368206361757365732061206e6577206368756e6b20746f2062652020202020637265617465642c20612066656520696e64696361746564206279205b60566f74696e67466565605d2069732064656475637465642e202d20696620606f726967696e6020697320616c7265616479206120766f7465723a2074686520696e646578205f5f6d7573745f5f2062652076616c696420616e6420706f696e7420746f2074686520636f7272656374202020706f736974696f6e206f662074686520606f726967696e6020696e207468652063757272656e7420766f74657273206c6973742e204e6f7465207468617420616e7920747261696c696e67206066616c73656020766f74657320696e2060766f746573602069732069676e6f7265643b20496e20617070726f76616c20766f74696e672c206e6f7420766f74696e6720666f7220612063616e64696461746520616e6420766f74696e672066616c73652c2061726520657175616c2e202d2054776f20657874726120444220656e74726965732c206f6e65204442206368616e67652e202d20417267756d656e742060766f74657360206973206c696d6974656420696e206c656e67746820746f206e756d626572206f662063616e646964617465732e766f7465735665633c626f6f6c3e68696e74536574496e646578436f756e63696c00000000000000886b1000140000000000000000000000925111000e00000000000000000000000000000000000000000000000000000000000000389711008c76100000000000000000009c6b100001000000000000000100000000000000a46b10000c0000000000000000000000925111000e00000000000000000000000000000000000000000000000000000000000000389711008c7610000000000000000000b06b100001000000000000000100000000000000b86b10000c0000000000000000000000763411000300000000000000000000000000000000000000000000000000000000000000389711008c7610000000000000000000c46b100001000000000000000100000000000000ace61000070000000000000000000000cc6b1000230000000000000000000000000000000000000000000000000000000000000038971100386d10000000000000000000f06b100004000000000000000100000000000000106c1000090000000000000000000000196c10000900000000000000000000000000000000000000000000000000000000000000389711008c7610000000000000000000246c1000010000000000000001000000000000002c6c10000b0000000101000000000000376c100018000000000000004f6c1000110000000000000000000000000000000000000038971100386d100000000000000000003897110000000000000000000100000000000000606c10000e00000001010000000000000b4e11000c000000000000006e6c1000100000000000000000000000000000000000000038971100806c10000000000000000000906c100002000000000000000000000000000000a06c10000b00000001010000000000000b4e11000c00000000000000ab6c1000170000000000000000000000000000000000000038971100c46c10000000000000000000d46c100001000000000000000000000000000000dc6c1000060000000101000000000000f66510000800000000000000e26c1000190000000000000000000000000000000000000038971100386d10000000000000000000fc6c100001000000000000000100000000000000046d10000c0000000000000000000000f66510000800000000000000000000000000000000000000000000000000000000000000389711008c7610000000000000000000106d100001000000000000000100000000000000186d10000a0000000000000000000000f66510000800000000000000000000000000000000000000000000000000000000000000389711008c7610000000000000000000246d1000010000000000000001000000000000002c6d10000a0000000000000000000000255c1100110000000000000000000000000000000000000000000000000000000000000038971100386d10000000000000000000486d100001000000000000000100000000000000506d10000e0000000000000000000000763411000300000000000000000000000000000000000000000000000000000000000000389711008c7610000000000000000000606d100001000000000000000100000000000000686d10000c0000000000000000000000746d10002800000000000000000000000000000000000000000000000000000000000000389711009c6d10000000000000000000ac6d100001000000000000000000000000000000b46d10000b0000000000000000000000bf6d1000210000000000000000000000000000000000000000000000000000000000000038971100e06d10000000000000000000f06d100003000000000000000000000000000000a85c11000500000001010000000000000b4e11000c000000000000000b4e11000c0000000000000000000000000000000000000038971100086e10000000000000000000c05c110002000000000000000000000050726573656e746174696f6e4475726174696f6e6f7210004f0000005465726d4475726174696f6e49721000260000004465736972656453656174730f7210003a0000005665633c28543a3a4163636f756e7449642c20543a3a426c6f636b4e756d626572293e00e37010005500000038711000550000008d71100054000000e17110002e000000566f7465436f756e74566f7465496e64657800009c70100047000000417070726f76616c734f6628543a3a4163636f756e7449642c20536574496e646578295665633c417070726f76616c466c61673e5265676973746572496e666f4f6628566f7465496e6465782c20753332290000370000000000000001000000a100000027701000570000007e7010001e000000566f746572496e666f4f66566f746572496e666f3c42616c616e63654f663c543e3e00003700000000000000010000004f0000000670100021000000566f746572735665633c4f7074696f6e3c543a3a4163636f756e7449643e3e00c36f1000430000004e657874566f746572536574846f10003f000000566f746572436f756e7400006a6f10001a00000043616e646964617465730000370000000000000001000000500000004e6f10001c00000043616e646964617465436f756e7400002a6f1000240000004e65787446696e616c697a6528543a3a426c6f636b4e756d6265722c207533322c205665633c543a3a4163636f756e7449643e29370000000000000001000000a2000000e26e1000480000004c6561646572626f6172645665633c2842616c616e63654f663c543e2c20543a3a4163636f756e744964293e3700000000000000010000004f000000186e100058000000706e100059000000c96e1000190000003700000000000000010000004f0000002047657420746865206c6561646572626f61726420696620776527726520696e207468652070726573656e746174696f6e2070686173652e2054686520666972737420656c656d656e742069732074686520776569676874206f66206561636820656e7472793b204974206d617920626520746865206469726563742073756d6d656420617070726f76616c207374616b65732c206f7220612077656967687465642076657273696f6e206f662069742e20536f727465642066726f6d206c6f7720746f20686967682e20546865206163636f756e747320686f6c64696e672074686520736561747320746861742077696c6c206265636f6d652066726565206f6e20746865206e6578742074616c6c792e2043757272656e74206e756d626572206f66206163746976652063616e64696461746573205468652070726573656e742063616e646964617465206c6973742e2043757272656e74206e756d626572206f6620566f746572732e20746865206e65787420667265652073657420746f2073746f7265206120766f74657220696e2e20546869732077696c6c206b6565702067726f77696e672e205468652070726573656e7420766f746572206c69737420286368756e6b656420616e6420636170706564206174205b60564f5445525f5345545f53495a45605d292e20426173696320696e666f726d6174696f6e2061626f7574206120766f7465722e2054686520766f746520696e64657820616e64206c69737420736c6f742074686174207468652063616e646964617465206077686f60207761732072656769737465726564206f7220604e6f6e6560206966207468657920617265206e6f742063757272656e746c7920726567697374657265642e2054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e6564206f722061726520696e2070726f67726573732e20205468652063757272656e74206d656d626572736869702e205768656e2074686572652773206120766f746520676f696e67206f6e2c20746869732073686f756c64207374696c6c206265207573656420666f722020657865637574697665206d6174746572732e2054686520626c6f636b206e756d62657220287365636f6e6420656c656d656e7420696e20746865207475706c65292069732074686520626c6f636b20746861742020746865697220706f736974696f6e2069732061637469766520756e74696c202863616c63756c61746564206279207468652073756d206f662074686520626c6f636b206e756d626572207768656e2074686520206d656d6265722077617320656c656374656420616e64207468656972207465726d206475726174696f6e292e204e756d626572206f66206163636f756e747320746861742073686f756c6420636f6e737469747574652074686520636f6c6c6563746976652e20486f77206c6f6e67206561636820706f736974696f6e2069732061637469766520666f722e20486f77206c6f6e6720746f2067697665206561636820746f702063616e64696461746520746f2070726573656e74207468656d73656c7665732061667465722074686520766f746520656e64732e000000000000287510000d000000000000007a6511000c000000000000003897110038751000000000000000000048751000020000000000000000000000587510000a000000000000007a6511000c0000000000000038971100687610000000000000000000647510000100000000000000000000006c75100009000000000000007a6511000c0000000000000038971100787510000000000000000000887510000200000000000000000000009875100014000000000000007a6511000c0000000000000038971100ac7510000000000000000000bc751000020000000000000000000000cc7510000a0000000000000076341100030000000000000038971100d87510000000000000000000e8751000020000000000000000000000f87510001300000000000000196c10000900000000000000389711000c76100000000000000000001c761000030000000000000000000000586511000c00000000000000925111000e0000000000000038971100347610000000000000000000447610000200000000000000000000005476100011000000000000007a6511000c000000000000003897110068761000000000000000000078761000010000000000000000000000807610000a00000000000000763411000300000000000000389711008c76100000000000000000009c761000050000000000000000000000c47610000e0000000000000076341100030000000000000038971100d47610000000000000000000e4761000010000000000000000000000ec76100011000000000000007634110003000000000000003897110000771000000000000000000010771000010000000000000043616e646964616379426f6e64000000370000000000000001000000a30000005f7b10004e000000ad7b100014000000566f74696e67426f6e6400001d7b100042000000566f74696e67466565000000370000000000000001000000a4000000b67a10004a000000007b10001d00000050726573656e74536c617368506572566f7465723700000000000000010000009a000000527a100045000000977a10001f0000004361727279436f756e740000370000000000000001000000a5000000e4791000470000002b7a100027000000496e6163746976654772616365506572696f6400370000000000000001000000a6000000477910004c000000937910004b000000de79100006000000370000000000000001000000a7000000f5781000490000003e791000090000004d696e696d756d566f74696e674c6f636b00000037000000000000000100000099000000b67810003f0000004465636179526174696f00003700000000000000010000009c000000637710004d000000b077100041000000f177100047000000387810004a0000008278100034000000564f5445525f5345545f53495a450000370000000000000001000000a80000003f77100024000000415050524f56414c5f5345545f53495a45000000370000000000000001000000a9000000187710002700000020546865206368756e6b2073697a65206f662074686520617070726f76616c20766563746f722e20546865206368756e6b2073697a65206f662074686520766f74657220766563746f722e20446563617920666163746f72206f6620776569676874207768656e206265696e6720616363756d756c617465642e2049742073686f756c64207479706963616c6c792062652073657420746f205f5f6174206c656173745f5f20606d656d626572736869705f73697a65202d316020746f206b6565702074686520636f6c6c656374697665207365637572652e205768656e2073657420746f20604e602c20697420696e64696361746573206028312f4e295e7460206f66207374616b656420697320646563617965642061742077656967687420696e6372656d656e742073746570206074602e20302077696c6c20726573756c7420696e206e6f20776569676874206265696e6720616464656420617420616c6c20286e6f726d616c20617070726f76616c20766f74696e67292e204120726561736f6e61626c652064656661756c742076616c75652069732032342e204d696e696d756d2061626f757420746861742063616e206265207573656420617320746865206c6f636b65642076616c756520666f7220766f74696e672e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e204120726561736f6e61626c652064656661756c742076616c756520697320313030302e20486f77206d616e7920766f746520696e6469636573206e65656420746f20676f20627920616674657220612074617267657420766f7465722773206c61737420766f7465206265666f726520746865792063616e2062652072656170656420696620746865697220617070726f76616c7320617265206d6f6f742e204120726561736f6e61626c652064656661756c742076616c756520697320312e20486f77206d616e792072756e6e6572732d75702073686f756c64206861766520746865697220617070726f76616c73207065727369737420756e74696c20746865206e65787420766f74652e204120726561736f6e61626c652064656661756c742076616c756520697320322e205468652070756e6973686d656e742c2070657220766f7465722c20696620796f752070726f7669646520616e20696e76616c69642070726573656e746174696f6e2e204120726561736f6e61626c652064656661756c742076616c756520697320312e2054686520616d6f756e74206f662066656520706169642075706f6e206561636820766f7465207375626d697373696f6e2c20756e6c6573732069662074686579207375626d69742061205f686f6c655f20696e64657820616e64207265706c6163652069742e20486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f2062652061626c6520746f207375626d697420766f7465732e20486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f207375626d6974206f6e6527732063616e6469646163792e204120726561736f6e61626c652064656661756c742076616c756520697320392e000000387d110028000000dc7b1000440000000e010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f656c656374696f6e732f7372632f6c69622e7273dc7b1000440000000e01000001000000436f756e63696c2050726f787963616e6e6f74207265617020647572696e672070726573656e746174696f6e20706572696f64766f746520696e646578206e6f742063757272656e7463616e6e6f74207265617020647572696e6720677261636520706572696f6474617267657420666f7220696e616374697669747920636c65616e7570206d757374206265206163746976657265706f72746572206d757374206265206120766f746572696e76616c6964207265706f7274657220696e646578696e76616c69642074617267657420696e646578626164207265706f7274657220696e6465786261642074617267657420696e64657872657472616374696f6e20696e64657820696e76616c696472657472616374696f6e20696e646578206d69736d6174636863616e6e6f742072657472616374207768656e2070726573656e74696e6763616e6e6f742072657472616374206e6f6e2d766f7465726475706c69636174652063616e646964617465207375626d697373696f6e696e76616c69642063616e64696461746520736c6f7463616e64696461746520686173206e6f7420656e6f7567682066756e647363616e6e6f742070726573656e74206f757473696465206f662070726573656e746174696f6e20706572696f64696e646578206e6f742063757272656e747374616b65206465706f736974656420746f2070726573656e742077696e6e657220616e6420626520616464656420746f206c6561646572626f6172642073686f756c64206265206e6f6e2d7a65726f6c6561646572626f617264206d757374206578697374207768696c652070726573656e742070686173652061637469766570726573656e746572206d75737420686176652073756666696369656e7420736c61736861626c652066756e647370726573656e7465642063616e646964617465206d7573742062652063757272656e7463616e646964617465206e6f7420776f72746879206f66206c6561646572626f61726463616e646964617465206d757374206e6f7420666f726d2061206475706c696361746564206d656d62657220696620656c65637465646475706c69636174652070726573656e746174696f6e696e636f727265637420746f74616c6e6f20617070726f76616c206368616e67657320647572696e672070726573656e746174696f6e20706572696f64696e636f727265637420766f746520696e646578616d6f756e74206f662063616e6469646174657320746f207265636569766520617070726f76616c20766f7465732073686f756c64206265206e6f6e2d7a65726f616d6f756e74206f662063616e64696461746520766f7465732063616e6e6f742065786365656420616d6f756e74206f662063616e646964617465736c6f636b65642076616c7565206d757374206265206d6f7265207468616e206c696d697477726f6e6720766f74657220696e6465786e657720766f746572206d75737420686176652073756666696369656e742066756e647320746f207061792074686520626f6e64696e76616c696420766f74657220696e646578000000000000e442110008000000000000008881100001000000000000000000000090811000010000000000000000000000988110000800000000000000c8151100010000000000000000000000a0811000010000000000000000000000a88110000700000000000000b0811000030000000000000000000000c8811000010000000000000000000000d08110000500000000000000c8151100010000000000000000000000d8811000010000000000000000000000e08110000800000000000000c8151100010000000000000000000000e88110000100000000000000ccb710000d000000b98210000e0000005370656e64696e677f8210003a0000004177617264656400ccb710000d0000001144110007000000d0431100090000005f821000200000004275726e740000003c82100023000000526f6c6c6f766572f08110004c000000205370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e20536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20536f6d652066756e64732068617665206265656e20616c6c6f63617465642e205765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e204e65772070726f706f73616c2e53657373696f6e2056616c696461746f72734772616e64706146696e616c697479205374616c6c656454726561737572792050726f706f73616c730000387d1100280000001c831000430000007f000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f74726561737572792f7372632f6c69622e72734469676573744974656d206e6f7420657175616c0000000000a08310001200000000000000b4831000010000000000000000000000cc83100001000000000000007265706f72745f6d69736265686176696f72000000000000ed8310000700000000000000e7ea100007000000d483100019000000205265706f727420736f6d65206d69736265686176696f722e5f7265706f72744772616e64706146696e616c697479000000000070aa10000b0000000000000000000000238a11002300000000000000000000000000000000000000000000000000000000000000389711008897100000000000000000006c8610000100000000000000010000000000000074861000050000000000000000000000798610001b0000000000000000000000000000000000000000000000000000000000000038971100948610000000000000000000a486100001000000000000000100000000000000ac8610000d0000000000000000000000b9861000230000000000000000000000000000000000000000000000000000000000000038971100b48e10000000000000000000dc86100001000000000000000000000000000000e48610000a0000000000000000000000925111000e0000000000000000000000000000000000000000000000000000000000000038971100788710000000000000000000f086100001000000000000000000000000000000f8861000070000000000000000000000ff8610002000000000000000000000000000000000000000000000000000000000000000389711002087100000000000000000003087100001000000000000000000000000000000388710000c0000000000000000000000448710000500000000000000000000000000000000000000000000000000000000000000389711004c87100000000000000000005c871000020000000000000001000000000000006c8710000c00000001010000000000004487100005000000000000009f8d11000c000000000000000000000000000000000000003897110078871000000000000000000088871000010000000000000000000000308910001b000000537461746553746f72656453746174653c543a3a426c6f636b4e756d6265723e370000000000000001000000aa0000000c8910002400000050656e64696e674368616e676553746f72656450656e64696e674368616e67653c543a3a426c6f636b4e756d6265723edb881000310000004e657874466f726365640000ac8810002f0000005374616c6c656428543a3a426c6f636b4e756d6265722c20543a3a426c6f636b4e756d6265722900370000000000000001000000a1000000888810002400000043757272656e7453657449645365744964000000370000000000000001000000ab00000000881000570000005788100031000000536574496453657373696f6e3700000000000000010000004f00000090871000700000002041206d617070696e672066726f6d206772616e6470612073657420494420746f2074686520696e646578206f6620746865202a6d6f737420726563656e742a2073657373696f6e20666f7220776869636820697473206d656d62657273207765726520726573706f6e7369626c652e20546865206e756d626572206f66206368616e6765732028626f746820696e207465726d73206f66206b65797320616e6420756e6465726c79696e672065636f6e6f6d696320726573706f6e736962696c69746965732920696e20746865202273657422206f66204772616e6470612076616c696461746f72732066726f6d2067656e657369732e20607472756560206966207765206172652063757272656e746c79207374616c6c65642e206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e2050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e205374617465206f66207468652063757272656e7420617574686f72697479207365742e205468652063757272656e7420617574686f72697479207365742e000000000078891000080000000000000080891000020000000000000000000000b08910000a000000000000007365745f6b65797300000000dabb10000400000000000000098b10000700000000000000108b10000500000000000000e7ea100007000000008a100039000000398a100048000000818a1000310000003897110000000000b28a1000350000003897110000000000c54d11000b000000e78a100022000000f34d110016000000d84d11000c0000002053657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b6579602e20416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722e205468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e20546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e202d204f286c6f67206e2920696e206e756d626572206f66206163636f756e74732e543a3a4b65797370726f6f6653657373696f6e00000000543511000a0000000000000000000000848d1000130000000000000000000000000000000000000000000000000000000000000038971100889710000000000000000000988d100001000000000000000100000000000000a08d10000c00000000000000000000009f8d11000c0000000000000000000000000000000000000000000000000000000000000038971100189710000000000000000000ac8d100001000000000000000100000000000000b48d10000d0000000000000000000000f7431100040000000000000000000000000000000000000000000000000000000000000038971100c48d10000000000000000000d48d100002000000000000000100000000000000e48d10000a0000000000000000000000ee8d10001e00000000000000000000000000000000000000000000000000000000000000389711008897100000000000000000000c8e1000020000000000000001000000000000001c8e10001200000000000000000000002e8e1000080000000000000000000000000000000000000000000000000000000000000038971100889710000000000000000000388e100003000000000000000100000000000000508e1000080000000204010000000000e7ea10000700000000000000588e10000e00000000000000098b1000070000000000000038971100688e10000000000000000000788e100004000000000000000000000000000000988e1000080000000204010000000000e7ea10000700000000000000a08e10001400000000000000588e10000e0000000000000038971100b48e10000000000000000000c48e10000400000000000000000000005665633c543a3a56616c696461746f7249643e008b9110001f00000043757272656e74496e6465786d9110001e0000005175657565644368616e6765640000003700000000000000010000004f000000f69010004e00000044911000290000005175657565644b6579735665633c28543a3a56616c696461746f7249642c20543a3a4b657973293e6f9010004f000000be9010003800000044697361626c656456616c696461746f72735665633c7533323e000002901000200000003897110000000000229010004d0000004e6578744b657973543a3a56616c696461746f72496400003700000000000000010000004f000000db8f10002700000038971100000000002d8f100056000000838f1000580000004b65794f776e6572284b65795479706549642c205665633c75383e293700000000000000010000004f000000e48e10004900000038971100000000002d8f100056000000838f10005800000020546865206f776e6572206f662061206b65792e20546865207365636f6e64206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e20546865206669727374206b657920697320616c77617973206044454455505f4b45595f5052454649586020746f206861766520616c6c20746865206461746120696e207468652073616d65206272616e6368206f662074686520747269652e20486176696e6720616c6c206461746120696e207468652073616d65206272616e63682073686f756c642070726576656e7420736c6f77696e6720646f776e206f7468657220717565726965732e20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e20496e6469636573206f662064697361626c65642076616c696461746f72732e205468652073657420697320636c6561726564207768656e20606f6e5f73657373696f6e5f656e64696e67602072657475726e732061206e657720736574206f66206964656e7469746965732e2054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b6579732077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e20547275652069662074686520756e6465726c79696e672065636f6e6f6d6963206964656e746974696573206f7220776569676874696e6720626568696e64207468652076616c696461746f727320686173206368616e67656420696e20746865207175657565642076616c696461746f72207365742e2043757272656e7420696e646578206f66207468652073657373696f6e2e205468652063757272656e7420736574206f662076616c696461746f72732e000000000000e49110001000000000000000f4911000050000000000000038971100fc91100000000000000000000c921000020000000000000044454455505f4b45595f505245464958265b75385d000000370000000000000001000000ac0000001c92100059000000759210000d0000002055736564206173206669727374206b657920666f7220604e6578744b6579736020616e6420604b65794f776e65726020746f2070757420616c6c20746865206461746120696e746f207468652073616d65206272616e6368206f662074686520747269652e3a73657373696f6e3a6b65797353657373696f6e204e6578744b6579730000000000249310000d000000000000003493100002000000000000000000000064931000090000000000000000000000ac9310000f00000000000000bc931000010000000000000000000000d49310000700000000000000000000000c9410001000000000000000bc9310000100000000000000000000001c941000080000000000000070726f706f73655f7370656e64000000000000005f5511000500000000000000645511001500000000000000fa9510000b000000000000004b22110023000000289510004b000000739510004d000000c0951000150000003897110000000000c54d11000b000000d04d110008000000f111110019000000d595100025000000d84d11000c00000072656a6563745f70726f706f73616c00000000001d9510000b00000000000000e9cd100016000000de9410003f0000003897110000000000c54d11000b000000d04d110008000000f111110019000000514e110010000000d84d11000c000000617070726f76655f70726f706f73616c5c94100057000000b39410002b0000003897110000000000c54d11000b000000d04d110008000000f111110019000000b712110011000000d84d11000c00000020417070726f766520612070726f706f73616c2e2041742061206c617465722074696d652c207468652070726f706f73616c2077696c6c20626520616c6c6f636174656420746f207468652062656e656669636961727920616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e2052656a65637420612070726f706f736564207370656e642e20546865206f726967696e616c206465706f7369742077696c6c20626520736c61736865642e70726f706f73616c5f69642050757420666f727761726420612073756767657374696f6e20666f72207370656e64696e672e2041206465706f7369742070726f706f7274696f6e616c20746f207468652076616c756520697320726573657276656420616e6420736c6173686564206966207468652070726f706f73616c2069732072656a65637465642e2049742069732072657475726e6564206f6e6365207468652070726f706f73616c20697320617761726465642e202d204f6e65204442206368616e67652c206f6e6520657874726120444220656e7472792e62656e656669636961727954726561737572790000000000000008d010000d0000000000000000000000ccb710000d000000000000000000000000000000000000000000000000000000000000003897110018971000000000000000000028971000010000000000000001000000000000009acf1000090000000101000000000000ccb710000d000000000000003097100024000000000000000000000000000000000000003897110054971000000000000000000064971000010000000000000000000000000000006c97100009000000000000000000000075971000120000000000000000000000000000000000000000000000000000000000000038971100889710000000000000000000989710000100000000000000010000003700000000000000010000009c000000fd9710002900000050726f706f73616c3c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e3700000000000000010000004f000000de9710001f000000417070726f76616c735665633c50726f706f73616c496e6465783e0037000000000000000100000050000000a09710003e0000002050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e2050726f706f73616c7320746861742068617665206265656e206d6164652e204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e000000000000089910000c00000000000000149910000700000000000000389711001c99100000000000000000002c9910000200000000000000000000003c99100013000000000000007a6511000c000000000000003897110050991000000000000000000060991000010000000000000000000000689910000b00000000000000925111000e0000000000000038971100749910000000000000000000849910000100000000000000000000008c991000040000000000000014991000070000000000000038971100909910000000000000000000a0991000010000000000000050726f706f73616c426f6e645065726d696c6c00370000000000000001000000ad000000609a100055000000b59a10004400000050726f706f73616c426f6e644d696e696d756d00370000000000000001000000990000000e9a1000520000005370656e64506572696f6400370000000000000001000000ae000000ec991000220000004275726e370000000000000001000000af000000a8991000440000002050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e20506572696f64206265747765656e2073756363657373697665207370656e64732e204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e204672616374696f6e206f6620612070726f706f73616c27732076616c756520746861742073686f756c6420626520626f6e64656420696e206f7264657220746f20706c616365207468652070726f706f73616c2e20416e2061636365707465642070726f706f73616c2067657473207468657365206261636b2e20412072656a65637465642070726f706f73616c20646f6573206e6f742e4772616e64706146696e616c6974792050656e64696e674368616e67654772616e64706146696e616c697479205374617465496e636f6e73697374656e74207374617465202d20636f756c646e277420736574746c6520696d62616c616e636520666f722066756e6473207370656e7420627920747265617375727953657373696f6e205175657565644b65797300590000000800000004000000b0000000b10000000000000000000000b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000590000000800000004000000b0000000b10000000000000000000000b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000590000000800000004000000b3000000b10000000000000000000000b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000590000000800000004000000b3000000b10000000000000000000000b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004772616e64706146696e616c697479204e657874466f72636564636f6465206973206e6f7420666f756e647072697374696e6520636f6465206973206e6f7420666f756e647468657265206973206e6f7420656e6f7567682067617320666f722073746f72696e672074686520636f646553657373696f6e204b65794f776e6572000000f0a0100048000000a10a00000e000000f0a01000480000009b0a00000a00000080a0100019000000a0a01000430000003401000009000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f70687261676d656e2f7372632f6c69622e7273000000000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e72733897110000000000391411000200000060a110007c000000dca11000490000007900000006000000657865632e7072656661625f6d6f64756c652e696e697469616c2063616e27742062652067726561746572207468616e20657865632e7072656661625f6d6f64756c652e6d6178696d756d3b0a09090909090974687573204d656d6f72793a3a6e6577206d757374206e6f74206661696c3b0a0909090909097165642f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f7761736d2f6d6f642e72736e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e72656769737465726564206475706c6963617465206b65791c831000430000007f0000000100000050726f706f73657227732062616c616e636520746f6f206c6f774e6f2070726f706f73616c206174207468617420696e64657866696e616c6e756d417574686f727368697020417574686f7237000000000000000100000038000000387d110028000000e8a210003f000000bf000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f626162652f7372632f6c69622e727300e8a210003f000000bf0000000100000073657269616c697a656420617267732073686f756c642062652070726f7669646564206279207468652072756e74696d653b0a090909636f72726563746c792073657269616c697a656420646174612073686f756c6420626520646573657269616c697a61626c653b0a090909716564387d110028000000607d110050000000370100000900000065706f636820696e64696365732077696c6c206e6576657220726561636820325e3634206265666f726520746865206465617468206f662074686520756e6976657273653b207165640000000000000038a410000a0000000000000044a410000100000000000000000000005ca4100001000000000000007365745f756e636c65730000000000007da410000a0000000000000087a410000e00000064a41000190000002050726f76696465206120736574206f6620756e636c65732e6e65775f756e636c65735665633c543a3a4865616465723e417574686f72736869700000000000a8a51000060000000000000000000000aea510003a0000000000000000000000000000000000000000000000000000000000000038971100e8a510000000000000000000f8a510000100000000000000010000000000000000a610000600000000000000000000000b4e11000c000000000000000000000000000000000000000000000000000000000000003897110008a61000000000000000000018a610000100000000000000000000000000000020a610000c0000000000000000000000f74311000400000000000000000000000000000000000000000000000000000000000000389711002ca6100000000000000000003ca61000010000000000000001000000556e636c65735665633c556e636c65456e7472794974656d3c543a3a426c6f636b4e756d6265722c20543a3a486173682c20543a3a4163636f756e7449643e3e370000000000000001000000500000008ca6100007000000417574686f7200003700000000000000010000004f00000073a6100019000000446964536574556e636c65733700000000000000010000004f00000044a610002f000000205768657468657220756e636c6573207765726520616c72656164792073657420696e207468697320626c6f636b2e20417574686f72206f662063757272656e7420626c6f636b2e20556e636c6573417574686f727368697020556e636c6573556e636c657320616c72656164792073657420696e20626c6f636b2e756e636c6520616c726561647920696e636c75646564756e636c652069732067656e65736973756e636c6520697320746f6f206869676820696e20636861696e756e636c6520706172656e74206e6f7420696e20636861696e756e636c65206e6f7420726563656e7420656e6f75676820746f20626520696e636c756465644261626500000000005caa10000a000000000000000000000076f91000030000000000000000000000000000000000000000000000000000000000000038971100e4aa1000000000000000000068aa10000100000000000000010000000000000070aa10000b00000000000000000000007baa1000270000000000000000000000000000000000000000000000000000000000000038971100a4aa10000000000000000000b4aa100001000000000000000100000000000000bcaa10000b000000000000000000000076f91000030000000000000000000000000000000000000000000000000000000000000038971100e4aa10000000000000000000c8aa100002000000000000000100000000000000d8aa10000b000000000000000000000076f91000030000000000000000000000000000000000000000000000000000000000000038971100e4aa10000000000000000000f4aa100001000000000000000100000000000000fcaa10000a000000000000000000000006ab100008000000000000000000000000000000000000000000000000000000000000003897110070ab1000000000000000000010ab10000a00000000000000010000000000000060ab10000e000000000000000000000006ab100008000000000000000000000000000000000000000000000000000000000000003897110070ab1000000000000000000080ab10000100000000000000010000000000000088ab10000c00000000000000000000007634110003000000000000000000000000000000000000000000000000000000000000003897110094ab10000000000000000000a4ab100009000000000000000100000000000000ecab1000110000000101000000000000763411000300000000000000fdab10000d00000000000000000000000000000000000000389711000cac1000000000000000000038971100000000000000000001000000000000001cac10000b000000000000000000000027ac100008000000000000000000000000000000000000000000000000000000000000003897110030ac1000000000000000000040ac100002000000000000000000000045706f6368496e64657800008bb0100015000000417574686f7269746965735665633c28417574686f7269747949642c2042616265417574686f72697479576569676874293e00003700000000000000010000005000000070b010001b00000047656e65736973536c6f74000eb010003e0000004cb010002400000043757272656e74536c6f7400370000000000000001000000ab000000f9af10001500000052616e646f6d6e6573735b75383b2033325d000033ae10002e000000389711000000000061ae10000b00000038971100000000006cae100041000000adae10003e000000ebae10004500000030af10004500000075af100041000000b6af1000430000004e65787452616e646f6d6e6573730000370000000000000001000000b50000001cae1000170000005365676d656e74496e6465783700000000000000010000009c000000d7ac10001f0000003897110000000000f6ac10003d00000033ad10004000000073ad100025000000389711000000000098ad10003b000000d3ad10004200000015ae100007000000556e646572436f6e737472756374696f6e5665633c5b75383b2033325d3e000037000000000000000100000050000000496e697469616c697a65644d61796265567266003700000000000000010000004f00000050ac10004000000090ac1000470000002054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732060536f6d6560206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e205765206d616b6520612074726164656f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e2057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f2060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e20576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572792065706f63682e204e6578742065706f63682072616e646f6d6e6573732e205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e20232053656375726974792054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e792063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d626572732074686174207468697320286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e20626520757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e2043757272656e7420736c6f74206e756d6265722e2054686520736c6f74206174207768696368207468652066697273742065706f63682061637475616c6c7920737461727465642e2054686973206973203020756e74696c2074686520666972737420626c6f636b206f662074686520636861696e2e2043757272656e742065706f636820617574686f7269746965732e2043757272656e742065706f636820696e6465782e0000000010b110000d0000000000000076f9100003000000000000003897110020b11000000000000000000030b1100002000000000000000000000040b110001100000000000000a3e0100009000000000000003897110054b11000000000000000000064b11000050000000000000045706f63684475726174696f6e000000370000000000000001000000b6000000bcb2100043000000ffb210003f0000004578706563746564426c6f636b54696d65000000370000000000000001000000b70000008cb1100041000000cdb110004400000011b210004100000052b210004200000094b210002800000020546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e6720626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f7574207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f74206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e20546865206e756d626572206f66202a2a736c6f74732a2a207468617420616e2065706f63682074616b65732e20576520636f75706c652073657373696f6e7320746f2065706f6368732c20692e652e2077652073746172742061206e65772073657373696f6e206f6e636520746865206e65772065706f636820626567696e732e756e636c6573303074696d657374616d702073657420696e20626c6f636b20646f65736e2774206d6174636820736c6f7420696e207365616c4e6f206f74686572206572726f72732061726520616363657074656420616674657220616e2068617264206572726f7221496e686572656e7420776974682073616d65206964656e74696669657220616c726561647920657869737473215468657265206973206f6e6c79206f6e6520666174616c206572726f723b20716564005900000008000000040000009d0000003a65787472696e7369635f696e64657800000000e4421100080000000000000020b5100004000000000000000000000040b5100002000000000000000000000050b51000050000000000000058b5100005000000000000000000000080b5100002000000000000000000000090b51000080000000000000048ea100001000000000000000000000098b51000010000000000000000000000a0b510000b0000000000000048ea1000010000000000000000000000acb51000010000000000000000000000664311000800000000000000b4b51000020000000000000000000000c4b51000010000000000000000000000ccb510000e00000000000000b4b51000020000000000000000000000dcb510000100000000000000d043110009000000ccb710000d000000d9431100040000005eb710000b00000069b7100053000000bcb7100010000000566f746564000000d043110009000000d943110004000000f7431100040000005eb710000b0000005eb710000b000000d6b610004200000018b7100046000000417070726f766564a5b6100031000000446973617070726f7665640070b6100035000000d943110004000000f7431100040000002fb61000410000004d656d62657245786563757465640000e4b510004b00000020412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e207761732065786563757465643b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e6720612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e4d656d626572436f756e742041206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e20604d656d626572436f756e7460292e50726f706f73616c496e64657853797374656d204e756d62657253797374656d2045787472696e73696373526f6f74496e7374616e636531436f6c6c656374697665204d656d62657273496e7374616e636532436f6c6c656374697665204d656d6265727353797374656d2044696765737453797374656d20426c6f636b4861736853797374656d204163636f756e744e6f6e6365000000387d1100280000007cb8100041000000e9000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f73797374656d2f7372632f6c69622e7273000000387d110028000000d8b810004500000083000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6c6c6563746976652f7372632f6c69622e727353797374656d20506172656e744861736853797374656d2052616e646f6d4d6174657269616c0080b9100048000000a10a00000e00000053797374656d204576656e747353797374656d204576656e74546f70696373000000000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000d0ba10000a0000000000000038971100000000000000000000000000dcba1000010000000000000000000000e4ba10000600000000000000ecba100001000000000000000000000004bb10000100000000000000000000000cbb10000e000000000000001cbb100001000000000000000000000034bb10000100000000000000000000003cbb1000080000000000000044bb10000100000000000000000000005cbb100001000000000000000000000064bb10000b0000000000000070bb100001000000000000000000000088bb100001000000000000000000000090bb10000c000000000000009cbb1000010000000000000000000000b4bb1000010000000000000066696c6c5f626c6f636b00008bbc10004800000072656d61726b00000000000084bc10000700000000000000e7ea10000700000069bc10001b0000007365745f686561705f706167657300000000000064bc1000050000000000000076f910000300000025bc10003f0000007365745f636f646500000000fc2011000300000000000000e7ea10000700000013bc1000120000007365745f73746f72616765000000000001bc1000050000000000000006bc10000d000000e6bb10001b0000006b696c6c5f73746f7261676500000000dabb10000400000000000000debb100008000000bcbb10001e000000204b696c6c20736f6d65206974656d732066726f6d2073746f726167652e6b6579735665633c4b65793e2053657420736f6d65206974656d73206f662073746f726167652e6974656d735665633c4b657956616c75653e2053657420746865206e657720636f64652e2053657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e7061676573204d616b6520736f6d65206f6e2d636861696e2072656d61726b2e5f72656d61726b20412062696720646973706174636820746861742077696c6c20646973616c6c6f7720616e79206f74686572207472616e73616374696f6e20746f20626520696e636c756465642e53797374656d0000000000000004c210000c00000001010000000000000b4e11000c0000000000000010c21000080000000000000000000000000000000000000038971100e8d21000000000000000000018c210000100000000000000010000000000000020c210000e0000000000000000000000763411000300000000000000000000000000000000000000000000000000000000000000389711006cc21000000000000000000030c210000100000000000000000000000000000038c210001300000000000000000000004bc210000600000000000000000000000000000000000000000000000000000000000000389711006cc21000000000000000000054c21000010000000000000000000000000000005cc21000100000000000000000000000763411000300000000000000000000000000000000000000000000000000000000000000389711006cc2100000000000000000007cc210000100000000000000000000000000000084c2100014000000000000000000000098c21000100000000000000000000000000000000000000000000000000000000000000038971100a8c210000000000000000000b8c2100002000000000000000100000000000000c8c21000090000000101000000000000925111000e000000000000007c4f110007000000000000000000000000000000000000003897110078c310000000000000000000d4c2100001000000000000000100000000000000dcc210000d0000000101000000000000763411000300000000000000e7ea1000070000000000000000000000000000000000000038971100ecc210000000000000000000fcc210000100000000000000010000000000000004c310000e000000000000000000000012c3100012000000000000000000000000000000000000000000000000000000000000003897110024c31000000000000000000034c310000200000000000000010000000000000044c31000060000000000000000000000925111000e0000000000000000000000000000000000000000000000000000000000000038971100e8d2100000000000000000004cc310000100000000000000010000000000000054c310000a00000000000000000000007c4f110007000000000000000000000000000000000000000000000000000000000000003897110078c31000000000000000000060c310000100000000000000010000000000000068c310000e00000000000000000000007c4f110007000000000000000000000000000000000000000000000000000000000000003897110078c31000000000000000000088c310000100000000000000010000000000000090c3100006000000000000000000000096c310000b0000000000000000000000000000000000000000000000000000000000000038971100a4c310000000000000000000b4c3100001000000000000000100000000000000bcc31000060000000000000000000000c2c31000230000000000000000000000000000000000000000000000000000000000000038971100e8c310000000000000000000f8c310000100000000000000010000000000000000c410000a00000000000000000000000ac410000a0000000000000000000000000000000000000000000000000000000000000038971100e8d21000000000000000000014c41000010000000000000001000000000000001cc410000b000000020101000000000027c4100002000000000000007c4f1100070000000000000029c41000210000000000000038971100f8d2100000000000000000004cc410000d00000000000000010000004163636f756e744e6f6e6365543a3a496e646578f9ca10001f00000045787472696e736963436f756e740000cbca10002e000000416c6c45787472696e7369637357656967687457656967687400000086ca100045000000416c6c45787472696e736963734c656e3700000000000000010000004f00000036ca1000500000004e6578745765696768744d756c7469706c6965725765696768744d756c7469706c696572370000000000000001000000ab000000c2c91000590000001bca10001b000000426c6f636b486173680000009cc910002600000045787472696e73696344617461000000370000000000000001000000510000004dc910004f00000052616e646f6d4d6174657269616c2869382c205665633c543a3a486173683e29370000000000000001000000b800000090c8100069000000f9c81000540000004e756d62657200004ec8100042000000506172656e7448617368000032c810001c00000045787472696e73696373526f6f740000370000000000000001000000b9000000edc71000450000004469676573744469676573744f663c543e00000037000000000000000100000050000000b1c710003c0000004576656e74735665633c4576656e745265636f72643c543a3a4576656e742c20543a3a486173683e3e000000370000000000000001000000ba00000089c71000280000004576656e74436f756e744576656e74496e6465785bc710002e0000004576656e74546f7069637328295665633c28543a3a426c6f636b4e756d6265722c204576656e74496e646578293e0000b4c4100049000000fdc4100025000000389711000000000022c510004b0000006dc510002a000000389711000000000097c5100054000000ebc51000510000003cc6100039000000389711000000000075c6100053000000c8c61000530000001bc7100040000000204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e6465786573206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e20546865206669727374206b657920736572766573206e6f20707572706f73652e2054686973206669656c64206973206465636c6172656420617320646f75626c655f6d6170206a75737420666f7220636f6e76656e69656e6365206f66207573696e67206072656d6f76655f707265666978602e20416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e205468697320616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e6420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e205468652076616c756520686173207468652074797065206028543a3a426c6f636b4e756d6265722c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573742074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e20546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e20446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2045787472696e7369637320726f6f74206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2048617368206f66207468652070726576696f757320626c6f636b2e205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e20536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e205468697320697320617272616e67656420617320612072696e6720627566666572207769746820746865206069386020707265666978206265696e672074686520696e64657820696e746f20746865206056656360206f6620746865206f6c6465737420686173682e2045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e20546865206e65787420776569676874206d756c7469706c6965722e20546869732073686f756c6420626520757064617465642061742074686520656e64206f66206561636820626c6f636b206261736564206f6e207468652073617475726174696f6e206c6576656c2028776569676874292e20546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2077656967687420666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e2045787472696e73696373206e6f6e636520666f72206163636f756e74732e496e7374616e636531436f6c6c6563746976652050726f706f73616c73496e7374616e636531436f6c6c65637469766520566f74696e67496e7374616e636532436f6c6c6563746976652050726f706f73616c73496e7374616e636532436f6c6c65637469766520566f74696e6700000000000038cc10000b0000000000000044cc10000100000000000000000000005ccc10000400000000000000000000007ccc1000070000000000000084cc10000100000000000000000000009ccc1000030000000000000000000000b84811000700000000000000b4cc1000020000000000000000000000e4cc100004000000000000000000000070491100040000000000000004cd10000300000000000000000000004ccd100004000000000000007365745f6d656d6265727300000000007ccf10000b00000000000000255c110011000000fbce1000540000004fcf100017000000389711000000000066cf10001600000065786563757465000000000058531100080000000000000075ce10001e00000093ce10003d0000003897110000000000d0ce10002b0000000000000058ce1000090000000000000061ce1000140000000000000058531100080000000000000075ce10001e000000c54d11000b00000006ce1000240000002ace10002e000000d84d11000c000000000000005853110008000000000000007c4f11000700000000000000e4cd10000500000000000000e9cd10001600000000000000ffcd10000700000000000000f743110004000000c54d11000b0000006ccd1000230000008fcd100055000000d84d11000c000000202d20426f756e6465642073746f72616765207265616420616e64207772697465732e202d2057696c6c20626520736c696768746c792068656176696572206966207468652070726f706f73616c20697320617070726f766564202f20646973617070726f7665642061667465722074686520766f74652e696e646578436f6d706163743c50726f706f73616c496e6465783e617070726f7665202d20426f756e6465642073746f7261676520726561647320616e64207772697465732e202d20417267756d656e7420607468726573686f6c6460206861732062656172696e67206f6e207765696768742e7468726573686f6c64436f6d706163743c4d656d626572436f756e743e426f783c3c542061732054726169743c493e3e3a3a50726f706f73616c3e20446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e204f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e205365742074686520636f6c6c6563746976652773206d656d62657273686970206d616e75616c6c7920746f20606e65775f6d656d62657273602e204265206e69636520746f2074686520636861696e20616e642070726f76696465206974207072652d736f727465642e20526571756972657320726f6f74206f726967696e2e6e65775f6d656d62657273496e7374616e636531436f6c6c65637469766550726f706f73616c735665633c543a3a486173683e00e8d010002400000050726f706f73616c4f663c542061732054726169743c493e3e3a3a50726f706f73616c00b5d0100033000000566f74696e67566f7465733c543a3a4163636f756e7449643e00000088d010002d00000050726f706f73616c436f756e7400000076d010001200000028d010004e000000205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e2050726f706f73616c7320736f206661722e20566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e2054686520686173686573206f6620746865206163746976652070726f706f73616c732e496e7374616e636532436f6c6c65637469766500000000009acf1000090000000000000000000000a3cf10000c0000000000000000000000000000000000000000000000000000000000000038971100f8d210000000000000000000b0cf100001000000000000000100000000000000b8cf10000a00000001010000000000007c4f11000700000000000000c2cf1000190000000000000000000000000000000000000038971100d8d210000000000000000000dccf100001000000000000000000000000000000e4cf10000600000001010000000000007c4f11000700000000000000eacf1000130000000000000000000000000000000000000038971100d8d21000000000000000000000d010000100000000000000000000000000000008d010000d000000000000000000000076341100030000000000000000000000000000000000000000000000000000000000000038971100e8d21000000000000000000018d0100001000000000000000100000000000000ace61000070000000000000000000000255c1100110000000000000000000000000000000000000000000000000000000000000038971100f8d21000000000000000000020d010000100000000000000010000003700000000000000010000004f0000003700000000000000010000009c000000370000000000000001000000500000007cb8100041000000e9000000010000003a6865617070616765733a636f646500d8b8100045000000830000000100000070726f706f736572206e6f742061206d656d6265726475706c69636174652070726f706f73616c73206e6f7420616c6c6f776564496e7374616e636531436f6c6c6563746976652050726f706f73616c4f66496e7374616e636531436f6c6c6563746976652050726f706f73616c436f756e7470726f706f73616c206d757374206578697374766f746572206e6f742061206d656d6265726d69736d61746368656420696e6465786475706c696361746520766f74652069676e6f726564496e7374616e636532436f6c6c6563746976652050726f706f73616c4f66496e7374616e636532436f6c6c6563746976652050726f706f73616c436f756e740000000000000064d410000f0000000000000074d4100002000000000000000000000084d4100004000000000000004e65774163636f756e74496e64657800d0431100090000001fd510000c000000a4d41000220000003897110000000000c6d410004100000007d51000180000002041206e6577206163636f756e7420696e646578207761732061737369676e65642e2054686973206576656e74206973206e6f7420747269676765726564207768656e20616e206578697374696e6720696e64657820697320726561737369676e656420746f20616e6f7468657220604163636f756e744964602e4163636f756e74496e6465780050d510001900000070d5100048000000230100000e000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f6c69622e7273d0d510000e000000ded5100048000000220100004a0000006578706c696369742070616e69632f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f6c69622e72730000d0d510000e000000ded5100048000000210100004a00000058d610002b00000083d6100044000000ef0000000400000054696d657374616d70206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f74696d657374616d702f7372632f6c69622e727300e0d610003000000083d6100044000000e30000000400000054696d657374616d70206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b28d710004e00000083d6100044000000e40000000400000054696d657374616d70206d75737420696e6372656d656e74206279206174206c65617374203c4d696e696d756d506572696f643e206265747765656e2073657175656e7469616c20626c6f636b7300000000000054d810000b000000000000003897110000000000000000000000000060d8100001000000000000000000000068d810000d000000000000003897110000000000000000000000000078d8100001000000000000000000000080d810000e000000000000003897110000000000000000000000000090d8100001000000000000000000000098d810000c0000000000000038971100000000000000000000000000a4d81000010000000000000000000000acd810000500000000000000b4d81000010000000000000000000000bcd8100001000000000000004d656d626572416464656400c5d91000390000004d656d62657252656d6f7665640000008ad910003b0000004d656d6265727353776170706564000053d91000370000004d656d6265727352657365740dd910004600000044756d6d79000000e0d810002d000000c4d810001c000000205068616e746f6d206d656d6265722c206e6576657220757365642e727374643a3a6d61726b65723a3a5068616e746f6d446174613c284163636f756e7449642c204576656e74293e20546865206d656d62657273686970207761732072657365743b2073656520746865207472616e73616374696f6e20666f722077686f20746865206e6577207365742069732e2054776f206d656d62657273207765726520737761707065643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732072656d6f7665643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732061646465643b2073656520746865207472616e73616374696f6e20666f722077686f2e54696d657374616d70204e6f77496e646963657320456e756d53657400005900000008000000040000009d000000387d11002800000044da1000420000004a000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f696e64696365732f7372632f6c69622e72730000387d110028000000a0da1000450000005c000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f6d656d626572736869702f7372632f6c69622e727300000044da1000420000004a0000000100000054696d657374616d7020746f6f2066617220696e2066757475726520746f206163636570744765747320616e64206465636f6465732074696d657374616d7020696e686572656e742064617461496e646963657300000000fcdb10000b000000000000000000000007dc10000f000000000000000000000000000000000000000000000000000000000000003897110018dc1000000000000000000028dc10000100000000000000010000000000000030dc100007000000010100000000000007dc10000f00000000000000255c1100110000000000000000000000000000000000000038971100b4e61000000000000000000038dc10000100000000000000010000004e657874456e756d536574543a3a4163636f756e74496e64657800003700000000000000010000009c00000056dc10001f000000456e756d5365740040dc1000160000002054686520656e756d65726174696f6e20736574732e20546865206e657874206672656520656e756d65726174696f6e207365742e496e6469636573204e657874456e756d536574e9dd10001c000000b8dc1000440000009e00000003000000c5dd100024000000b8dc100044000000a7000000030000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f6578656375746976652f7372632f6c69622e727393dd100032000000b8dc10004400000001010000030000006cdd100027000000b8dc100044000000090100000400000044dd100028000000b8dc1000440000000f0100000300000053746f7261676520726f6f74206d757374206d6174636820746861742063616c63756c617465642e446967657374206974656d206d757374206d6174636820746861742063616c63756c617465642e4e756d626572206f6620646967657374206974656d73206d757374206d6174636820746861742063616c63756c617465642e5472616e73616374696f6e207472696520726f6f74206d7573742062652076616c69642e506172656e7420686173682073686f756c642062652076616c69642e0000000000000034de1000030000000000000038de100001000000000000000000000050de100009000000000000007365740000000000d2df10000300000000000000d5df10001200000098de1000160000003897110000000000aede10005600000004df10003600000038971100000000003adf1000510000008bdf10001100000038971100000000009cdf10003600000020536574207468652063757272656e742074696d652e20546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6e2070686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e205468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e742073706563696669656420627920604d696e696d756d506572696f64602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060496e686572656e74602e6e6f77436f6d706163743c543a3a4d6f6d656e743e54696d657374616d7000000000a0e01000030000000000000000000000a3e01000090000000000000000000000000000000000000000000000000000000000000038971100ace010000000000000000000bce0100001000000000000000100000000000000c4e01000090000000000000000000000f7431100040000000000000000000000000000000000000000000000000000000000000038971100d0e010000000000000000000e0e010000100000000000000010000004e6f77543a3a4d6f6d656e74370000000000000001000000ab00000015e11000240000004469645570646174650000003700000000000000010000004f000000e8e010002d00000020446964207468652074696d657374616d7020676574207570646174656420696e207468697320626c6f636b3f2043757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e0000000000000074e110000d00000000000000a3e0100009000000000000003897110084e11000000000000000000094e1100004000000000000004d696e696d756d506572696f64000000370000000000000001000000bb000000b4e110005a0000000ee210005a00000068e2100059000000c1e210001c00000020546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e204265776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f2064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20652e672e20466f7220417572612c2069742077696c6c20626520646f75626c65207468697320706572696f64206f6e2064656661756c742073657474696e67732e0000000000000090e310000a000000000000009ce31000010000000000000000000000b4e31000030000000000000000000000cce310000d000000000000009ce31000010000000000000000000000dce31000030000000000000000000000f4e310000b0000000000000000e4100002000000000000000000000030e4100003000000000000000000000048e410000d0000000000000058e4100001000000000000000000000070e4100004000000000000006164645f6d656d6265720000000000005712110003000000000000000b4e11000c000000f2e510001f000000389711000000000011e610002d00000072656d6f76655f6d656d6265720000009ee51000240000003897110000000000c2e5100030000000737761705f6d656d626572000000000095e5100006000000000000000b4e11000c000000000000009be5100003000000000000000b4e11000c00000037e5100030000000389711000000000067e510002e00000072657365745f6d656d626572730000000000000030e510000700000000000000255c11001100000090e4100056000000e6e410001b000000389711000000000001e510002f000000204368616e676520746865206d656d6265727368697020746f2061206e6577207365742c20646973726567617264696e6720746865206578697374696e67206d656d626572736869702e204265206e69636520616e64207061737320606d656d6265727360207072652d736f727465642e204d6179206f6e6c792062652063616c6c65642066726f6d206052657365744f726967696e60206f7220726f6f742e6d656d626572732053776170206f7574206f6e65206d656d626572206072656d6f76656020666f7220616e6f746865722060616464602e204d6179206f6e6c792062652063616c6c65642066726f6d2060537761704f726967696e60206f7220726f6f742e72656d6f76656164642052656d6f76652061206d656d626572206077686f602066726f6d20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d206052656d6f76654f726967696e60206f7220726f6f742e204164642061206d656d626572206077686f6020746f20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d20604164644f726967696e60206f7220726f6f742e496e7374616e6365314d656d6265727368697000000000000000ace61000070000000000000000000000255c1100110000000000000000000000000000000000000000000000000000000000000038971100b4e610000000000000000000c4e610000100000000000000010000004d656d626572730037000000000000000100000050000000cce6100032000000205468652063757272656e74206d656d626572736869702c2073746f72656420617320616e206f726465726564205665632e000080e7100048000000b10100002300000080e7100048000000b20100002300000030e7100049000000870200001d0000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f736f72742e7273000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e727330e71000490000009d0000003a00000030e7100049000000a400000030000000a0da1000450000005c00000001000000496e7374616e6365314d656d62657273686970204d656d62657273616c72656164792061206d656d626572626164206f726967696e6e6f742061206d656d62657200000080e7100048000000a10a00000e00000054e810001c00000056617269616e74206973206e6576657220636f6e737472756374656480e81000440000000a040000220000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f6c69622e727373746f72616765206973206e6f74206e756c6c2c207468657265666f7265206d75737420626520612076616c69642074797065000000000000ea1000080000000000000008ea100003000000000000000000000020ea100001000000000000000000000028ea10000c000000000000008c43110002000000000000000000000034ea10000100000000000000000000003cea10000a0000000000000048ea100001000000000000000000000050ea100001000000000000000000000058ea10000f0000000000000068ea100001000000000000000000000070ea100001000000000000000000000078ea10000a0000000000000084ea100002000000000000000000000094ea1000020000000000000000000000a4ea10000800000000000000acea1000020000000000000000000000bcea100001000000000000005472616e73666572d043110009000000d0431100090000001144110007000000eeeb10005a000000496e7374616e746961746564b7eb100037000000436f646553746f7265640000d94311000400000089eb10002e0000005363686564756c655570646174656400763411000300000059eb100030000000446973706174636865640000d043110009000000f743110004000000eeea10004e0000003ceb10001d000000436f6e7472616374d043110009000000e7ea100007000000c4ea10002300000020416e206576656e742066726f6d20636f6e7472616374206f66206163636f756e742e5665633c75383e20412063616c6c2077617320646973706174636865642066726f6d2074686520676976656e206163636f756e742e2054686520626f6f6c207369676e616c73207768657468657220697420776173207375636365737366756c20657865637574696f6e206f72206e6f742e20547269676765726564207768656e207468652063757272656e74207363686564756c6520697320757064617465642e20436f646520776974682074686520737065636966696564206861736820686173206265656e2073746f7265642e20436f6e7472616374206465706c6f7965642062792061646472657373206174207468652073706563696669656420616464726573732e205472616e736665722068617070656e6564206066726f6d6020746f2060746f60207769746820676976656e206076616c7565602061732070617274206f662061206063616c6c60206f722060696e7374616e7469617465602e436f6e7472616374205072697374696e65436f6465436f6e747261637420436f646553746f72616765436f6e747261637420436f6e7472616374496e666f4f66436f6e747261637420476173507269636500000037000000000000000100000038000000c0ec10004a0000003200000006000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f63757276652e7273000000000000e8ed10000f00000000000000f8ed100001000000000000000000000010ee100003000000000000000000000028ee1000080000000000000030ee100002000000000000000000000060ee1000020000000000000000000000af861100040000000000000070ee1000040000000000000000000000d0ee100007000000000000000000000008ef10000b0000000000000014ef100004000000000000000000000074ef10000a0000000000000000000000c4ef10000f00000000000000d4ef100002000000000000000000000004f0100005000000000000007570646174655f7363686564756c65000000000054f6100008000000000000005cf6100008000000e4f510002d000000389711000000000011f61000430000007075745f636f64650000000092f3100009000000000000009bf310000c00000000000000e0f510000400000000000000e7ea10000700000054f5100057000000abf51000350000000000000046f1100004000000000000004b22110023000000000000005f551100050000000000000064551100150000000000000092f3100009000000000000009bf310000c00000000000000bbf310000400000000000000e7ea100007000000bff3100042000000389711000000000001f410004a0000004bf410002c00000077f4100046000000bdf41000520000000ff5100045000000696e7374616e7469617465000000000089f31000090000000000000064551100150000000000000092f3100009000000000000009bf310000c00000000000000a7f310000900000000000000b0f310000b00000000000000bbf310000400000000000000e7ea10000700000068f110006f0000003897110000000000d7f11000260000003897110000000000fdf11000500000004df21000410000008ef210005b000000e9f210005700000040f310002a0000006af310001f000000636c61696d5f737572636861726765000000000046f1100004000000000000000b4e11000c000000000000004af110000a0000000000000054f11000140000002cf010005c00000088f01000450000003897110000000000cdf010004e0000001bf110002b00000020416c6c6f777320626c6f636b2070726f64756365727320746f20636c61696d206120736d616c6c2072657761726420666f72206576696374696e67206120636f6e74726163742e204966206120626c6f636b2070726f6475636572206661696c7320746f20646f20736f2c206120726567756c61722075736572732077696c6c20626520616c6c6f77656420746f20636c61696d20746865207265776172642e20496620636f6e7472616374206973206e6f742065766963746564206173206120726573756c74206f6620746869732063616c6c2c206e6f20616374696f6e73206172652074616b656e20616e64207468652073656e646572206973206e6f7420656c696769626c6520666f7220746865207265776172642e646573746175785f73656e6465724f7074696f6e3c543a3a4163636f756e7449643e20496e7374616e7469617465732061206e657720636f6e74726163742066726f6d207468652060636f646568617368602067656e65726174656420627920607075745f636f6465602c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e20496e7374616e74696174696f6e20697320657865637574656420617320666f6c6c6f77733a202d205468652064657374696e6174696f6e206164647265737320697320636f6d7075746564206261736564206f6e207468652073656e64657220616e642068617368206f662074686520636f64652e202d2054686520736d6172742d636f6e7472616374206163636f756e7420697320637265617465642061742074686520636f6d707574656420616464726573732e202d20546865206063746f725f636f64656020697320657865637574656420696e2074686520636f6e74657874206f6620746865206e65776c792d63726561746564206163636f756e742e204275666665722072657475726e656420202061667465722074686520657865637574696f6e206973207361766564206173207468652060636f646560206f6620746865206163636f756e742e205468617420636f64652077696c6c20626520696e766f6b656420202075706f6e20616e792063616c6c2072656365697665642062792074686973206163636f756e742e202d2054686520636f6e747261637420697320696e697469616c697a65642e656e646f776d656e746761735f6c696d6974436f6d706163743c4761733e636f64655f68617368436f6465486173683c543e64617461204d616b657320612063616c6c20746f20616e206163636f756e742c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e202a20496620746865206163636f756e74206973206120736d6172742d636f6e7472616374206163636f756e742c20746865206173736f63696174656420636f64652077696c6c20626520657865637574656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e202a20496620746865206163636f756e74206973206120726567756c6172206163636f756e742c20616e792076616c75652077696c6c206265207472616e736665727265642e202a204966206e6f206163636f756e742065786973747320616e64207468652063616c6c2076616c7565206973206e6f74206c657373207468616e20606578697374656e7469616c5f6465706f736974602c206120726567756c6172206163636f756e742077696c6c206265206372656174656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e2053746f7265732074686520676976656e2062696e617279205761736d20636f646520696e746f2074686520636861696e27732073746f7261676520616e642072657475726e73206974732060636f646568617368602e20596f752063616e20696e7374616e746961746520636f6e747261637473206f6e6c7920776974682073746f72656420636f64652e636f6465205570646174657320746865207363686564756c6520666f72206d65746572696e6720636f6e7472616374732e20546865207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e207468652073746f726564207363686564756c652e7363686564756c655363686564756c6500000000ccf81000080000000000000000000000d4f810000300000000000000000000000000000000000000000000000000000000000000389711007cf910000000000000000000d8f8100001000000000000000100000000000000e0f810000f00000000000000000000005cf61000080000000000000000000000000000000000000000000000000000000000000038971100f0f81000000000000000000000f910000100000000000000010000000000000008f910000c0000000101000000000000b0f310000b00000000000000e7ea100007000000000000000000000000000000000000003897110014f91000000000000000000024f91000010000000000000000000000000000002cf910000b0000000101000000000000b0f310000b0000000000000037f9100016000000000000000000000000000000000000003897110050f91000000000000000000060f910000100000000000000000000000000000068f910000e000000000000000000000076f910000300000000000000000000000000000000000000000000000000000000000000389711007cf9100000000000000000008cf910000100000000000000010000000000000094f910000e00000001010000000000000b4e11000c00000000000000a2f910000f0000000000000000000000000000000000000038971100b4f910000000000000000000c4f9100001000000000000000000000000000000ccf910000800000000000000000000007a6511000c0000000000000000000000000000000000000000000000000000000000000038971100d4f910000000000000000000e4f910000100000000000000010000004761735370656e744761730020fb10002000000043757272656e745363686564756c6500370000000000000001000000bc000000fbfa1000250000005072697374696e65436f64653700000000000000010000004f000000a2fa100059000000436f646553746f726167657761736d3a3a5072656661625761736d4d6f64756c650000003700000000000000010000004f00000049fa1000590000004163636f756e74436f756e746572753634000000370000000000000001000000ab00000034fa100015000000436f6e7472616374496e666f4f66436f6e7472616374496e666f3c543e0000003700000000000000010000004f0000000afa10002a0000004761735072696365370000000000000001000000bd000000ecf910001e00000020546865207072696365206f66206f6e6520756e6974206f66206761732e2054686520636f6465206173736f6369617465642077697468206120676976656e206163636f756e742e20546865207375627472696520636f756e7465722e2041206d617070696e67206265747765656e20616e206f726967696e616c20636f6465206861736820616e6420696e737472756d656e746564207761736d20636f64652c20726561647920666f7220657865637574696f6e2e2041206d617070696e672066726f6d20616e206f726967696e616c20636f6465206861736820746f20746865206f726967696e616c20636f64652c20756e746f756368656420627920696e737472756d656e746174696f6e2e2043757272656e7420636f7374207363686564756c6520666f7220636f6e7472616374732e20476173207370656e7420736f2066617220696e207468697320626c6f636b2e00000000c0fe10001300000000000000925111000e0000000000000038971100d4fe10000000000000000000e4fe100004000000000000000000000004ff100010000000000000007a6511000c00000000000000389711005cff1000000000000000000014ff10000100000000000000000000001cff100011000000000000007634110003000000000000003897110030ff1000000000000000000040ff100002000000000000000000000050ff10000b000000000000007a6511000c00000000000000389711005cff100000000000000000006cff100001000000000000000000000074ff100011000000000000007a6511000c000000000000003897110088ff1000000000000000000098ff1000070000000000000000000000d0ff10000f000000000000007a6511000c0000000000000038971100e0ff10000000000000000000f0ff1000020000000000000000000000000011000b000000000000007a6511000c00000000000000389711007c00110000000000000000000c001100010000000000000000000000140011000b000000000000007a6511000c00000000000000389711007c0011000000000000000000200011000100000000000000000000002800110012000000000000007a6511000c00000000000000389711007c00110000000000000000003c0011000100000000000000000000004400110012000000000000007a6511000c000000000000003897110058001100000000000000000068001100010000000000000000000000700011000b000000000000007a6511000c00000000000000389711007c00110000000000000000008c0011000200000000000000000000009c0011000b00000000000000d4f81000030000000000000038971100cc0011000000000000000000a8001100020000000000000000000000b80011001200000000000000d4f81000030000000000000038971100cc0011000000000000000000dc001100020000000000000000000000ec001100080000000000000076341100030000000000000038971100f4001100000000000000000004011100020000000000000000000000140111000c000000000000007634110003000000000000003897110020011100000000000000000030011100010000000000000000000000380111000d00000000000000d4f810000300000000000000389711004801110000000000000000005801110002000000000000005369676e6564436c61696d48616e646963617000370000000000000001000000be000000080711003800000038971100000000004007110043000000830711001a000000546f6d6273746f6e654465706f736974d30611003500000053746f7261676553697a654f6666736574000000370000000000000001000000a90000005606110054000000aa0611002900000052656e74427974654665650037000000000000000100000099000000090611004d00000052656e744465706f7369744f6666736574000000370000000000000001000000bf0000009104110041000000d2041100160000003897110000000000e80411005a00000042051100560000009805110053000000eb0511001e00000053757263686172676552657761726400370000000000000001000000c00000003e04110039000000770411001a0000005472616e736665724665650019041100250000004372656174696f6e46656500f2031100270000005472616e73616374696f6e426173654665650000bb031100370000005472616e73616374696f6e4279746546656500003700000000000000010000009b0000007803110043000000436f6e7472616374466565003700000000000000010000009a0000002103110050000000710311000700000043616c6c4261736546656500cc02110047000000130311000e000000496e7374616e7469617465426173654665650000370000000000000001000000c1000000760211004e000000c4021100080000004d61784465707468370000000000000001000000c20000001c0211004c000000680211000e0000004d617856616c756553697a65370000000000000001000000c3000000ce0111004e000000426c6f636b4761734c696d6974000000370000000000000001000000c40000006801110049000000b10111001d00000020546865206d6178696d756d20616d6f756e74206f6620676173207468617420636f756c6420626520657870656e6465642070657220626c6f636b2e204120726561736f6e61626c652064656661756c742076616c75652069732031305f3030305f3030302e20546865206d6178696d756d2073697a65206f6620612073746f726167652076616c756520696e2062797465732e204120726561736f6e61626c652064656661756c74206973203136204b69422e20546865206d6178696d756d206e657374696e67206c6576656c206f6620612063616c6c2f696e7374616e746961746520737461636b2e204120726561736f6e61626c652064656661756c742076616c7565206973203130302e20546865206261736520666565206368617267656420666f7220696e7374616e74696174696e67206120636f6e74726163742e204120726561736f6e61626c652064656661756c742076616c7565206973203137352e20546865206261736520666565206368617267656420666f722063616c6c696e6720696e746f206120636f6e74726163742e204120726561736f6e61626c652064656661756c742076616c7565206973203133352e205468652066656520726571756972656420746f20696e7374616e7469617465206120636f6e747261637420696e7374616e63652e204120726561736f6e61626c652064656661756c742076616c75652069732032312e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b20746865207065722d6279746520706f7274696f6e2e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b2074686520626173652e205468652066656520726571756972656420746f2063726561746520616e206163636f756e742e205468652066656520726571756972656420746f206d616b652061207472616e736665722e205265776172642074686174206973207265636569766564206279207468652070617274792077686f736520746f75636820686173206c656420746f2072656d6f76616c206f66206120636f6e74726163742e2054686520616d6f756e74206f662066756e6473206120636f6e74726163742073686f756c64206465706f73697420696e206f7264657220746f206f66667365742074686520636f7374206f66206f6e6520627974652e204c6574277320737570706f736520746865206465706f73697420697320312c303030204255202862616c616e636520756e697473292f6279746520616e64207468652072656e7420697320312042552f627974652f6461792c207468656e206120636f6e7472616374207769746820312c3030302c3030302042552074686174207573657320312c303030206279746573206f662073746f7261676520776f756c6420706179206e6f2072656e742e20427574206966207468652062616c616e6365207265647563656420746f203530302c30303020425520616e64207468652073746f7261676520737461796564207468652073616d6520617420312c3030302c207468656e20697420776f756c6420706179203530302042552f6461792e205072696365206f6620612062797465206f662073746f7261676520706572206f6e6520626c6f636b20696e74657276616c2e2053686f756c642062652067726561746572207468616e20302e2053697a65206f66206120636f6e7472616374206174207468652074696d65206f6620696e7374616e746961696f6e2e205468697320697320612073696d706c652077617920746f20656e73757265207468617420656d70747920636f6e747261637473206576656e7475616c6c7920676574732064656c657465642e20546865206d696e696d756d20616d6f756e7420726571756972656420746f2067656e6572617465206120746f6d6273746f6e652e204e756d626572206f6620626c6f636b2064656c617920616e2065787472696e73696320636c61696d20737572636861726765206861732e205768656e20636c61696d207375726368617267652069732063616c6c656420627920616e2065787472696e736963207468652072656e7420697320636865636b656420666f722063757272656e745f626c6f636b202d2064656c617943616e6e6f7420726573746f726520746f20696e6578697374696e67206f7220616c69766520636f6e74726163746d656d6f727976616c69646174696f6e3a20696d706f727420656e74727920706f696e747320746f2061206e6f6e2d6578697374656e74207479706543616e6e6f7420696d706f727420676c6f62616c736d6f64756c6520696d706f7274732061206e6f6e2d6578697374656e742066756e6374696f6e6d6f64756c6520696d706f72747320606578745f7072696e746c6e60206275742064656275672066656174757265732064697361626c656443616e6e6f7420696d706f7274207461626c65736d6f64756c652068617320696d706f7274732066726f6d2061206e6f6e2d27656e7627206e616d6573706163654d656d6f727920696d706f7274206d757374206861766520746865206669656c64206e616d6520276d656d6f7279274d756c7469706c65206d656d6f727920696d706f72747320646566696e65644d6178696d756d206e756d626572206f662070616765732073686f756c6420626520616c77617973206465636c617265642e52657175657374656420696e697469616c206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520726571756573746564206d6178696d756d4d6178696d756d206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520636f6e66696775726564206d6178696d756d2e64656661756c743a000000387d11002800000080e8100044000000c80100000100000080e8100044000000c8010000010000006e6577207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e2063757272656e74496e76616c69642073757263686172676520636c61696d3a206f726967696e206d757374206265207369676e6564206f7220696e686572656e7420616e6420617578696c696172792073656e646572206f6e6c792070726f7669646564206f6e20696e686572656e74417574686f72697479446973636f76657279204b657973000000387d110028000000c80a11004e00000034000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f617574686f726974792d646973636f766572792f7372632f6c69622e72730000c80a11004e000000340000000100000000000000ac0b11000500000000000000b40b1100010000000000000000000000bc0b1100010000000000000000000000c40b11000a00000000000000a8431100010000000000000000000000d00b1100010000000000000000000000d80b11000a00000000000000b40b1100010000000000000000000000bc0b110001000000000000005375646964000000f7431100040000001e0c1100180000004b65794368616e6765640000e20b11003c0000005375646f4173446f6e6520546865207375646f6572206a757374207377697463686564206964656e746974793b20746865206f6c64206b657920697320737570706c6965642e2041207375646f206a75737420746f6f6b20706c6163652e707265636f6e646974696f6e3a20616c6c20696d706f7274732073686f756c6420626520636865636b656420616761696e737420746865207369676e617475726573206f6620636f72726573706f6e64696e670a09090909090966756e6374696f6e7320646566696e65642062792060646566696e655f656e762160206d6163726f206279207468652075736572206f6620746865206d6163726f3b0a0909090909097369676e617475726573206f662074686573652066756e6374696f6e7320646566696e6564206279206024706172616d73603b0a09090909090963616c6c7320616c77617973206d616465207769746820617267756d656e7473207479706573206f662077686963682061726520646566696e65642062792074686520636f72726573706f6e64696e6720696d706f7274733b0a09090909090974687573207479706573206f6620617267756d656e74732073686f756c6420626520657175616c20746f2074797065206c69737420696e206024706172616d736020616e640a0909090909096c656e677468206f6620617267756d656e74206c69737420616e642024706172616d732073686f756c6420626520657175616c3b0a0909090909097468757320746869732063616e206e6576657220626520604e6f6e65603b0a0909090909097165643b0a09090909090972657475726e2074797065206572726f7276616c69646174696f6e206572726f72647572696e6720657865637574696f6e00387d110028000000740e11003f00000068000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7375646f2f7372632f6c69622e727300740e11003f00000068000000010000006f6e6c79207468652063757272656e74207375646f206b65792063616e207375646f5375646f204b65796f6e6c79207468652063757272656e74207375646f206b65792063616e206368616e676520746865207375646f206b657900400f1100480000009b0a00000a000000400f110048000000a10a00000e0000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e7273000000000c1011000400000000000000684a1100010000000000000000000000101011000a00000000000000000000006010110007000000000000006810110001000000000000000000000080101100090000000000000000000000c81011000700000000000000d0101100020000000000000000000000001111000b000000000000007375646fc81211004e0000003897110000000000bd111100340000003897110000000000c54d11000b000000d04d110008000000f1111100190000000a121100180000002212110035000000d84d11000c0000007365745f6b65790000000000fc20110003000000000000004b221100230000005a1211005d0000003897110000000000bd111100340000003897110000000000c54d11000b000000d04d110008000000f111110019000000b712110011000000d84d11000c0000007375646f5f617300000000005712110003000000000000004b221100230000000000000058531100080000000000000060531100100000005811110054000000ac111100110000003897110000000000bd111100340000003897110000000000c54d11000b000000d04d110008000000f1111100190000000a121100180000002212110035000000d84d11000c0000002041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c207769746820605369676e656460206f726967696e2066726f6d206120676976656e206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e202d204c696d697465642073746f726167652072656164732e202d204f6e6520444220777269746520286576656e74292e202d20556e6b6e6f776e20776569676874206f662064657269766174697665206070726f706f73616c6020657865637574696f6e2e77686f2041757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f206b65792e202d204f6e65204442206368616e67652e2041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e5375646f000000000000741311000300000000000000000000000b4e11000c0000000000000000000000000000000000000000000000000000000000000038971100781311000000000000000000881311000100000000000000010000004b657900370000000000000001000000c500000090131100210000002054686520604163636f756e74496460206f6620746865207375646f206b65792e0000003b1411000d0000001e1411001b0000003914110002000000dc131100420000001f020000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f6e6f64652f72756e74696d652f7372632f6c69622e727342616420696e70757420646174612070726f766964656420746f203a20657865637574655f626c6f636b5014110010000000696e697469616c697a655f626c6f636b681411000f0000006170706c795f65787472696e736963008014110013000000696e686572656e745f65787472696e73696373009c1411000f000000636865636b5f696e686572656e747300b41411001400000076616c69646174655f7472616e73616374696f6ed01411000f0000006f6666636861696e5f776f726b657200e8141100040000007369676ef4141100060000007665726966790000041511000d0000006163636f756e745f6e6f6e6365000000af86110004000000241511001500000067656e65726174655f73657373696f6e5f6b65797300000000000000c01511000600000000000000c8151100010000000000000000000000d0151100010000000000000000000000d81511000500000000000000e0151100020000000000000000000000f0151100010000000000000000000000f81511001a00000000000000108d110001000000000000000000000014161100020000000000000052657761726400001144110007000000c616110038000000536c617368000000d04311000900000011441100070000007d161100490000004f6c64536c617368696e675265706f7274446973636172646564000024161100470000006b1611001200000020416e206f6c6420736c617368696e67207265706f72742066726f6d2061207072696f72206572612077617320646973636172646564206265636175736520697420636f756c64206e6f742062652070726f6365737365642e204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e20416c6c2076616c696461746f72732068617665206265656e2072657761726465642062792074686520676976656e2062616c616e63652e5374616b696e672043757272656e7445726153746172745374616b696e67204e6f6d696e61746f727368656164206f66205374616b696e67204e6f6d696e61746f72735374616b696e672056616c696461746f727368656164206f66205374616b696e672056616c696461746f72735374616b696e67205374616b6572735374616b696e6720426f6e6465645374616b696e67204c65646765725374616b696e672050617965655374616b696e672043757272656e74456c65637465640000000000f81911000400000000000000fc191100030000000000000000000000441a11000f0000000000000000000000bc1a11000a00000000000000c81a1100010000000000000000000000e01a11000e0000000000000000000000501b11000600000000000000581b1100010000000000000000000000701b1100170000000000000000000000281c11001100000000000000389711000000000000000000000000003c1c1100100000000000000000000000bc1c11000800000000000000c41c1100010000000000000000000000dc1c11000b0000000000000000000000341d110008000000000000003c1d1100010000000000000000000000541d11000b0000000000000000000000ac1d1100050000000000000038971100000000000000000000000000b41d11000b00000000000000000000000c1e11000900000000000000181e1100010000000000000000000000301e11000b0000000000000000000000881e11000e00000000000000981e1100010000000000000000000000b01e11000b0000000000000000000000081f110013000000000000001c1f1100010000000000000000000000341f11000100000000000000000000003c1f11000d00000000000000389711000000000000000000000000004c1f1100050000000000000000000000741f11000d0000000000000038971100000000000000000000000000841f1100060000000000000000000000b41f11001100000000000000c81f1100010000000000000000000000e01f11000100000000000000626f6e6400000000412211000a000000000000004b22110023000000000000005f5511000500000000000000645511001500000000000000f12211000500000000000000f622110011000000d72b110059000000302c1100210000003897110000000000512c11004c00000038971100000000009d2c1100490000003897110000000000c54d11000b000000e62c110035000000d04d1100080000001b2d11001a0000003897110000000000352d11005b000000902d110049000000d84d11000c000000626f6e645f6578747261000000000000c92b11000e000000000000006455110015000000a32a110059000000fc2a11000d0000003897110000000000092b1100540000005d2b110059000000b62b11001300000038971100000000005a211100550000003897110000000000c54d11000b000000af2111003a000000d04d1100080000001d55110010000000d84d11000c000000756e626f6e640000000000005f55110005000000000000006455110015000000c8261100550000001d271100400000005d271100490000003897110000000000a627110052000000f8271100300000003897110000000000282811004f000000772811004f000000c62811003f00000038971100000000009c22110055000000389711000000000005291100260000003897110000000000c54d11000b0000002b29110050000000e9211100260000007b29110059000000d42911005c000000302a1100690000001d55110010000000992a11000a00000077697468647261775f756e626f6e646564000000c12411004b00000038971100000000000c2511004d000000592511001300000038971100000000009c2211005500000038971100000000006c2511001b0000003897110000000000c54d11000b0000008725110055000000dc251100510000002d2611003d0000006a2611005e0000000f22110032000000d84d11000c00000076616c696461746500000000a02411000500000000000000a52411001c000000662411003a0000003897110000000000232111003700000038971100000000009c221100550000003897110000000000c54d11000b000000af2111003a000000e9211100260000000f22110032000000d84d11000c0000006e6f6d696e617465000000003724110007000000000000003e241100280000004e231100440000003897110000000000232111003700000038971100000000009c221100550000003897110000000000c54d11000b0000009223110049000000db231100260000000124110036000000d84d11000c0000006368696c6c00000007231100320000003897110000000000232111003700000038971100000000009c221100550000003897110000000000c54d11000b000000af2111003a00000039231100150000000f22110032000000d84d11000c0000007365745f706179656500000000000000f12211000500000000000000f6221100110000006e2211002e0000003897110000000000232111003700000038971100000000009c221100550000003897110000000000c54d11000b000000af2111003a000000e9211100260000000f22110032000000d84d11000c0000007365745f636f6e74726f6c6c6572000000000000412211000a000000000000004b22110023000000ff201100240000003897110000000000232111003700000038971100000000005a211100550000003897110000000000c54d11000b000000af2111003a000000e9211100260000000f22110032000000d84d11000c0000007365745f76616c696461746f725f636f756e740000000000fc2011000300000000000000fa4e11000c000000dc20110020000000666f7263655f6e6f5f65726173000000b02011002c0000003897110000000000c54d11000b000000a020110010000000d84d11000c000000666f7263655f6e65775f657261000000252011005300000078201100280000003897110000000000c54d11000b000000a020110010000000d84d11000c0000007365745f696e76756c6e657261626c6573000000000000001b2011000a00000000000000255c110011000000e81f11003300000020536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e76616c696461746f727320466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c20626520726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e202d204e6f20617267756d656e74732e20466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e2054686520696465616c206e756d626572206f662076616c696461746f72732e6e6577202852652d297365742074686520636f6e74726f6c6c6572206f6620612073746173682e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e202d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732e202d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e636f6e74726f6c6c65723c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f75726365202852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e706179656552657761726444657374696e6174696f6e204465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e202d20436f6e7461696e73206f6e6520726561642e204465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e202d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f66206074617267657473602c2077686963682069732063617070656420617420604d41585f4e4f4d494e4154494f4e53602e202d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e746172676574735665633c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263653e204465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e707265667356616c696461746f7250726566733c42616c616e63654f663c543e3e2052656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e205468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722069742077616e74732e2053656520616c736f205b6043616c6c3a3a756e626f6e64605d2e202d20436f756c6420626520646570656e64656e74206f6e2074686520606f726967696e6020617267756d656e7420616e6420686f77206d7563682060756e6c6f636b696e6760206368756e6b732065786973742e2020497420696d706c6965732060636f6e736f6c69646174655f756e6c6f636b656460207768696368206c6f6f7073206f76657220604c65646765722e756e6c6f636b696e67602c2077686963682069732020696e6469726563746c7920757365722d636f6e74726f6c6c65642e20536565205b60756e626f6e64605d20666f72206d6f72652064657461696c2e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732c20796574207468652073697a65206f6620776869636820636f756c64206265206c61726765206261736564206f6e20606c6564676572602e205363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e6420706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e20543a3a43757272656e63793a3a6d696e696d756d5f62616c616e636528292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e204f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665207468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e204e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d41585f554e4c4f434b494e475f4348554e4b5360292063616e20636f2d657869737473206174207468652073616d652074696d652e20496e207468617420636173652c205b6043616c6c3a3a77697468647261775f756e626f6e646564605d206e65656420746f2062652063616c6c656420666972737420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e2053656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204c696d697465642062757420706f74656e7469616c6c79206578706c6f697461626c6520636f6d706c65786974792e202d20456163682063616c6c20287265717569726573207468652072656d61696e646572206f662074686520626f6e6465642062616c616e636520746f2062652061626f766520606d696e696d756d5f62616c616e6365602920202077696c6c2063617573652061206e657720656e74727920746f20626520696e73657274656420696e746f206120766563746f722028604c65646765722e756e6c6f636b696e676029206b65707420696e2073746f726167652e202020546865206f6e6c792077617920746f20636c65616e207468652061666f72656d656e74696f6e65642073746f72616765206974656d20697320616c736f20757365722d636f6e74726f6c6c656420766961206077697468647261775f756e626f6e646564602e203c2f7765696768743e2041646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757020666f72207374616b696e672e20557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e20556e6c696b65205b60626f6e64605d206f72205b60756e626f6e64605d20746869732066756e6374696f6e20646f6573206e6f7420696d706f736520616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e6d61785f6164646974696f6e616c2054616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c20626520746865206163636f756e74207468617420636f6e74726f6c732069742e206076616c756560206d757374206265206d6f7265207468616e2074686520606d696e696d756d5f62616c616e636560207370656369666965642062792060543a3a43757272656e6379602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e202d20546872656520657874726120444220656e74726965732e204e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e656420756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20616e6420676574732072656d6f76656420617320647573742e5374616b696e6700000000683411000e0000000000000000000000763411000300000000000000000000000000000000000000000000000000000000000000389711006c36110000000000000000007c3411000100000000000000010000000000000084341100150000000000000000000000763411000300000000000000000000000000000000000000000000000000000000000000389711009c3411000000000000000000ac34110001000000000000000100000000000000b43411000d0000000000000000000000255c1100110000000000000000000000000000000000000000000000000000000000000038971100d03711000000000000000000c434110003000000000000000100000000000000dc3411000600000001010000000000000b4e11000c000000000000000b4e11000c00000000000000000000000000000000000000389711001c3511000000000000000000e434110001000000000000000000000000000000ec3411000600000001010000000000000b4e11000c00000000000000f23411002900000000000000000000000000000000000000389711001c35110000000000000000002c35110001000000000000000000000000000000343511000500000001010000000000000b4e11000c00000000000000f62211001100000000000000000000000000000000000000389711003c35110000000000000000004c35110001000000000000000100000000000000543511000a00000001010100000000000b4e11000c00000000000000a52411001c00000000000000000000000000000000000000389711006035110000000000000000007035110001000000000000000100000000000000783511000a00000001010100000000000b4e11000c00000000000000255c1100110000000000000000000000000000000000000038971100d0371100000000000000000084351100010000000000000001000000000000008c3511000700000001010000000000000b4e11000c0000000000000093351100240000000000000000000000000000000000000038971100b83511000000000000000000c835110004000000000000000100000000000000e83511000e0000000000000000000000255c1100110000000000000000000000000000000000000000000000000000000000000038971100d03711000000000000000000f835110001000000000000000100000000000000003611000a00000000000000000000000a3611000800000000000000000000000000000000000000000000000000000000000000389711006c361100000000000000000014361100010000000000000001000000000000001c3611000f00000000000000000000002b3611000b00000000000000000000000000000000000000000000000000000000000000389711003836110000000000000000004836110001000000000000000100000000000000503611001b00000000000000000000009f8d11000c00000000000000000000000000000000000000000000000000000000000000389711006c36110000000000000000007c36110001000000000000000100000000000000843611001600000000000000000000009a361100090000000000000000000000000000000000000000000000000000000000000038971100a43611000000000000000000b436110001000000000000000100000000000000bc3611000900000000000000000000007a6511000c0000000000000000000000000000000000000000000000000000000000000038971100c83611000000000000000000d836110003000000000000000100000000000000f0361100080000000000000000000000f83611000700000000000000000000000000000000000000000000000000000000000000389711000037110000000000000000001037110001000000000000000100000000000000183711001300000000000000000000002b37110007000000000000000000000000000000000000000000000000000000000000003897110034371100000000000000000044371100030000000000000001000000000000005c3711000a0000000000000000000000663711001d0000000000000000000000000000000000000000000000000000000000000038971100d0371100000000000000000084371100010000000000000001000000000000008c3711000f00000001010000000000000a36110008000000000000009b371100320000000000000000000000000000000000000038971100d03711000000000000000000e037110001000000000000000100000056616c696461746f72436f756e74753332000000da3d11002a0000004d696e696d756d56616c696461746f72436f756e74000000370000000000000001000000c60000008a3d110050000000496e76756c6e657261626c6573000000b63c1100560000000c3d1100530000005f3d11002b000000426f6e6465640000763c1100400000004c65646765725374616b696e674c65646765723c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e003700000000000000010000004f000000253c11005100000050617965650000003700000000000000010000004f000000ec3b11003900000056616c696461746f72730000370000000000000001000000c70000009b3b1100510000004e6f6d696e61746f72730000423b1100590000005374616b6572734578706f737572653c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e00370000000000000001000000c8000000853a110053000000d83a11004600000038971100000000001e3b11002400000043757272656e74456c65637465640000463a11003f00000043757272656e74457261457261496e64657800002f3a11001700000043757272656e7445726153746172744d6f6d656e744f663c543e0000370000000000000001000000ab000000113a11001e00000043757272656e74457261537461727453657373696f6e496e646578003700000000000000010000009c000000dd3911003400000043757272656e74457261506f696e74734561726e6564457261506f696e747300370000000000000001000000c90000009a39110043000000536c6f745374616b65000000370000000000000001000000980000001e3911004c00000038971100000000006a39110030000000466f726365457261466f7263696e67003700000000000000010000004f000000d738110047000000536c6173685265776172644672616374696f6e50657262696c6c0000370000000000000001000000ca000000603811003e00000038971100000000009e38110039000000426f6e646564457261735665633c28457261496e6465782c2053657373696f6e496e646578293e001738110049000000457261536c6173684a6f75726e616c5665633c536c6173684a6f75726e616c456e7472793c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e3e00000037000000000000000100000050000000e83711002f00000020416c6c20736c617368657320746861742068617665206f6363757272656420696e206120676976656e206572612e2041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e205468652070657263656e74616765206f662074686520736c617368207468617420697320646973747269627574656420746f207265706f72746572732e205468652072657374206f662074686520736c61736865642076616c75652069732068616e646c6564206279207468652060536c617368602e205472756520696620746865206e6578742073657373696f6e206368616e67652077696c6c2062652061206e657720657261207265676172646c657373206f6620696e6465782e2054686520616d6f756e74206f662062616c616e6365206163746976656c79206174207374616b6520666f7220656163682076616c696461746f7220736c6f742c2063757272656e746c792e2054686973206973207573656420746f20646572697665207265776172647320616e642070756e6973686d656e74732e205265776172647320666f72207468652063757272656e74206572612e205573696e6720696e6469636573206f662063757272656e7420656c6563746564207365742e205468652073657373696f6e20696e646578206174207768696368207468652063757272656e742065726120737461727465642e20546865207374617274206f66207468652063757272656e74206572612e205468652063757272656e742065726120696e6465782e205468652063757272656e746c7920656c65637465642076616c696461746f7220736574206b65796564206279207374617368206163636f756e742049442e204e6f6d696e61746f727320666f72206120706172746963756c6172206163636f756e74207468617420697320696e20616374696f6e207269676874206e6f772e20596f752063616e27742069746572617465207468726f7567682076616c696461746f727320686572652c2062757420796f752063616e2066696e64207468656d20696e207468652053657373696f6e206d6f64756c652e2054686973206973206b6579656420627920746865207374617368206163636f756e742e20546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f2074686520736574206f66207374617368206b657973206f6620616c6c2076616c696461746f727320746f206e6f6d696e6174652e20546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e2057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e20416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e63652074686579277265206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f757220696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e2054686520696465616c206e756d626572206f66207374616b696e67207061727469636970616e74732e00000000743e11000e000000000000009f8d11000c0000000000000038971100843e11000000000000000000943e11000100000000000000000000009c3e11000f000000000000000a361100080000000000000038971100ac3e11000000000000000000bc3e1100010000000000000053657373696f6e735065724572610000370000000000000001000000a5000000fd3e11001c000000426f6e64696e674475726174696f6e00370000000000000001000000cb000000c43e110039000000204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e204e756d626572206f662073657373696f6e7320706572206572612e5374616b696e6720536c6f745374616b650000603f110019000000803f110048000000bb0100002d0000005374616b696e6720457261536c6173684a6f75726e616c0000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f6f70732f61726974682e72735374616b696e6720496e76756c6e657261626c6573000000387d110028000000f83f1100420000009c020000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7374616b696e672f7372632f6c69622e72730000f83f1100420000009c02000001000000636f6e74726f6c6c657220616c72656164792070616972656463616e206e6f7420626f6e6420776974682076616c7565206c657373207468616e206d696e696d756d2062616c616e6365737461736820616c726561647920626f6e6465646e6f7420612073746173686e6f74206120636f6e74726f6c6c657263616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b73746172676574732063616e6e6f7420626520656d7074790000000000e44211000800000000000000ec42110002000000000000000000000038971100000000000000000000000000fc421100060000000000000004431100030000000000000000000000389711000000000000000000000000001c4311000e0000000000000038971100000000000000000000000000389711000000000000000000000000002a431100070000000000000034431100020000000000000000000000389711000000000000000000000000004443110006000000000000004c431100010000000000000000000000389711000000000000000000000000005443110009000000000000004c431100010000000000000000000000389711000000000000000000000000005d43110009000000000000004c4311000100000000000000000000003897110000000000000000000000000066431100080000000000000070431100020000000000000000000000389711000000000000000000000000008043110009000000000000008c431100020000000000000000000000389711000000000000000000000000009c4311000b00000000000000a843110001000000000000000000000038971100000000000000000000000000b04311000600000000000000b843110003000000000000000000000038971100000000000000000050726f706f736564084411000900000011441100070000005461626c6564000008441100090000001144110007000000184411000e00000045787465726e616c5461626c656453746172746564000000e84311000f000000fb4311000d0000005061737365640000e84311000f0000004e6f7450617373656443616e63656c6c656445786563757465640000e84311000f000000f74311000400000044656c656761746564000000d043110009000000d043110009000000556e64656c65676174656400d0431100090000005665746f65640000d043110009000000d943110004000000dd4311000b0000004163636f756e74496448617368426c6f636b4e756d6265725265666572656e64756d496e646578626f6f6c566f74655468726573686f6c6450726f70496e64657842616c616e63655665633c4163636f756e7449643e44656d6f637261637920566f74654f6644656d6f6372616379205265666572656e64756d496e666f4f6644656d6f63726163792044656c65676174696f6e7368656164206f662044656d6f63726163792044656c65676174696f6e7344656d6f6372616379204469737061746368517565756544656d6f637261637920566f74657273466f7244656d6f6372616379205075626c696350726f70730000005045110048000000a10a00000e00000044656d6f6372616379204465706f7369744f664e6f207075626c69632070726f706f73616c732077616974696e6743616e6e6f7420696e6a6563742061207265666572656e64756d207468617420656e6473206561726c696572207468616e2070726563656564696e67207265666572656e64756d000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e727344656d6f6372616379204e65787445787465726e616c4e6f2065787465726e616c2070726f706f73616c2077616974696e67000000000000b84811000700000000000000c0481100020000000000000000000000f0481100060000000000000000000000204911000600000000000000284911000100000000000000000000004049110006000000000000000000000070491100040000000000000074491100020000000000000000000000a4491100070000000000000000000000dc4911000a0000000000000074491100020000000000000000000000e8491100070000000000000000000000204a11001000000000000000304a1100010000000000000000000000484a1100020000000000000000000000584a11001000000000000000684a1100010000000000000000000000804a1100020000000000000000000000904a11001900000000000000684a1100010000000000000000000000ac4a1100050000000000000000000000d44a11001800000000000000684a1100010000000000000000000000ec4a1100050000000000000000000000144b11000a00000000000000204b1100030000000000000000000000684b1100080000000000000000000000a84b11000d00000000000000b84b1100010000000000000000000000d04b1100010000000000000000000000d84b11001100000000000000ec4b1100010000000000000000000000044c11000100000000000000000000000c4c11000d000000000000001c4c1100030000000000000000000000644c11000100000000000000000000006c4c11000900000000000000784c1100010000000000000000000000904c1100050000000000000000000000b84c11000c0000000000000038971100000000000000000000000000c44c1100050000000000000000000000ec4c11000c00000000000000784c1100010000000000000000000000f84c1100050000000000000000000000204d11000800000000000000284d1100020000000000000000000000584d1100050000000000000000000000804d11000a00000000000000389711000000000000000000000000008c4d1100050000000000000070726f706f736500000000005853110008000000000000006053110010000000000000005f55110005000000000000006455110015000000f5541100280000003897110000000000c54d11000b000000d04d1100080000003f55110020000000d84d11000c0000007365636f6e640000000000005853110008000000000000002d55110012000000f5541100280000003897110000000000c54d11000b000000d04d1100080000001d55110010000000d84d11000c000000766f746500000000374f110009000000000000000a4f11001800000000000000704911000400000000000000f154110004000000755411004d000000c25411002f0000003897110000000000c54d11000b000000d04d110008000000565411001f000000d84d11000c00000070726f78795f766f74650000c453110054000000185411003e0000003897110000000000c54d11000b000000d04d110008000000565411001f000000d84d11000c000000656d657267656e63795f63616e63656c00000000374f11000900000000000000e84311000f00000070531100540000004c5311000c00000065787465726e616c5f70726f706f7365000000005853110008000000000000006053110010000000005311004c0000004c5311000c00000065787465726e616c5f70726f706f73655f6d616a6f726974790000009252110056000000e852110018000000389711000000000018521100530000006b5211002700000065787465726e616c5f70726f706f73655f64656661756c74a551110052000000f751110021000000389711000000000018521100530000006b52110027000000666173745f747261636b0000000000006f4f11000d000000000000007c4f11000700000000000000855111000d00000000000000925111000e00000000000000a05111000500000000000000925111000e000000834f110054000000d74f110059000000305011003b00000038971100000000006b5011003e000000a95011004b000000f450110055000000495111003c0000007665746f5f65787465726e616c000000000000006f4f11000d000000000000007c4f110007000000404f11002f00000063616e63656c5f7265666572656e64756d00000000000000374f110009000000000000000a4f110018000000224f11001500000063616e63656c5f71756575656400000000000000da4e11000400000000000000de4e11001700000000000000f54e11000500000000000000fa4e11000c00000000000000064f110004000000000000000a4f110018000000b24e1100280000007365745f70726f787900000000000000ad4e110005000000000000000b4e11000c000000874e1100260000003897110000000000c54d11000b000000f34d110016000000d84d11000c00000072657369676e5f70726f7879614e1100260000003897110000000000c54d11000b000000514e110010000000d84d11000c00000072656d6f76655f70726f78792b4e1100260000003897110000000000c54d11000b000000514e110010000000d84d11000c00000064656c656761746500000000094e110002000000000000000b4e11000c00000000000000174e11000a00000000000000214e11000a000000e44d11000f0000003897110000000000c54d11000b000000f34d110016000000d84d11000c000000756e64656c65676174650000b44d1100110000003897110000000000c54d11000b000000d04d110008000000d84d11000c00000020556e64656c656761746520766f74652e2023203c7765696768743e202d204f2831292e2023203c2f7765696768743e2044656c656761746520766f74652e202d204f6e6520657874726120444220656e7472792e746f543a3a4163636f756e744964636f6e76696374696f6e436f6e76696374696f6e20436c656172207468652070726f78792e2043616c6c6564206279207468652073746173682e202d204f6e6520444220636c6561722e20436c656172207468652070726f78792e2043616c6c6564206279207468652070726f78792e205370656369667920612070726f78792e2043616c6c6564206279207468652073746173682e70726f78792043616e63656c20612070726f706f73616c2071756575656420666f7220656e6163746d656e742e7768656e436f6d706163743c543a3a426c6f636b4e756d6265723e7768696368436f6d706163743c7533323e77686174436f6d706163743c5265666572656e64756d496e6465783e2052656d6f76652061207265666572656e64756d2e7265665f696e646578205665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e70726f706f73616c5f68617368543a3a48617368205363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c656420696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e6520627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e202d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e202d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265202020656e61637465642e20496e6372656173656420746f2060456d657267656e6379566f74696e67506572696f646020696620746f6f206c6f772e766f74696e675f706572696f64543a3a426c6f636b4e756d62657264656c6179205363686564756c652061206e656761746976652d7475726e6f75742d62696173207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061207072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e205363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e205363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e70726f706f73616c426f783c543a3a50726f706f73616c3e205363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d6520566f746520696e2061207265666572656e64756d206f6e20626568616c66206f6620612073746173682e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b20206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e202d204f6e65204442206368616e67652c206f6e6520444220656e7472792e20566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e566f74652050726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e202d204f6e6520444220656e7472792e436f6d706163743c50726f70496e6465783e202d2054776f204442206368616e6765732c206f6e6520444220656e7472792e76616c7565436f6d706163743c42616c616e63654f663c543e3e44656d6f6372616379000000000000ac5a11000f0000000000000000000000084411000900000000000000000000000000000000000000000000000000000000000000389711006c5b11000000000000000000bc5a110001000000000000000100000000000000c45a11000b0000000000000000000000cf5a11002b0000000000000000000000000000000000000000000000000000000000000038971100385c11000000000000000000fc5a110001000000000000000100000000000000045b11000900000001010000000000000844110009000000000000000d5b1100210000000000000000000000000000000000000038971100305b11000000000000000000405b110001000000000000000000000000000000485b11000f0000000000000000000000e84311000f00000000000000000000000000000000000000000000000000000000000000389711006c5b11000000000000000000585b110001000000000000000100000000000000605b1100090000000000000000000000e84311000f00000000000000000000000000000000000000000000000000000000000000389711006c5b110000000000000000007c5b110001000000000000000100000000000000845b1100100000000101000000000000e84311000f00000000000000945b11002d0000000000000000000000000000000000000038971100b05c11000000000000000000c45b110001000000000000000000000000000000cc5b11000d0000000101000000000000925111000e00000000000000d95b11002b0000000000000000000000000000000000000038971100045c11000000000000000000145c1100010000000000000001000000000000001c5c1100090000000101000000000000e84311000f00000000000000255c1100110000000000000000000000000000000000000038971100385c11000000000000000000485c110001000000000000000100000000000000505c1100060000000101000000000000565c11001f00000000000000f1541100040000000000000000000000000000000000000038971100785c11000000000000000000885c110004000000000000000100000000000000a85c11000500000001010000000000000b4e11000c000000000000000b4e11000c0000000000000000000000000000000000000038971100b05c11000000000000000000c05c110002000000000000000000000000000000d05c11000b00000001010100000000000b4e11000c00000000000000db5c11001a0000000000000000000000000000000000000038971100f85c11000000000000000000085d110001000000000000000100000000000000105d1100150000000000000000000000f7431100040000000000000000000000000000000000000000000000000000000000000038971100ec5d11000000000000000000285d110002000000000000000100000000000000385d11000c0000000000000000000000445d11001c0000000000000000000000000000000000000000000000000000000000000038971100605d11000000000000000000705d110004000000000000000000000000000000905d11000900000001010000000000007c4f11000700000000000000995d1100230000000000000000000000000000000000000038971100bc5d11000000000000000000cc5d110002000000000000000000000000000000dc5d11000d00000001010000000000007c4f11000700000000000000f7431100040000000000000000000000000000000000000038971100ec5d11000000000000000000fc5d11000100000000000000010000005075626c696350726f70436f756e74006c6311003d0000005075626c696350726f70735665633c2850726f70496e6465782c20543a3a50726f706f73616c2c20543a3a4163636f756e744964293e00004c631100200000004465706f7369744f662842616c616e63654f663c543e2c205665633c543a3a4163636f756e7449643e290000370000000000000001000000a20000002b631100210000005265666572656e64756d436f756e7400df6211004c0000004e65787454616c6c790000003700000000000000010000009c000000ad621100320000005265666572656e64756d496e666f4f66285265666572656e64756d496e666f3c543a3a426c6f636b4e756d6265722c20543a3a50726f706f73616c3e29000000806211002d000000446973706174636851756575655665633c4f7074696f6e3c28543a3a50726f706f73616c2c205265666572656e64756d496e646578293e3e370000000000000001000000500000005062110030000000566f74657273466f725665633c543a3a4163636f756e7449643e0000370000000000000001000000500000002762110029000000566f74654f66285265666572656e64756d496e6465782c20543a3a4163636f756e744964290000003700000000000000010000004f000000e86011005800000040611100530000009361110057000000ea6111003d00000050726f78790000003700000000000000010000004f0000007a6011004c000000c66011002200000044656c65676174696f6e7328543a3a4163636f756e7449642c20436f6e76696374696f6e29000000370000000000000001000000cc0000002a601100500000004c6173745461626c656457617345787465726e616c000000ca5f110056000000206011000a0000004e65787445787465726e616c28543a3a50726f706f73616c2c20566f74655468726573686f6c6429370000000000000001000000cd000000dc5e110056000000325f110055000000875f110029000000b05f11001a000000426c61636b6c69737428543a3a426c6f636b4e756d6265722c205665633c543a3a4163636f756e7449643e29370000000000000001000000a20000004e5e110054000000a25e11003a00000043616e63656c6c6174696f6e730000003700000000000000010000004f000000045e11004a000000205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e2041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d6265722028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e20546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e20546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743a202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f72202d20605075626c696350726f70736020697320656d7074792e205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c69632070726f706f73616c2e2047657420746865206163636f756e742028616e64206c6f636b20706572696f64732920746f20776869636820616e6f74686572206163636f756e742069732064656c65676174696e6720766f74652e2057686f2069732061626c6520746f20766f746520666f722077686f6d2e2056616c7565206973207468652066756e642d686f6c64696e67206163636f756e742c206b65792069732074686520766f74652d7472616e73616374696f6e2d73656e64696e67206163636f756e742e204765742074686520766f746520696e206120676976656e207265666572656e64756d206f66206120706172746963756c617220766f7465722e2054686520726573756c74206973206d65616e696e6766756c206f6e6c792069662060766f746572735f666f726020696e636c756465732074686520766f746572207768656e2063616c6c6564207769746820746865207265666572656e64756d2028796f75276c6c20676574207468652064656661756c742060566f7465602076616c7565206f7468657277697365292e20496620796f7520646f6e27742077616e7420746f20636865636b2060766f746572735f666f72602c207468656e20796f752063616e20616c736f20636865636b20666f722073696d706c65206578697374656e636520776974682060566f74654f663a3a657869737473602066697273742e204765742074686520766f7465727320666f72207468652063757272656e742070726f706f73616c2e205175657565206f66207375636365737366756c207265666572656e646120746f20626520646973706174636865642e20496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e20546865206e657874207265666572656e64756d20696e64657820746861742073686f756c642062652074616c6c6965642e20546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e2054686f73652077686f2068617665206c6f636b65642061206465706f7369742e20546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e00000000000000fc6411000f00000000000000925111000e00000000000000389711000c65110000000000000000001c651100050000000000000000000000446511000c00000000000000925111000e0000000000000038971100e0651100000000000000000050651100010000000000000000000000586511000c00000000000000925111000e0000000000000038971100e06511000000000000000000646511000100000000000000000000006c6511000e000000000000007a6511000c000000000000003897110088651100000000000000000098651100010000000000000000000000a06511001500000000000000925111000e0000000000000038971100b86511000000000000000000c8651100010000000000000000000000d06511000d00000000000000925111000e0000000000000038971100e06511000000000000000000f06511000100000000000000456e6163746d656e74506572696f6400370000000000000001000000ce0000003f6711005c00000038971100000000009b6711004c000000e76711005a00000041681100270000004c61756e6368506572696f640667110039000000566f74696e67506572696f64d86611002e0000004d696e696d756d4465706f73697442616c616e63654f663c543e0000370000000000000001000000cf0000008b6611004d000000456d657267656e6379566f74696e67506572696f64000000370000000000000001000000d0000000506611003b000000436f6f6c6f6666506572696f64000000370000000000000001000000d1000000f86511005800000020506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f7220616e20656d657267656e6379207265666572656e64756d2e20546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e20486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e20546865206d696e696d756d20706572696f64206f66206c6f636b696e6720616e642074686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e2049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e73757265207468617420766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652e387d11002800000080681100440000004f010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f64656d6f63726163792f7372632f6c69622e7273036b110023000000d96a11002a00000080681100440000004f0100000100000076616c756520746f6f206c6f7770726f706f73657227732062616c616e636520746f6f206c6f7763616e206f6e6c79207365636f6e6420616e206578697374696e672070726f706f73616c7365636f6e64657227732062616c616e636520746f6f206c6f7744656d6f63726163792050726f78796e6f7420612070726f787944656d6f63726163792043616e63656c6c6174696f6e7370726f706f73616c207374696c6c20626c61636b6c697374656470726f706f73616c20616c7265616479206d61646544656d6f637261637920426c61636b6c697374696e76616c696420686173686e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974796e6f2070726f706f73616c206d616465756e6b6e6f776e2070726f706f73616c6e6f2065787465726e616c2070726f706f73616c6964656e74697479206d6179206e6f74207665746f20612070726f706f73616c207477696365616c726561647920612070726f787977726f6e672070726f78796e6f742064656c656761746564756e6b6e6f776e20696e64657863616e6e6f742063616e63656c207468652073616d652070726f706f73616c20747769636570726f706f73616c206e6f7420666f756e64766f746520676976656e20666f7220696e76616c6964207265666572656e64756d2e696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64653a205f5f5068616e746f6d4974656d2073686f756c64206e6576657220626520757365642e00003300000004000000040000002500000042725461626c65446174617461626c65330000000400000004000000d200000064656661756c744636345265696e74657270726574493634556e726561636861626c654e6f70426c6f636b00330000000400000004000000d30000004c6f6f704966456c7365456e6442724272496642725461626c650000330000000400000004000000d400000052657475726e43616c6c43616c6c496e6469726563740000330000000400000004000000d500000044726f7053656c6563744765744c6f63616c5365744c6f63616c5465654c6f63616c476574476c6f62616c536574476c6f62616c4933324c6f61644936344c6f61644633324c6f61644636344c6f61644933324c6f616438534933324c6f616438554933324c6f61643136534933324c6f61643136554936344c6f616438534936344c6f616438554936344c6f61643136534936344c6f61643136554936344c6f61643332534936344c6f616433325549333253746f726549363453746f726546333253746f726546363453746f726549333253746f72653849333253746f7265313649363453746f72653849363453746f7265313649363453746f7265333243757272656e744d656d6f727947726f774d656d6f7279493332436f6e737400330000000400000004000000d6000000493634436f6e7374330000000400000004000000d7000000463332436f6e7374463634436f6e73743300000004000000040000000900000049333245717a49333245714933324e654933324c74534933324c74554933324774534933324774554933324c65534933324c655549333247655349333247655549363445717a49363445714936344e654936344c74534936344c74554936344774534936344774554936344c65534936344c655549363447655349363447655546333245714633324e654633324c7446333247744633324c65463332476546363445714636344e654636344c7446363447744636344c654636344765493332436c7a49333243747a493332506f70636e744933324164644933325375624933324d756c493332446976534933324469765549333252656d5349333252656d55493332416e644933324f72493332586f7249333253686c4933325368725349333253687255493332526f746c493332526f7472493634436c7a49363443747a493634506f70636e744936344164644936345375624936344d756c493634446976534936344469765549363452656d5349363452656d55493634416e644936344f72493634586f7249363453686c4936345368725349363453687255493634526f746c493634526f74724633324162734633324e65674633324365696c463332466c6f6f724633325472756e634633324e656172657374463332537172744633324164644633325375624633324d756c4633324469764633324d696e4633324d6178463332436f70797369676e4636344162734636344e65674636344365696c463634466c6f6f724636345472756e634636344e656172657374463634537172744636344164644636345375624636344d756c4636344469764636344d696e4636344d6178463634436f70797369676e493332577261704936344933325472756e63534633324933325472756e63554633324933325472756e63534636344933325472756e6355463634493634457874656e6453493332493634457874656e64554933324936345472756e63534633324936345472756e63554633324936345472756e63534636344936345472756e6355463634463332436f6e7665727453493332463332436f6e7665727455493332463332436f6e7665727453493634463332436f6e766572745549363446333244656d6f7465463634463634436f6e7665727453493332463634436f6e7665727455493332463634436f6e7665727453493634463634436f6e766572745549363446363450726f6d6f74654633324933325265696e746572707265744633324936345265696e746572707265744636344633325265696e74657270726574493332496e76616c696444617461547261696c696e6744617461556e6578706563746564456f6600002c7111000b000000492f4f204572726f723a204e6f526573756c7456616c7565330000000400000004000000d80000004636344933324936344633324e6f6e65536f6d65330000000400000004000000d9000000656e7600907111005d0000001201000016000000000000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31312e302f7372632f6761732f6d6f642e72736c6173745f696e6465782069732067726561746572207468616e20303b206c6173745f696e64657820697320737461636b2073697a65202d20313b2071656470721100660000001001000017000000447211002500000043616c6c20746f2066756e6374696f6e2074686174206f75742d6f662d626f756e64733a20000000000000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31312e302f7372632f737461636b5f6865696768742f6d6f642e7273546869732073686f756c64206265206120696e646578206f66206120646566696e65642066756e6374696f6e44756520746f2076616c69646174696f6e20636f64652073656374696f6e2073686f756c642065786973747346756e6374696f6e20626f6479206973206f7574206f6620626f756e647366756e6374696f6e20696d706f727420636f756e74206973206e6f74207a65726f3b20696d706f72742073656374696f6e206d757374206578697374733b2071656466756e635f696478206973206c657373207468616e2066756e6374696f6e20696d706f72747320636f756e743b0a090909096e74682066756e6374696f6e20696d706f7274206d7573742062652060536f6d65603b0a0909090971656400f495110012000000417411000f000000147411000a0000001e74110014000000327411000f0000005369676e61747572652020287370656369666965642062792066756e6320292069736e277420646566696e6564206973206e6f7420646566696e65647372632f6c6962616c6c6f632f7665632e7273007c7411001c0000005074110013000000cc04000009000000617373657274696f6e206661696c65643a20656e64203c3d206c656e2075110048000000b1010000230000002075110048000000b201000023000000d074110049000000870200001d00000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f736f72742e7273000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e7273d0741100490000009d0000003a000000d074110049000000a4000000300000004d761100120000005f7611000c0000006066756e635f696478602073686f756c6420636f6d652066726f6d20606e6565645f7468756e6b73603b0a09090909606e6565645f7468756e6b736020697320706f70756c617465642077697468207468652073616d65206974656d73207468617420696e20607265706c6163656d656e745f6d6170603b0a090909097165644174207468697320706f696e7420616e20696e646578206d7573742062652061737369676e656420746f2065616368207468756e6b66756e6374696f6e207769746820696478202069736e277420666f756e644672616d6569735f706f6c796d6f72706869630000330000000400000004000000da000000656e645f6172697479000000330000000400000004000000250000006272616e63685f617269747973746172745f6865696768744e6f2066756e6374696f6e2073656374696f6e4e6f20636f64652073656374696f6e4e6f20747970652073656374696f6e000000e47911000a00000046756e6374696f6e206973206e6f7420666f756e6420696e2066756e632073656374696f6e46756e6374696f6e20626f647920666f722074686520696e6465782069736e277420666f756e64d87911000c000000447911000b000000737461636b206d757374206265206e6f6e2d656d70747900397911000b000000f078110006000000737461636b206f766572666c6f774172697479206f6620616c6c206a756d702d74617267657473206d75737420626520657175616c54797065206e6f7420666f756e6400e978110007000000e07711006d000000c8000000110000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31312e302f7372632f737461636b5f6865696768742f6d61785f6865696768742e72736d61785f686569676874707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768742f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31312e302f7372632f737461636b5f6865696768742f6d61785f6865696768742e72737472756e633a20707573683a2000003479110005000000747279696e6720746f20706f70206d6f72652076616c756573207468616e20707573686564737461636b20756e646572666c6f77706f703a20756e726561636861626c65706f705f6672616d653a20636f6e74726f6c20737461636b20697320656d707479636f6e74726f6c20737461636b206f75742d6f662d626f756e647390791100480000009b0a00000a0000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e7273707573685f6672616d653a2066756e635f6964783a206578745f6368696c645f73746f726167655f726f6f74206e657665722072657475726e73207533323a3a6d61785f76616c75653b2071656452756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e6753797374656d2073746174652063757272656e746c792070726576656e74732074686973207472616e73616374696f6e5472616e73616374696f6e20646f6573206e6f742068617665207265717569726564207065726d697373696f6e73496e76616c6964206f726967696e496e76616c69645472616e73616374696f6e20637573746f6d206572726f725472616e73616374696f6e20776f756c642065786861757374732074686520626c6f636b206c696d6974735472616e73616374696f6e2068617320616e20616e6369656e7420626972746820626c6f636b5472616e73616374696f6e20686173206120626164207369676e61747572655472616e73616374696f6e206973206f757464617465645472616e73616374696f6e2077696c6c2062652076616c696420696e2074686520667574757265496e6162696c69747920746f2070617920736f6d6520666565732028652e672e206163636f756e742062616c616e636520746f6f206c6f77295472616e73616374696f6e2063616c6c206973206e6f74206578706563746564556e6b6e6f776e5472616e73616374696f6e20637573746f6d206572726f72436f756c64206e6f742066696e6420616e20756e7369676e65642076616c696461746f7220666f722074686520756e7369676e6564207472616e73616374696f6e436f756c64206e6f74206c6f6f6b757020696e666f726d6174696f6e20726571756972656420746f2076616c696461746520746865207472616e73616374696f6e00a07c110019000000c07c1100500000005800000022000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f67656e657269632f6572612e727348617368206e6f7420657175616c0000387d110028000000607d1100500000008700000009000000696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64652f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d73616e64626f782f7372632f2e2e2f776974686f75745f7374642e7273387d110028000000607d1100500000009000000009000000417574686f727368697020446964536574556e636c6573426162652045706f6368496e6465784261626520417574686f726974696573426162652047656e65736973536c6f74426162652043757272656e74536c6f74426162652052616e646f6d6e65737342616265204e65787452616e646f6d6e65737342616265205365676d656e74496e6465784261626520556e646572436f6e737472756374696f6e4261626520496e697469616c697a656462616265736c6f74436f756c64206e6f74206465636f64652072657175657374656420696e686572656e742074797065214241424520696e686572656e742064617461206e6f7420666f756e64746f6f206d616e7920696e737472756374696f6e73000000f47e110024000000187f1100170000005d02000009000000547269656420746f20736872696e6b20746f2061206c61726765722063617061636974797372632f6c6962616c6c6f632f7261775f7665632e7273436f6e7472616374204761735370656e74436f6e74726163742043757272656e745363686564756c65436f6e7472616374204163636f756e74436f756e7465726761736578745f7365745f73746f726167656578745f6765745f73746f726167656578745f63616c6c6578745f696e7374616e74696174656578745f72657475726e6578745f63616c6c65726578745f616464726573736578745f6761735f70726963656578745f6761735f6c6566746578745f62616c616e63656578745f76616c75655f7472616e736665727265646578745f72616e646f6d6578745f6e6f776578745f6d696e696d756d5f62616c616e63656578745f64697370617463685f63616c6c6578745f726573746f72655f746f6578745f736372617463685f73697a656578745f736372617463685f726561646578745f736372617463685f77726974656578745f6465706f7369745f6576656e746578745f7365745f72656e745f616c6c6f77616e63656578745f72656e745f616c6c6f77616e63656578745f7072696e746c6e6578745f626c6f636b5f6e756d6265724e6f6e2d656d7074792066756e6374696f6e20626f647920657870656374656400a68111000f000000b581110002000000b7811100030000001881110030000000488111005e0000007a00000005000000617373657274696f6e206661696c65643a20636f6e746578742e6672616d655f737461636b2e69735f656d70747928292f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7761736d692d76616c69646174696f6e2d302e322e302f7372632f66756e632e7273417420696e737472756374696f6e202840293a2000008082110048000000b1010000230000008082110048000000b201000023000000598211001c0000006898110018000000e50300000d0000001082110049000000870200001d0000000000000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f736f72742e7273617373657274696f6e206661696c65643a206d6964203c3d206c656e00000000000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e727310821100490000009d0000003a0000001082110049000000a40000003000000052657475726e207479706573206c656e6774682073686f756c642062652030206f722031178511001e000000358511001f00000066756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2071656466756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2066756e6374696f6e5f73656374696f6e5f6c656e203d3d20636f64655f73656374696f6e5f6c656e3b207165640000fd8411001a000000d88411000a000000e28411001b00000073746172742066756e6374696f6e20657870656374656420746f20686176652074797065205b5d202d3e205b5d000000c784110011000000a78411002000000087841100200000005f841100280000007365676d656e74206f66667365742073686f756c642072657475726e2049333270617373697665206d656d6f7279207365676d656e747320617265206e6f7420737570706f727465647061737369766520656c656d656e74207365676d656e747320617265206e6f7420737570706f72746564746f6f206d616e79206d656d6f727920726567696f6e7320696e20696e6465782073706163653a20746f6f206d616e79207461626c657320696e20696e6465782073706163653a20747279696e6720746f20696d706f7274206d757461626c6520676c6f62616c206475706c6963617465206578706f72742046756e6374696f6e20232072656164696e672f76616c69646174696f6e206572726f723a204d697373696e6720626f647920666f722066756e6374696f6e206c656e677468206f662066756e6374696f6e2073656374696f6e206973202c207768696c65206c656e206f6620636f64652073656374696f6e2069732043616e2774206465636f6465207761736d20636f64654d6f64756c65206973206e6f742076616c69646d6f64756c65206465636c6172657320696e7465726e616c206d656d6f72796d756c7469706c65207461626c6573206465636c617265647461626c652065786365656473206d6178696d756d2073697a6520616c6c6f776564757365206f6620666c6f6174696e6720706f696e74207479706520696e2066756e6374696f6e20747970657320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e206c6f63616c7320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e20676c6f62616c7320697320666f7262696464656e67617320696e737472756d656e746174696f6e206661696c6564737461636b2068656967687420696e737472756d656e746174696f6e206661696c656463616c6c6465706c6f796465706c6f792066756e6374696f6e2069736e2774206578706f72746564756e6b6e6f776e206578706f72743a20657870656374696e67206f6e6c79206465706c6f7920616e642063616c6c2066756e6374696f6e7366756e6374696f6e206861732061206e6f6e2d6578697374656e7420747970656578706f72742072656665727320746f206e6f6e2d6578697374656e742066756e6374696f6e657870656374656420612066756e6374696f6e656e74727920706f696e7420706f696e747320746f20616e20696d706f727465642066756e6374696f6e656e74727920706f696e74206861732077726f6e67207369676e617475726563616c6c2066756e6374696f6e2069736e2774206578706f727465646572726f722073657269616c697a696e6720696e737472756d656e746564206d6f64756c6500000000000001000000020000000400000008000000100000002000000044656d6f6372616379205075626c696350726f70436f756e7444656d6f6372616379205265666572656e64756d436f756e7444656d6f6372616379204e65787454616c6c7944656d6f6372616379204c6173745461626c656457617345787465726e616c436f756e63696c20446573697265645365617473436f756e63696c20566f7465436f756e74436f756e63696c204e657874566f746572536574436f756e63696c20566f746572436f756e74436f756e63696c2043616e646964617465436f756e7454696d657374616d7020496e697469616c697a6564000000000000708911000e0000000000000080891100010000000000000000000000888911000100000000000000000000009089110006000000000000003897110000000000000000000000000098891100010000000000000000000000a0891100070000000000000038971100000000000000000000000000a889110001000000000000004e6577417574686f7269746965730000238a110023000000ff891100240000005061757365640000d889110027000000526573756d656400b0891100280000002043757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e2043757272656e7420617574686f726974792073657420686173206265656e207061757365642e204e657720617574686f726974792073657420686173206265656e206170706c6965642e5665633c28417574686f7269747949642c20417574686f72697479576569676874293e4772616e64706146696e616c69747920417574686f7269746965734772616e64706146696e616c6974792043757272656e7453657449644772616e64706146696e616c69747920536574496453657373696f6e4f6666636861696e206572726f723a206665746368696e67206e6574776f726b207374617465206661696c6564214f6666636861696e206572726f723a207369676e696e67206661696c6564214f6666636861696e206572726f723a206465636f64696e6720576f726b6572537461747573206661696c6564214f6666636861696e206572726f723a207375626d697474696e67207472616e73616374696f6e206661696c656421496d4f6e6c696e65205265636569766564486561727462656174734f6666656e636573205265706f72747342794b696e64496e6465780000000000a48b11000700000000000000ac8b1100020000000000000000000000bc8b110002000000000000004f6666656e6365006f8c110004000000738c11000e000000cc8b110055000000218c11004e00000020546865726520697320616e206f6666656e6365207265706f72746564206f662074686520676976656e20606b696e64602068617070656e656420617420746865206073657373696f6e5f696e6465786020616e6420286b696e642d7370656369666963292074696d6520736c6f742e2054686973206576656e74206973206e6f74206465706f736974656420666f72206475706c696361746520736c61736865732e4b696e644f706171756554696d65536c6f7453657373696f6e2053746f72656452616e676553657373696f6e2043757272656e74496e64657853657373696f6e205175657565644368616e67656453657373696f6e2044697361626c656456616c696461746f72730000000000048d11000a00000000000000108d1100010000000000000000000000188d110002000000000000004e657753657373696f6e00009f8d11000c000000288d1100550000007d8d110022000000204e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f742074686520626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e53657373696f6e496e64657800c08d110048000000a10a00000e000000000000002f72757374632f316464313838343839313633366430656235313135376431333732333030373662636632303632372f7372632f6c6962636f72652f736c6963652f6d6f642e72735374616b696e672056616c696461746f72436f756e745374616b696e67204d696e696d756d56616c696461746f72436f756e745374616b696e672043757272656e744572615374616b696e672043757272656e74457261537461727453657373696f6e496e6465785374616b696e672043757272656e74457261506f696e74734561726e65645374616b696e6720466f7263654572615374616b696e6720536c6173685265776172644672616374696f6e5374616b696e6720426f6e646564457261730000000000248f1100100000000000000038971100000000000000000000000000348f11000100000000000000000000003c8f11000f000000000000004c8f1100010000000000000000000000548f1100010000000000000045787472696e736963537563636573737e8f11002500000045787472696e7369634661696c656400718f11000d0000005c8f11001500000020416e2065787472696e736963206661696c65642e44697370617463684572726f7220416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e52657175697265526f6f744f726967696e526571756972655369676e65644f726967696e426c6f636b46756c6c4261645369676e617475726543616e206e6f74206c6f6f6b7570526571756972654e6f4f726967696e53797374656d2045787472696e736963436f756e7453797374656d20416c6c45787472696e7369637357656967687453797374656d20416c6c45787472696e736963734c656e53797374656d204e6578745765696768744d756c7469706c69657253797374656d2045787472696e7369634461746153797374656d204576656e74436f756e7474696d737461703054696d657374616d7020696e686572656e742064617461206973206e6f742070726f76696465642e496e76616c69642074696d657374616d7020696e686572656e74206461746120656e636f64696e672e54696d657374616d702044696455706461746554726561737572792050726f706f73616c436f756e74547265617375727920417070726f76616c736d616b655f746f705f6672616d655f706f6c796d6f72706869632069732063616c6c6564207769746820656d707479206672616d6520737461636b0000db0000000c00000004000000dc000000746869732066756e6374696f6e2063616e27742062652063616c6c6564207769746820656d707479206672616d6520737461636b4d6973706c6163656420656c736520696e737472756374696f6e0000d8921100470000001f931100050000009c92110037000000d3921100050000006a921100170000006192110009000000b29411001400000049921100180000006192110009000000b294110014000000189211001d00000035921100130000004892110001000000546f6f206c61726765206d656d6f727920616c69676e6d656e7420325e20286578706563746564206174206d6f73742029547279696e6720746f2075706461746520676c6f62616c20206f66207479706520547279696e6720746f20757064617465206c6f63616c20416e795370656369666963330000000400000004000000d80000004c6162656c7320696e2062725f7461626c6520706f696e747320746f20626c6f636b206f6620646966666572656e742074797065733a2020616e6420496620626c6f636b20776974686f757420656c736520726571756972656420746f2068617665204e6f526573756c7420626c6f636b20747970652e204275742069742068617320207479706534931100180000004c9311000b000000556e657870656374656420737461636b20686569676874202c20657870656374656420547279696e6720746f2061636365737320706172656e74206672616d6520737461636b2076616c7565732e00009493110017000000ab9311001600000045787065637465642076616c7565206f66207479706520206f6e20746f70206f6620737461636b2e20476f7420000000cc93110007000000537461636b3a20000000010056941100240000002c94110006000000329411000e000000409411001600000008941100240000002c941100060000006d6178696d756d206d656d6f72792073697a65206d757374206265206174206d6f7374202070616765736d6178696d756d206c696d697420206973206c657373207468616e206d696e696d756d20696e697469616c206d656d6f72792073697a65206d757374206265206174206d6f73742000008c94110026000000b294110014000000547279696e6720746f20696e697469616c697a65207661726961626c65206f6620747970652020776974682076616c7565206f66207479706520496e69742065787072657373696f6e2073686f756c6420616c776179732062652077697468206c656e67746820324e6f6e20636f6e7374616e74206f70636f646520696e20696e697420657870725d951100070000006f951100220000005d95110007000000649511000b00000045787072657373696f6e20646f65736e277420656e647320776974682060656e6460206f70636f6465476c6f62616c20206973206d757461626c6520646f65736e277420657869737473206f72206e6f742079657420646566696e6564000000a495110010000000b49511000f0000004d656d6f727920617420696e6465782020646f65736e27742065786973747300d49511000f000000b49511000f0000005461626c6520617420696e6465782000f495110012000000b49511000f00000046756e6374696f6e20617420696e646578200000189611000e000000b49511000f0000005479706520617420696e6465782000008696110010000000b49511000f0000005896110010000000789611000e00000058961100100000006896110010000000457870656374656420676c6f62616c2020746f20626520696d6d757461626c6520746f206265206d757461626c65476c6f62616c20617420696e646578206e6f6e2d656d70747920737461636b2065787065637465640000c096110020000000e096110012000000747279696e6720746f206765742076616c756520617420706f736974696f6e20206f6e20737461636b206f662073697a6520636865636b656420636f75706c65206f66206c696e65732061626f7665001897110015000000657863656564656420737461636b206c696d69742000000038971100000000004572726f72000000330000000400000004000000dd0000004c6f63616c732072616e6765206e6f7420696e2033322d6269742072616e67658897110022000000aa97110015000000bf97110007000000547279696e6720746f20616363657373206c6f63616c207769746820696e64657820207768656e20746865726520617265206f6e6c7920206c6f63616c730000e09711002d0000000d9811000c0000001998110003000000617373657274696f6e206661696c65643a2060286c656674203d3d20726967687429600a20206c6566743a2060602c0a2072696768743a2060603a20249811003400000064657374696e6174696f6e20616e6420736f7572636520736c69636573206861766520646966666572656e74206c656e67746873689811001800000058080000090000007372632f6c6962636f72652f736c6963652f6d6f642e7273004180b1c6000b08000000000000000000bfbb03046e616d6501b6bb03a305000e6578745f626c616b65325f323536011f6578745f6765745f616c6c6f63617465645f6368696c645f73746f7261676502176578745f636c6561725f6368696c645f73746f7261676503146578745f6765745f73746f726167655f696e746f04166578745f6b696c6c5f6368696c645f73746f7261676505156578745f7365745f6368696c645f73746f7261676506196578745f6765745f616c6c6f63617465645f73746f72616765070f6578745f7365745f73746f72616765080c6578745f74776f785f31323809116578745f636c6561725f73746f726167650a126578745f737232353531395f7665726966790b0e6578745f7072696e745f757466380c0d6578745f7072696e745f6e756d0d166578745f6368696c645f73746f726167655f726f6f740e106578745f636c6561725f7072656669780f166578745f73616e64626f785f6d656d6f72795f6e6577101b6578745f73616e64626f785f6d656d6f72795f74656172646f776e11176578745f73616e64626f785f696e7374616e746961746512126578745f73616e64626f785f696e766f6b65131d6578745f73616e64626f785f696e7374616e63655f74656172646f776e14106578745f73746f726167655f726f6f7415186578745f73746f726167655f6368616e6765735f726f6f7416126578745f656432353531395f76657269667917166578745f73616e64626f785f6d656d6f72795f67657418166578745f73616e64626f785f6d656d6f72795f736574190d6578745f7072696e745f6865781a106578745f69735f76616c696461746f721b156578745f6c6f63616c5f73746f726167655f6765741c216578745f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365741d116578745f6e6574776f726b5f73746174651e106578745f737232353531395f7369676e1f166578745f7375626d69745f7472616e73616374696f6e20156578745f6c6f63616c5f73746f726167655f73657421146578745f656432353531395f67656e657261746522146578745f737232353531395f67656e657261746523236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f74240a6578745f6d616c6c6f6325086578745f6672656526176578745f737232353531395f7075626c69635f6b657973270b6578745f74776f785f3634280c5f5f727573745f616c6c6f63290a5f5f72675f616c6c6f632a0e5f5f727573745f6465616c6c6f632b0c5f5f72675f6465616c6c6f632c0e5f5f727573745f7265616c6c6f632d0c5f5f72675f7265616c6c6f632e135f5f727573745f616c6c6f635f7a65726f65642f115f5f72675f616c6c6f635f7a65726f65643009686173685f746573743134616c6c6f633a3a7261775f7665633a3a63617061636974795f6f766572666c6f773a3a68636164633139656466653965313035353229636f72653a3a70616e69636b696e673a3a70616e69633a3a68613237623135356231613762656131643325616c6c6f633a3a666d743a3a666f726d61743a3a68373139333337636638383237333534323436636f72653a3a70616e69636b696e673a3a70616e69635f626f756e64735f636865636b3a3a68613834643033333136663462356666613523636f72653a3a666d743a3a77726974653a3a68373639626232616366663461376638613648616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a68303032666333346665303731316264303708727573745f6f6f6d382e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a6864623133323335353631653632346136393a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a68633133653134623932623865333434343a3b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a68373137336662316338303332343364353b3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68613062616630316338386562366162373c34636f72653a3a736c6963653a3a736c6963655f696e6465785f6c656e5f6661696c3a3a68656632663938626564366266373533643d4e636f72653a3a666d743a3a6e756d3a3a696d703a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f72207533323e3a3a666d743a3a68303438303937613766373038326163303e2d636f72653a3a70616e69636b696e673a3a70616e69635f666d743a3a68346637396263373939663330393733323f2f636f72653a3a666d743a3a6e756d3a3a696d703a3a666d745f7536343a3a68383932326134393263623337346536624011727573745f626567696e5f756e77696e6441313c5420617320636f72653a3a616e793a3a416e793e3a3a747970655f69643a3a68303837626662333038396434323234304235636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a68313538353734313262386634366265634343636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a77726974655f7072656669783a3a68363936303565363538343765653566304436636f72653a3a736c6963653a3a736c6963655f696e6465785f6f726465725f6661696c3a3a6835353833396665343434333633396662452c636f72653a3a666d743a3a466f726d61747465723a3a7061643a3a6862663133663132313734343633363530462e636f72653a3a7374723a3a736c6963655f6572726f725f6661696c3a3a686237366535353838326633366137346647323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6830303136373764333333316431623262484a3c636f72653a3a6f70733a3a72616e67653a3a52616e67653c4964783e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686339373033363631643132393261316649323c6368617220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68303731343665363835653563656332624a3d636f72653a3a756e69636f64653a3a626f6f6c5f747269653a3a426f6f6c547269653a3a6c6f6f6b75703a3a68616234336463613764383766373731634b49636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a68373032373631646266343866333635364c34636f72653a3a666d743a3a417267756d656e7456313a3a73686f775f7573697a653a3a68303764326632623133316361643036374d453c636f72653a3a63656c6c3a3a426f72726f774572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68326433626561393162376638333331354e483c636f72653a3a63656c6c3a3a426f72726f774d75744572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68383634373335313833373766363262364f323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6836323735643962386134343631633938502e636f72653a3a6f7074696f6e3a3a6578706563745f6661696c65643a3a683163333163613936623063653034653051303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6864396534343966646163316334353532522e636f72653a3a736c6963653a3a6d656d6368723a3a6d656d6368723a3a6839323166353536393537323230396564538001636f72653a3a7374723a3a7472616974733a3a3c696d706c20636f72653a3a736c6963653a3a536c696365496e6465783c7374723e20666f7220636f72653a3a6f70733a3a72616e67653a3a52616e67653c7573697a653e3e3a3a696e6465783a3a7b7b636c6f737572657d7d3a3a68376561353565643561313134353233665427636f72653a3a7374723a3a66726f6d5f757466383a3a68393936353463313839323463653036345530636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a683566363963313432356330613037353356533c636f72653a3a666d743a3a6275696c646572733a3a5061644164617074657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6865393736373038366566313830663239572f636f72653a3a666d743a3a57726974653a3a77726974655f636861723a3a6835376138336636353030656231663365582e636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a6835616339306139346131333230656233593a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a68306138363933663139633766366666665a3b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a68636638393338356535396637623637615b3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68383637616663663734396563326230325c3a636f72653a3a666d743a3a6275696c646572733a3a44656275675374727563743a3a6669656c643a3a68646430303731316136373965613430345d39636f72653a3a666d743a3a6275696c646572733a3a44656275675475706c653a3a6669656c643a3a68393065333464346262613566643437365e443c636f72653a3a666d743a3a417267756d656e747320617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68626634386164393337636464313931615f313c73747220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686637313733623038663233376563326360303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686530393630373933333765373636363961303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683931653862363165666339613332346262423c636f72653a3a7374723a3a557466384572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686166363337373838663261376137313063303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6833396433666631363039386537383237643e3c636f72653a3a666d743a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686464366234323235356566653732333065383c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a686365346336373635363834626464353866343c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a686463373536653930643966306231373167363c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a666c7573683a3a683533303838393235643430663439313868693c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6838653863316664626539333838346163694b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68663530663164396638316533336133346a30636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68323434346236303933336133646533306b7d7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c205230293e3a3a6465636f64653a3a68333464663538646264396436366233626c6b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68323661353531326466306130366630326d543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68376638333330366130393338636466636e2d616c6c6f633a3a7665633a3a5665633c543e3a3a72657461696e3a3a68356638643836666366306661623534356f443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683032363437663936366662386566376170443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683339393163366632303237333937323471443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a686566656166643264633364616137393472463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a683162353632313133646564343136383473543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683039636136373637663535386430666574543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683134393565336533346436663466623675543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683136303731343633646432653861656276543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683262653166343131363934633333326577543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683266353961316562306564306263356578543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683266666136396263346264313332613379543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68343634633337336136666331646362347a9f013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68383962656633636262333533326338617b543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68353335363332653631633034346136637c543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68383862356330343234613539346162647d543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68393130613036323863303037356534637e543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68613962383762393439623233386535347f753c73725f7072696d6974697665733a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68316665643862623861336335356666388001543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686337333532366633613336356262663281017f6e6f64655f72756e74696d653a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a6465636f64653a3a68333130306265306638643432366337618201543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68646332643431646231373737373966618301513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68333930383730653562343365626334618401513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68346235353034353038313230323761658501693c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6864386638303832353262313639643938860168636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a68616338303437376531623137353030658701513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68376163313434383630363561393861358801513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6838646539353166376338633363373834890130636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68303032396532383461626336653161348a01793c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a68346366353833643730356531323330398b017b3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a68373233336337366666386563623337638c017273726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a68633632613631323832356230656538308d0180013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a68363336343837393532646263326661308e017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a68626433333036616562666336626362358f01463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68653566313862323833376430363465349001793c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6834396339306230636239366136303838910185013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a667265655f62616c616e63653a3a68383966356130363566393565373865319201743c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a68643530643334363435306561343137639301723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a683833306434623064366665663163303194018d013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6d616b655f667265655f62616c616e63655f62653a3a68386234623564326136633936643835629501613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a683131363062303861386164636233646296017573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a72656d6f76653a3a6866633362376362623662393231306232970191013c73726d6c5f636f6e7472616374733a3a54726965496446726f6d506172656e74436f756e7465723c543e2061732073726d6c5f636f6e7472616374733a3a54726965496447656e657261746f723c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a747269655f69643a3a686161356339313864623663376232333398013773726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a626c6f636b5f6e756d6265723a3a68653533383938356333383936373334639901723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68363064383435646236353836623862669a017573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a68383232653933386530363765323330359b01613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68373635323739333664343963626361349c017773726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6d75746174653a3a68363839653731333562643437646538339d017773726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6d75746174653a3a68323138376639326134336161343632319e016b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68616238326334383138373537326534309f016c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830386561633136356661396637393538a001713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6864653530373162386130653734333633a101713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6835653932376533663634393764666562a201303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6836633166636332326337613565393130a301723c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6865323831616332613336303138303565a401303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6861393633376463316164363838343137a501783c73726d6c5f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6837313537343363326237386233626138a6017b3c73726d6c5f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6832626663373164323632393930636138a7017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a6839346337326433373239326630393437a80184013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a6838626464373063336465333638653932a901cd0173726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a5f494d504c5f454e434f44455f464f525f4c696e6b6167653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a4c696e6b6167653c4b65793e3e3a3a656e636f64655f746f3a3a6835333330396563306462363039336239aa01cd0173726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a5f494d504c5f454e434f44455f464f525f4c696e6b6167653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a4c696e6b6167653c4b65793e3e3a3a656e636f64655f746f3a3a6865393330353763396263376337323461ab0184013c73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a456e756d657261746f723c4b2c562c473e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6838643238373730663035386262636565ac016f73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a53746f726167654c696e6b65644d61703a3a73746f726167655f6c696e6b65645f6d61705f66696e616c5f6b65793a3a6838383431306663323634343831633764ad0184013c73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a456e756d657261746f723c4b2c562c473e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6865386566633638356136363861353930ae016f73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a53746f726167654c696e6b65644d61703a3a73746f726167655f6c696e6b65645f6d61705f66696e616c5f6b65793a3a6835313634396637613236326262653938af0184013c73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a456e756d657261746f723c4b2c562c473e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6866396432363165633964396131623766b0016f73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a53746f726167654c696e6b65644d61703a3a73746f726167655f6c696e6b65645f6d61705f66696e616c5f6b65793a3a6835356235363734623230613437653865b1017d7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c205230293e3a3a6465636f64653a3a6865373864623462383164613762393330b2013d73726d6c5f6f6666656e6365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6836363030663338636433666133303631b301743c73726d6c5f6f6666656e6365733a3a5f5f476574427974655374727563745265706f72747342794b696e64496e6465783c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831636238373936303566366365663164b4016c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6832333939613538336430656438336234b5014d73726d6c5f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a696e7374616e74696174653a3a6836623966633736373531646261363534b60181013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a6836616130363564356539663732313132b7014b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6861613261623366303331336232356636b8013173726d6c5f636f6e7472616374733a3a657865633a3a7472616e736665723a3a6837373362356236396662646161313137b9013973726d6c5f636f6e7472616374733a3a7761736d3a3a636f64655f63616368653a3a6c6f61643a3a6866323337613535386232383836373039ba01593c73726d6c5f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732073726d6c5f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a6831333937356561393739303766376236bb01783c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a6836616339326635393738306465653137bc018c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a656e737572655f63616e5f77697468647261773a3a6839626535636564373733626261363035bd0148616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6832343561663334383230376130353433be0130636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6835323765316362333634383130643564bf017f3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a6866353465663532326365346138316461c0017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6831313131303862313035626263336366c1014673726d6c5f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a63616c6c3a3a6839353866323730643039323832636563c2014273726d6c5f636f6e7472616374733a3a72656e743a3a7472795f65766963745f6f725f616e645f7061795f72656e743a3a6863336336633731646632616562646432c3013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6864633565333763353634646262616336c4013f7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6831613165646131353962323138616264c501c7013c73726d6c5f6f6666656e6365733a3a4d6f64756c653c543e2061732073725f7374616b696e675f7072696d6974697665733a3a6f6666656e63653a3a5265706f72744f6666656e63653c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c542061732073726d6c5f6f6666656e6365733a3a54726169743e3a3a4964656e74696669636174696f6e5475706c652c4f3e3e3a3a7265706f72745f6f6666656e63653a3a6832383939313265386363346166666539c6014b3c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6832633136623336633063663237386639c7016f73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6838636333303466313030626264666365c801437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6861623165653031323634626232353937c90141616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a7365617263683a3a7365617263685f747265653a3a6834353339376134376233366633383934ca01613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6863623836653530643234616238333461cb01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6831633062376138643436393335636534cc014073726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6576656e745f696e64657865643a3a6834313461616236326136396366376638cd0134636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a636f6e7461696e733a3a6863616665643431346630633236373166ce013673726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6c6f673a3a6865613866373434663735656363653135cf017e3c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a736c6173683a3a6866643562376165396361393035363832d00189013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6465706f7369745f6372656174696e673a3a6836373839333262303737623239363337d1015373725f7072696d6974697665733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a7b7b636c6f737572657d7d3a3a6838323439353335646130363233616166d2015373725f7072696d6974697665733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a7b7b636c6f737572657d7d3a3a6833333938303938366437323438633665d3014b73725f7072696d6974697665733a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3a3a696e746f5f6163636f756e743a3a6839633438346130663064333336626130d4019a0173726d6c5f7374616b696e673a3a5f494d504c5f4445434f44455f464f525f4578706f737572653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f7374616b696e673a3a4578706f737572653c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a6837393935333333636162333938616263d501483c73726d6c5f6f6666656e6365733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837303239393466376333643337643031d6015c3c73726d6c5f6f6666656e6365733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6832386366306335363565653635396665d701703c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6830373463363933373136623438643830d801303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830313735343962623362373765363161d901406e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73797374656d3a3a6838353435663263626138613161386365da01416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696e64696365733a3a6839656632383931386338356161373231db01426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f62616c616e6365733a3a6835613762623764323431326363363930dc01416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7374616b696e673a3a6861386530623037316263646566366661dd01416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73657373696f6e3a3a6837336536323763303639326138663139de01436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f64656d6f63726163793a3a6863633261336536646130336365323230df014e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636f6c6c6563746976655f496e7374616e6365313a3a6836656163653863306136333236353131e001436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f656c656374696f6e733a3a6832623263323461633638353163356334e1014e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6d656d626572736869705f496e7374616e6365313a3a6863616165316234326264323238666536e201416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6772616e6470613a3a6834613630316463343234393033386164e301426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f74726561737572793a3a6863333761653137623166353232663861e401436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636f6e7472616374733a3a6865343131326666386464386131633438e5013e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7375646f3a3a6861316434653964343230393738353039e601436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696d5f6f6e6c696e653a3a6836356133633932336635663033326535e701426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6f6666656e6365733a3a6862633937306433383331323331343235e8018d016e6f64655f72756e74696d653a3a5f494d504c5f4445434f44455f464f525f53657373696f6e4b6579733a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a53657373696f6e4b6579733e3a3a6465636f64653a3a6834616339333937656166633633346665e9018a0173726d6c5f636f6c6c6563746976653a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a6465636f64653a3a6831333130353934363139353131333335ea018b0173726d6c5f636f6e7472616374733a3a5f494d504c5f4445434f44455f464f525f5363686564756c653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6e7472616374733a3a5363686564756c653e3a3a6465636f64653a3a6834396636343234393334303165366132eb0182016e6f64655f72756e74696d653a3a5f494d504c5f454e434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a656e636f64655f746f3a3a6832373361383431636330393135346263ec01723c73725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573744974656d3c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6830376364313565343730393839633137ed018d0173726d6c5f636f6c6c6563746976653a3a5f494d504c5f454e434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a656e636f64655f746f3a3a6835626138363964316265616430313464ee018e0173726d6c5f636f6e7472616374733a3a5f494d504c5f454e434f44455f464f525f5363686564756c653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6e7472616374733a3a5363686564756c653e3a3a656e636f64655f746f3a3a6866346132356361353138616335333261ef01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6834306664363130326135353165306162f0012b616c6c6f633a3a736c6963653a3a6d657267655f736f72743a3a6833316161333833653836616137363032f10184016e6f64655f72756e74696d653a3a5f494d504c5f454e434f44455f464f525f4576656e743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a4576656e743e3a3a656e636f64655f746f3a3a6836643335653535356638613331303163f201a20173726d6c5f636f6c6c6563746976653a3a5f494d504c5f454e434f44455f464f525f5261774576656e743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6c6c6563746976653a3a5261774576656e743c486173682c4163636f756e7449642c493e3e3a3a656e636f64655f746f3a3a6834343930633836383033333235343464f301653c6e6f64655f72756e74696d653a3a43616c6c2061732073725f7072696d6974697665733a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a6830343764353632386132636561316131f401583c6e6f64655f72756e74696d653a3a43616c6c2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6838336539363263643433313230313431f501583c73726d6c5f626162653a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6830613865393037323432653436316137f601437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6862373562336361323964663636363363f7017273726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a6836313935643964653537363138303536f8013573726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a617574686f723a3a6837616231333433646161623761326263f9013973726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7265776172645f62795f6964733a3a6834663135326364303734323563613964fa01673c73726d6c5f617574686f726974795f646973636f766572793a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6862373861323639343666653063343330fb013973726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a63757272656e745f696e6465783a3a6862643032343430373930666636353431fc016f73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6863323531613265623837643836373037fd013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865363039313833643065313763373335fe013473726d6c5f696e64696365733a3a4d6f64756c653c543e3a3a656e756d5f7365743a3a6834626439326135376534613539343639ff014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a683331333837306130366564383137366380025d3c73726d6c5f636f6e7472616374733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683337653735393432376661653439323181029c0173726d6c5f74726561737572793a3a5f494d504c5f4445434f44455f464f525f50726f706f73616c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f74726561737572793a3a50726f706f73616c3c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a6862653536383862356333373963656531820291013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a736c6173685f72657365727665643a3a683935323531313561306238396239363483028a013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a726573657276653a3a6835373538346635383335346464633662840295013c73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a686361376465303135316236633762653285024a73726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a7365745f6d656d626572735f736f727465643a3a683538373630336262373262373332656386025d3c73726d6c5f656c656374696f6e733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68343237636433356333343061653264318702603c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68613438353966393862646662343236348802603c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683732373531613862373434313363383089025d3c73726d6c5f64656d6f63726163793a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68653734393864343238613132313430328a02a40173726d6c5f7374616b696e673a3a5f494d504c5f4445434f44455f464f525f5374616b696e674c65646765723a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f7374616b696e673a3a5374616b696e674c65646765723c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a68323763626335363133383261626464638b026f73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a68316232373866353234623633623030388c026f73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a68643338646665333337366133616133618d025b3c73726d6c5f7374616b696e673a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68326662643138643966363865313162638e0281013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7472616e736665723a3a68393839356531356133343461393931338f023f73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7365745f667265655f62616c616e63653a3a686338383364396561623864346264333390024373726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7365745f72657365727665645f62616c616e63653a3a686434313335333537336630653135303591025b3c73726d6c5f696e64696365733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683836643831653663633431313261616292023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a683235616265373531383235343639656293027f3c73726d6c5f696e64696365733a3a4d6f64756c653c543e2061732073726d6c5f73797374656d3a3a4f6e4e65774163636f756e743c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f6e65775f6163636f756e743a3a683233616438626236666435383861326194023873726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a686461366639373031343963386135303795023673726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6b696c6c5f73746173683a3a683130383536663739323263306461306596023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a686634613737393939303031643038636297027573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a72656d6f76653a3a6837383737326333616663356337353965980281013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a77697468647261773a3a683562396534326566383633636534646199023e73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a76657374696e675f62616c616e63653a3a68626238373339643133333535626236339a023473726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6c6f636b733a3a68333638393134633832333539393965379b02483c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68353835323237626435376637343932309c027573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a68633038636165316435373833636636349d0286013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a746f74616c5f62616c616e63653a3a68643763643637643234383134613861659e02653c73726d6c5f62616c616e6365733a3a54616b65466565733c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a68376236613935643336393266623835389f023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830653936393331313632366135383439a0023d73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6862323666653064306530393634336432a1023d73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a746f74616c5f69737375616e63653a3a6862373662663765313663613336633032a2023f73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6835653663653264363439656133316565a3026f3c73726d6c5f62616c616e6365733a3a5f5f476574427974655374727563744672656542616c616e63653c542c493e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861383137633863343936663239343566a4024873726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6834313966353063313539363139383666a5028e013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6465706f7369745f696e746f5f6578697374696e673a3a6830386464613432346263363434343536a6023c73726d6c5f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6862663230666535343038633831396532a7023e73726d6c5f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6861643765666566376438653664313064a8028c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a657874656e645f6c6f636b3a3a6862363338363539643233333631623664a90289013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7365745f6c6f636b3a3a6836396238393930643162313061313162aa028c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a756e726573657276653a3a6832313164383839393835333764303834ab02437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830666563303961653439666334326261ac023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6864663432393736333738383031613830ad023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6862353065623633303432396164376434ae024a3c73726d6c5f62616c616e6365733a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6865353039326631653139383330613864af02493c73726d6c5f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831666134356231303637653363663366b002613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6835313936613536623066393933653735b102723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6832366232363063316563313961636339b202437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6833353837313637353866383936316335b3027573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6839613865636263363866646163613530b402303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832336661343463613531383764656463b5024d636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a68373032373631646266343866333635362e323334b6024373726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6837323862643265653064663338323230b7024e73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6863643962646630323731313235383765b8029f013c73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5265706f72744c6174656e637944656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865613333313236376432326439396637b9029c013c73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a57696e646f7753697a6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865373839396264363034313435393935ba02d5017375627374726174655f636f6e73656e7375735f626162655f7072696d6974697665733a3a6469676573743a3a5f494d504c5f4445434f44455f464f525f526177426162655072654469676573743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72207375627374726174655f636f6e73656e7375735f626162655f7072696d6974697665733a3a6469676573743a3a526177426162655072654469676573743e3a3a6465636f64653a3a6831633662323537393730353733386134bb024b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6831626132303333613836643063323539bc02613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6830346361333431346265366331306336bd028c013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e2061732073725f7072696d6974697665733a3a7472616974733a3a4f6e496e697469616c697a653c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6830613231343334363663376138326632be023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831396564393438326431653338623932bf024073726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a63616e6469646174655f7265675f696e666f3a3a6831373937623930333666633766346466c0023873726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a616c6c5f766f746572733a3a6861316534646265623437323035653037c1023a73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a617070726f76616c735f6f663a3a6832306234303633356262643638613261c202960173726d6c5f656c656374696f6e733a3a5f494d504c5f4445434f44455f464f525f566f746572496e666f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f656c656374696f6e733a3a566f746572496e666f3c42616c616e63653e3e3a3a6465636f64653a3a6830316262336439643662306561626533c3024a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6836306436643261353030666463656265c4022d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6835643130393431636331373563363639c50295013c73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a6864653264326333356566393630353236c6023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835393066393834646333383132663735c7023c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6831343362643439666263383664393238c8023e73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866653130333861666166393439343565c902713c73726d6c5f656c656374696f6e733a3a5f5f4765744279746553747275637443616e646964617465436f756e743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834643433333035643361333633333334ca02713c73726d6c5f656c656374696f6e733a3a5f5f476574427974655374727563745265676973746572496e666f4f663c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837363362656236383261363832343365cb024773726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6862376137636130316332323031333132cc0299013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a564f5445525f5345545f53495a4544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866366135363965663662643639346637cd0295013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838613264656532666338373233633965ce0297013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863653338613432616462313537383438cf029e013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a496e6163746976654772616365506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866363330386163656461376137343234d00295013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4361727279436f756e7444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833653330626135303162636236366136d10294013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e6746656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864333434393535393035313936363639d20298013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a43616e646964616379426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839393639666163356137666662626663d302493c73726d6c5f656c656374696f6e733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6838393533343563316230373032343266d4023e73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a646f5f7365745f617070726f76616c733a3a6830356233326237643335643433376531d5023a73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a72656d6f76655f766f7465723a3a6864343234646366303966313037613632d602497061726974795f7363616c655f636f6465633a3a656e636f64655f617070656e643a3a657874726163745f6c656e6774685f646174613a3a6866643865656134353734643132643761d7023a73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6830316131646133303365313665336564d8023c73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6864313433326339303364323232303332d902663c73726d6c5f6772616e6470613a3a5f5f4765744279746553747275637453746174653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861633430666337353837316663386439da023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6866613262363366396564623731643938db023a73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6839336165366236373664623230343535dc023c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6835383233613635353036306435633137dd024573726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864363061643832333262393932383237de0299013c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a44454455505f4b45595f50524546495844656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861626566343565663162336261356236df02763c73726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a54776f783634436f6e6361742061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a53746f726167654861736865723e3a3a686173683a3a6830336164393834343263623061383436e002437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6866396638336564633862303663363035e102437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6839623462623063373566323965326431e2023b73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6864623530656536616665326164663166e3023d73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866303933303965666331326462656261e4024673726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6865616232643963386538373037313930e5028e013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4275726e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862376133356263656433663732633433e602870173725f7072696d6974697665733a3a5f494d504c5f454e434f44455f464f525f50657262696c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073725f7072696d6974697665733a3a50657262696c6c3e3a3a656e636f64653a3a6830306536383731383739316332643562e70295013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5370656e64506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864653636393366366136366337323939e80296013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726f706f73616c426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830656261613063366636366431356332e9023673726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a70726f706f73616c733a3a6863663030323230323662663936306562ea028a013c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e2061732073725f7072696d6974697665733a3a7472616974733a3a4f6e496e697469616c697a653c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6835333934366339396564396363636432eb023673726d6c5f626162653a3a4d6f64756c653c543e3a3a646f5f696e697469616c697a653a3a6832613837383633353631643739633635ec023373726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7374616b6572733a3a6861393931653433343637656664343439ed0286013c73726d6c5f7374616b696e673a3a4d6f64756c653c543e2061732073726d6c5f73657373696f6e3a3a4f6e53657373696f6e456e64696e673c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f73657373696f6e5f656e64696e673a3a6831616537633337663639326237646539ee023b73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a7363686564756c655f6368616e67653a3a6863663437383934313665623338366464ef023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864313234373039313533353736666336f002437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6837383364333039663738623432326336f1024b3c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6832333063333531613138336135356361f20230636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6835363637303838653535663233666638f302633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6832303361323762636366356561396333f402683c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a73697a655f68696e743a3a6832346639626639393362356461613335f5023e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6833383534363563373835376562323363f602633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6835333163646162346661313032336566f7023e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6830656136623430363665613539646464f8024273726d6c5f636f6e7472616374733a3a7761736d3a3a707265706172653a3a707265706172655f636f6e74726163743a3a6836323964316235366163326233306638f9024a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6833663662373961343438356135623362fa02437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6839303831646161613832616561363963fb026a636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653c413e20666f7220266d757420463e3a3a63616c6c5f6f6e63653a3a6833313938663239346337633037623537fc02663c73726d6c5f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732073726d6c5f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a7b7b636c6f737572657d7d3a3a6832326566363933396635303938656631fd027d3c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6761733a3a6832623037396439643933646632663439fe025273725f73616e64626f783a3a696d703a3a456e7669726f6e6d656e74446566696e6974696f6e4275696c6465723c543e3a3a6164645f686f73745f66756e633a3a6837613337346132656234333561666165ff0289013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f73746f726167653a3a6833316361656264633564353264303138800389013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6765745f73746f726167653a3a6831306431663335653165616632636130810382013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c3a3a6862623530306664353561356239323037820389013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f696e7374616e74696174653a3a6832616439353630656131333639626339830384013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72657475726e3a3a6861636564646338343232366335616233840384013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c65723a3a6834636231663539323330323861356630850385013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f616464726573733a3a6833613661303262393533303630646139860387013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f70726963653a3a6864376232663834643362623864393663870386013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f6c6566743a3a6861373962343335303839303935373465880385013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f62616c616e63653a3a686339306131366437336261366433336589038f013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f76616c75655f7472616e736665727265643a3a68336165393265656438623133313066658a0384013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72616e646f6d3a3a68643635336131613637663332626464368b0381013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6e6f773a3a68616461313738623139303562636263618c038d013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6d696e696d756d5f62616c616e63653a3a68613038303466373261376563343666378d038b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f64697370617463685f63616c6c3a3a68383035303832366164303961386335628e0388013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f726573746f72655f746f3a3a68633132333439626561366435393336308f038a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f73697a653a3a683538306530613263333566306331646490038a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f726561643a3a683663373534623336306337633265613991038b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f77726974653a3a683632343433353932626339633736616592038b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6465706f7369745f6576656e743a3a6838306238323039323537373365616633930390013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f72656e745f616c6c6f77616e63653a3a683466323433313333626532356363666194038c013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72656e745f616c6c6f77616e63653a3a6839363463323461623138626436633334950385013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7072696e746c6e3a3a686637366431396430353439356163373596038a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f626c6f636b5f6e756d6265723a3a686433623536316436376666623763643497033273725f73616e64626f783a3a696d703a3a64697370617463685f7468756e6b3a3a68386536656133346363343135383566389803ad017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f4445434f44455f464f525f547970656456616c75653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72207375627374726174655f7072696d6974697665733a3a73616e64626f783a3a547970656456616c75653e3a3a6465636f64653a3a68363636646563623130363065303136389903b0017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f454e434f44455f464f525f547970656456616c75653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72207375627374726174655f7072696d6974697665733a3a73616e64626f783a3a547970656456616c75653e3a3a656e636f64655f746f3a3a68366638396436616535373364656261659a033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68656566626338616663316366666162389b033d73726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68613865633662663666313730656535339c033f73726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68323836393939663633396233306133669d03703c73726d6c5f617574686f72736869703a3a5f5f47657442797465537472756374446964536574556e636c65733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68356131666536346139393034343766639e038a033c285475706c65456c656d656e74302c205475706c65456c656d656e74312c205475706c65456c656d656e74322c205475706c65456c656d656e74332c205475706c65456c656d656e74342c205475706c65456c656d656e74352c205475706c65456c656d656e74362c205475706c65456c656d656e74372c205475706c65456c656d656e74382c205475706c65456c656d656e74392c205475706c65456c656d656e7431302c205475706c65456c656d656e7431312c205475706c65456c656d656e7431322c205475706c65456c656d656e7431332c205475706c65456c656d656e7431342c205475706c65456c656d656e7431352c205475706c65456c656d656e7431362c205475706c65456c656d656e7431372c205475706c65456c656d656e7431382c205475706c65456c656d656e743139292061732073725f7072696d6974697665733a3a7472616974733a3a4f6e46696e616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a68326334616136396565373634306235359f037573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6835326236326535373661623038396433a0033173726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a6e6f773a3a6834363532613662336165366264626163a103443c73726d6c5f626162653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6835316562616163646438636565393939a2033973726d6c5f626162653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6838626464366437316663366336386133a303683c73726d6c5f626162653a3a5f5f4765744279746553747275637452616e646f6d6e6573733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831646266336432303235653433663633a4034273726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6832653030663433376237636334623732a50397013c73726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4578706563746564426c6f636b54696d6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834383432303533646236336462623264a60393013c73726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45706f63684475726174696f6e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866373362303132363134623132356364a7033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837346264393230333636623666316562a8033173726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a72616e646f6d3a3a6836306461326464656333373364646436a9033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861623464373335663864656363386661aa03930173726d6c5f73797374656d3a3a5f494d504c5f454e434f44455f464f525f4576656e745265636f72643a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f73797374656d3a3a4576656e745265636f72643c452c543e3e3a3a656e636f64655f746f3a3a6831323131373037393638613835333637ab0330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6836616262343766373764373233383832ac033973726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6839396533616666666131613734653864ad033b73726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6838613435343333313564303062363733ae03663c73726d6c5f73797374656d3a3a5f5f476574427974655374727563744576656e74733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837643032313739653635613738326563af03693c73726d6c5f73797374656d3a3a5f5f47657442797465537472756374426c6f636b486173683c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831343962353364336363646564316439b0036e3c73726d6c5f73797374656d3a3a5f5f4765744279746553747275637452616e646f6d4d6174657269616c3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838346564373366313834376166366434b1034473726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6834613439316239383530666636343565b2033373726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a66696e616c697a653a3a6861336164316265613362353165373663b303920173726d6c5f636f6c6c6563746976653a3a5f494d504c5f4445434f44455f464f525f566f7465733a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6c6c6563746976653a3a566f7465733c4163636f756e7449643e3e3a3a6465636f64653a3a6831666334646262316561653233396639b4034a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6865373436613266666630383837623565b5033f73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6866373435383836616563616334393835b6034173726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6831336536643135376135613433613432b7034173726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6834353831653732656334363130393330b8034273726d6c5f73797374656d3a3a436865636b5765696768743c543e3a3a636865636b5f626c6f636b5f6c656e6774683a3a6837666561303334346333386136616365b9033c73726d6c5f73797374656d3a3a436865636b5765696768743c543e3a3a636865636b5f7765696768743a3a6834326632643563336464616539323165ba03463c616c6c6f633a3a626f7865643a3a426f783c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831393764386331333362343930343066bb03473c73726d6c5f696e64696365733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831303562663766353932313861333062bc03473c73726d6c5f7374616b696e673a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831396539646437656462396264616366bd03493c73726d6c5f64656d6f63726163793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836636635383139356236626464353231be034c3c73726d6c5f6d656d626572736869703a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837323735633464666230386236643532bf03493c73726d6c5f636f6e7472616374733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6862373936623731343832366162363138c003443c73726d6c5f7375646f3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6865393938653136373161363737386139c103533c73726d6c5f617574686f726974795f646973636f766572793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837346565386530313939376239383937c203463c73726d6c5f73797374656d3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6833626664323638333734663362376338c3034c3c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837663834326331386439383539653138c4033c73726d6c5f696e64696365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6837303666626537316539373135376665c5037573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6862383665646132366239376363326534c603d80173725f7072696d6974697665733a3a7472616e73616374696f6e5f76616c69646974793a3a5f494d504c5f454e434f44455f464f525f5472616e73616374696f6e56616c69646974794572726f723a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073725f7072696d6974697665733a3a7472616e73616374696f6e5f76616c69646974793a3a5472616e73616374696f6e56616c69646974794572726f723e3a3a656e636f64655f746f3a3a6831626165383133323764396564653362c7037173726d6c5f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a696e697469616c697a655f626c6f636b3a3a6834626664366136356235623930656539c8033d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f65787465726e616c3a3a6862613562643931393264343264353735c9033b73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f7075626c69633a3a6864623438343534306330333732386561ca033d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a7265666572656e64756d5f696e666f3a3a6833333765323135653936613163383731cb033873726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a766f746572735f666f723a3a6837306138346438373431306364346230cc033573726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a766f74655f6f663a3a6831613037316366663431353331376631cd033d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a64656c6567617465645f766f7465733a3a6832663566356266663563303233643636ce033e73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a636c6561725f7265666572656e64756d3a3a6866666637373262613837616630303565cf03443c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6832616531373964653035366164666439d0037973726d6c5f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a6170706c795f65787472696e7369635f776974685f6c656e3a3a6830363363313039363438386337343964d103a5013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e2061732073725f7072696d6974697665733a3a7472616974733a3a436865636b61626c653c4c6f6f6b75703e3e3a3a636865636b3a3a6835353432373336616466623430333761d2036e3c73726d6c5f636f6e7472616374733a3a436865636b426c6f636b4761734c696d69743c543e2061732073725f7072696d6974697665733a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a6834613539353938646632343262313836d303363c5420617320636f72653a3a636f6e766572743a3a496e746f3c553e3e3a3a696e746f3a3a6832653964376331393038323734626436d4033c73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6836356634343632646235343435393338d5033e73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865636431373939313835396165306236d6034773726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864353861656165393464373762386164d70398013c73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864623734353962613435343235656461d8033f73726d6c5f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6861613637353666646431666439393661d9034173726d6c5f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6838656137343163663931396330333264da0334636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6861613934663035386431333531633466db032e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6834333461393733383437303165333236dc033c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6835653664306564386338306561613034dd03593c73725f7072696d6974697665733a3a416e795369676e61747572652061732073725f7072696d6974697665733a3a7472616974733a3a5665726966793e3a3a7665726966793a3a6865653661376232666164623063306337de033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831313330393632353863393833353939df033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831333135303466353262396465616136e0033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861656430393864653237386637643631e1033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861666432643465663565656365613936e2033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6838333637626463333564323039376438e303c40173726d6c5f636f6e7472616374733a3a5f494d504c5f454e434f44455f464f525f526177416c697665436f6e7472616374496e666f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6e7472616374733a3a526177416c697665436f6e7472616374496e666f3c436f6465486173682c42616c616e63652c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6837343039376637333530333664356132e4033873726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a6839643530626664316331393964383432e5037773726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a76616c75653a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f7261676556616c75653c543e20666f7220473e3a3a6d75746174653a3a6833393630323862623831616532396435e6033c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6865373235383163383635373736343031e7033e73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6838353138373039636366353134386634e8036b3c73726d6c5f636f6e7472616374733a3a5f5f4765744279746553747275637447617350726963653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837646161333630313731323962626161e903723c73726d6c5f636f6e7472616374733a3a5f5f4765744279746553747275637443757272656e745363686564756c653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830613432353664383239653035616630ea034773726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6839373030323763326334383864663966eb0398013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426c6f636b4761734c696d697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835326264363965373737633864653839ec0397013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d617856616c756553697a6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863653266336335666664386535346666ed0393013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178446570746844656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839373239663263633533653864316636ee0396013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a43616c6c4261736546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830613062653632333537663633303232ef0396013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a436f6e747261637446656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836643062623334363530643336623765f0039d013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5472616e73616374696f6e4279746546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861653066326564313066333062336431f1039a013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53757263686172676552657761726444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835643765346164343430313363316363f2039c013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a52656e744465706f7369744f666673657444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830653366346264376531366535323031f3039c013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53746f7261676553697a654f666673657444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836666162343733336233653630636665f4039e013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5369676e6564436c61696d48616e646963617044656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832363431363262343562363133336365f5033773726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a626172655f63616c6c3a3a6862393261343137333037323335353038f6033773726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6761735f70726963653a3a6861353534306331613131336131343632f7033e73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a63757272656e745f7363686564756c653a3a6835393231353035363931356330383436f8033873726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a726573746f72655f746f3a3a6863613537313665383565633061613434f9034573726d6c5f636f6e7472616374733a3a7761736d3a3a707265706172653a3a436f6e74726163744d6f64756c653a3a6e65773a3a6838326533383933383863653766636635fa03467061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a436f646553656374696f6e3a3a626f646965733a3a6864393864326364313131613035613531fb0348616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6865373064323632373339343561313363fc033c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a66726f6d5f6d6f64756c653a3a6834643832616331306433343833336233fd03537061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a7265736f6c76655f747970655f7265663a3a6861643034326537313830333035313963fe03a9017061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c6553636166666f6c643e20666f72207061726974795f7761736d3a3a656c656d656e74733a3a6d6f64756c653a3a4d6f64756c653e3a3a66726f6d3a3a6836643231633062653130613035343964ff0344707761736d5f7574696c733a3a6761733a3a436f756e7465723a3a66696e616c697a655f6d6574657265645f626c6f636b3a3a686362636565306234333463346631643080042d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a68656165383561343031313132353734348104507061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a707573685f66756e6374696f6e3a3a6865396131343838383163653163323132820430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a686464633764633436363333376535353783043c707761736d5f7574696c733a3a737461636b5f6865696768743a3a696e6a6563745f6c696d697465723a3a686635333865316430386135653339666384046b3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a683633316637353930306465663336646285046b3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a686536383437396137393936386537646686046f3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a686631323333633761626466646630306287049f013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a686661623762663862623438396439613888043773726d6c5f7375646f3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683535306364366435376331373164303289043973726d6c5f7375646f3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68303362303139613732626139303138328a04613c73726d6c5f7375646f3a3a5f5f476574427974655374727563744b65793c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68383731363333663133333061636665378b04a5017375627374726174655f7072696d6974697665733a3a737232353531393a3a5f494d504c5f454e434f44455f464f525f5075626c69633a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72207375627374726174655f7072696d6974697665733a3a737232353531393a3a5075626c69633e3a3a656e636f64653a3a68613163366230616563303734343431648c040c436f72655f76657273696f6e8d0412436f72655f657865637574655f626c6f636b8e04693c73725f7072696d6974697665733a3a7472616974733a3a426c616b6554776f3235362061732073725f7072696d6974697665733a3a7472616974733a3a486173683e3a3a6f7264657265645f747269655f726f6f743a3a68373739373939656532646161363861618f0415436f72655f696e697469616c697a655f626c6f636b9004114d657461646174615f6d657461646174619104483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68666533386331353361356163326164389204683c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68393131356662623533323965303964399304683c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683930613566666362353464373266346694041c426c6f636b4275696c6465725f6170706c795f65787472696e73696395041b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b960420426c6f636b4275696c6465725f696e686572656e745f65787472696e7369637397043873726d6c5f74696d657374616d703a3a657874726163745f696e686572656e745f646174613a3a686362316436643834626362643035333698041c426c6f636b4275696c6465725f636865636b5f696e686572656e7473990418426c6f636b4275696c6465725f72616e646f6d5f736565649a042b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e9b045673725f7072696d6974697665733a3a7472616e73616374696f6e5f76616c69646974793a3a56616c69645472616e73616374696f6e3a3a636f6d62696e655f776974683a3a68353736346238623566396161613662309c04214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b65729d0480013c73726d6c5f696d5f6f6e6c696e653a3a737232353531393a3a6170705f737232353531393a3a5075626c6963206173207375627374726174655f6170706c69636174696f6e5f63727970746f3a3a7472616974733a3a52756e74696d654170705075626c69633e3a3a616c6c3a3a68613834343166646339353935386136399e041e4772616e6470614170695f6772616e6470615f617574686f7269746965739f0415426162654170695f636f6e66696775726174696f6ea00421417574686f72697479446973636f766572794170695f617574686f726974696573a1041a417574686f72697479446973636f766572794170695f7369676ea2041c417574686f72697479446973636f766572794170695f766572696679a3041d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e6365a40411436f6e7472616374734170695f63616c6ca5042153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b657973a604820173726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654c696e6b65644d61703c4b2c563e20666f7220473e3a3a72656d6f76653a3a6838663434353163653739313862313333a704820173726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6c696e6b65645f6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654c696e6b65644d61703c4b2c563e20666f7220473e3a3a72656d6f76653a3a6861663431626330376265363732653261a8043a73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832383266383039373163393635623735a9043c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6830613933393034626364613731633464aa04743c73726d6c5f7374616b696e673a3a5f5f47657442797465537472756374536c6173685265776172644672616374696f6e3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830373539636563383531333663626462ab04773c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637443757272656e74457261506f696e74734561726e65643c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863346466393062396266616466383466ac04703c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637443757272656e7445726153746172743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861346332306237316637343535343862ad04683c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563745374616b6572733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834653030616266353365363433633733ae046b3c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637456616c696461746f72733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839633736316334353032636466336536af04763c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563744d696e696d756d56616c696461746f72436f756e743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861336434623962346538633532666237b0044073726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a736c61736861626c655f62616c616e63655f6f663a3a6861636135383433363936353265613265b1043273726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a626f6e6465643a3a6830636562393635626631386363616232b2044573726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6837306665313036376639643939383935b30498013c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426f6e64696e674475726174696f6e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832623535646136383130626464303061b4043773726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d616b655f7061796f75743a3a6832376631663237613230333735323861b5043973726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7570646174655f6c65646765723a3a6832376563613564613530643864656139b6044a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6866633236366266623663653230323433b7043f73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a696e6a6563745f7265666572656e64756d3a3a6866346266323835623039613038383533b8043873726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6465706f7369745f6f663a3a6833636363393431363966326232643635b9043c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6831646437343931353664623131643533ba043e73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6838336233383939373363343862666435bb046c3c73726d6c5f64656d6f63726163793a3a5f5f47657442797465537472756374426c61636b6c6973743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838623533343432616361336431616461bc046f3c73726d6c5f64656d6f63726163793a3a5f5f476574427974655374727563744e65787445787465726e616c3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837643466363231333432643433663038bd046e3c73726d6c5f64656d6f63726163793a3a5f5f4765744279746553747275637444656c65676174696f6e733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833626665323435333261616465653139be04703c73726d6c5f64656d6f63726163793a3a5f5f47657442797465537472756374446973706174636851756575653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835356135336235653738653362353537bf044773726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864666466353637383338323064313530c00497013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4c61756e6368506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865623830643136316665383833373935c104a0013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456d657267656e6379566f74696e67506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833316232323132653732363163316232c20499013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d4465706f73697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832363265623533316566353366303065c3049a013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456e6163746d656e74506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838343565333534353965616136613466c4047573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c2073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6832623431383266303634326531386431c5043573726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a646f5f766f74653a3a6834376438626636343531373064396363c604553c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832333130333466623262396161316637c704303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830376539663164633463383837333064c804303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6833613863363935663762313962666661c904303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862343766326134326533363431363234ca04443c7061726974795f7761736d3a3a696f3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6836656663396633373739323336343738cb04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6863373733386638313465306262636138cc04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6865336235353835366335366563383866cd04457061726974795f7761736d3a3a656c656d656e74733a3a7365676d656e743a3a446174615365676d656e743a3a76616c75653a3a6861333366626161653136643036353336ce04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6831613930373663633036623361623965cf04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6835653364383861646633663531633032d004553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832333362653833316563653732373563d104553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a426c6f636b5479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838376433336131303565663737663430d204303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839343630376237663435333334613836d30433636f72653a3a6f7074696f6e3a3a4f7074696f6e3c26543e3a3a636c6f6e65643a3a6833336430666462656635333766383862d404453c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c543e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6834643038393932373338626235366665d504303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839626562663532613237376634306665d60440707761736d5f7574696c733a3a737461636b5f6865696768743a3a636f6d707574655f737461636b5f636f73743a3a6832656332613464616131633336616664d704533c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a6833663135373864636638623165303366d804323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6833333964366132336633616239353839d904593c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6832303531346563626537613764663764da04613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6865646336386533623863393232303938db043f707761736d5f7574696c733a3a737461636b5f6865696768743a3a7265736f6c76655f66756e635f747970653a3a6835666661376165643139363735653632dc0430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6834383364613531306533653334653735dd0441707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a636f6d707574653a3a6830646665316537373831363437623164de0434636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6835353237373135663731363338343330df042e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6833386430383365613239326630376635e0043c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6833396131373737326563303238336633e104303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830316234393736623730636366393962e2045a3c707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a4672616d6520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837373362393934386530363033303234e30446707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a6672616d653a3a6838653765623332646462333937343230e4044b707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a706f705f76616c7565733a3a6837613665336661633565303837386131e504323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6839353333633564346536303161336562e604323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6838333065633835663931653437646439e7044e73725f696f3a3a696d703a3a6578743a3a65787465726e5f66756e6374696f6e735f686f73745f696d706c3a3a6578745f7072696e745f757466383a3a6831316330336538356431303265376435e804683c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6833643262383038376431613430623032e9046b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6861376364656439653336396133323630ea047d3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973745772697465723c492c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6835653237663566326461333132313031eb046f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6833356432333232326631633463663837ec046f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743634206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6836666134636162356466656233633936ed046c3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6861353061613066336466316663643961ee046f3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6838663538373638626466643663363436ef04793c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973743c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6830326534363637616133663639633832f0046b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6866616531383734653335636562616238f104713c7061726974795f7761736d3a3a656c656d656e74733a3a696e6465785f6d61703a3a496e6465784d61703c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6837353163336164613534326365643464f204783c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6866653634336337356161613937393331f3047c3c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6834643135366137643832646366653437f404743c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a56617255696e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6862396165303366373735323163303237f504713c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a437573746f6d53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6864383435613264366361663338313736f6044b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6833303831373966353539376166373962f7044b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6862636562656465393336303030353930f8044b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6864356438333636626133356134666363f904463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6830393432356365343637643235646564fa046f3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6835373532633363323332363061333635fb04457061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e5265616465723a3a6e65773a3a6866656161316461386338643835366362fc0486017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a3c696d706c207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a6520666f7220616c6c6f633a3a737472696e673a3a537472696e673e3a3a646573657269616c697a653a3a6832303434366565303237346466653739fd042d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6862353339623432353939316562373937fe0434636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6866623631656536316166636362646537ff042e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a683038653936383835383561383932643480053c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a683631623461353636613537323964363781053b636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a7b7b636c6f737572657d7d3a3a68343831336137356561636161653734378205323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68663961303537303266333235643366618305397761736d695f76616c69646174696f6e3a3a76616c69646174655f6d656d6f72795f747970653a3a68386330623261323731393065373038328405347761736d695f76616c69646174696f6e3a3a657870725f636f6e73745f747970653a3a683232363566313162343233326265373685054a7761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a737465703a3a68353864303463346465383638653431658605473c7761736d695f76616c69646174696f6e3a3a4572726f7220617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6837353566373166363063653234393764870537616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a683462396237323936623436336634353588053b636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a636f70795f66726f6d5f736c6963653a3a68383832353431646433666436326537318905347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f76616c75653a3a68656337393434626366663764623131668a05347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f6c6162656c3a3a68326336353735376131376361383336338b05407761736d695f76616c69646174696f6e3a3a7574696c3a3a4c6f63616c733a3a747970655f6f665f6c6f63616c3a3a68383162303837636564666462346434388c05543c7761736d695f76616c69646174696f6e3a3a66756e633a3a537461636b56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68633739643161663136313838663435368d05537761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f6c6f61643a3a68366138333538613164613464626566308e05547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f73746f72653a3a68636564333562656564653636653562628f05557761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f746573746f703a3a68616533303233333361636330633266319005547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f72656c6f703a3a68376534356165623939363562643230379105537761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f756e6f703a3a68313765386433643566626361383862399205547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f62696e6f703a3a68333830663663353461613061383264399305547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f6376746f703a3a6835353663323836383738376336363661940530636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830363931663361393762336664333466950530636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68613966613837316265643663366635309605303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68393761376132643963636263616632399705453c616c6c6f633a3a737472696e673a3a537472696e6720617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683630376665306161343865353334636298054c3c7761736d695f76616c69646174696f6e3a3a737461636b3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68653966363833643036366338313166359905066d656d7365749a05066d656d6370799b05076d656d6d6f76659c05066d656d636d709d05095f5f6173686c7469339e05095f5f6c7368727469339f05085f5f6d756c746933a005095f5f75646976746933a105095f5f756d6f64746933a2050c5f5f756469766d6f6474693400550970726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d62790105727573746325312e33392e302d6e696768746c79202831646431383834383920323031392d30392d323229", "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579730cd914acf7b89329ae59e8f7e3b8f1ee7a4f5f68d4749cca82814f2f5b1d6bbb": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797399a2fc4b1339e668345bac7e1aadd1a834b90939a4ea40b64f30433a1d475817": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0xd437fe93b0bd0a5d67d30d85d010edc2": "0x40420f00", - "0xeecb67c20ca6cc8ba4d4434687f61309": "0x103919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef01000000000000005633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce44001000000000000007932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f01000000000000009becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993320100000000000000", + "0xc98362e2ca21b342cc749022ed9b560e4d29ec9862a960c2538c314f1d279635": "0x149ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e3180973474718099c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d1268655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0x6e4ab2ac5a7cf9b1829eacc84a75bde0804be01fc31c9419ea72407f50a33384": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0x366a192e1ce90bf109f11cf4d4bdab1ce310d835c09411b1be3ad53814e33196": "0x000001547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", + "0x125dc846383907f5846f72ce53ca0e4b": "0x00ca9a3b000000000000000000000000", + "0x46cef122497fefa60faf6c66d3ef05caf9870446796ae11f0a4f734fee993d8b": "0x00", + "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b6579737f325c981c2b001f5fe8c51cc7b89e50ebb1f60feb7ab3fa3bc79d6ab71d45cb": "0x9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", + "0x71020fee971bd00e8248d1830b8cffbe5b9cf4de1ea2911a1665c44fd70ab6f3": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26630f0000c16ff286230f0000c16ff2862300", + "0xfff675c76ad8a5dfbd7db9a4e80f7c0ece595ad1878d2b6fca6086b2483a055b": "0x0000c16ff28623000000000000000000", + "0x2b334d6ac6698775ed17edf8cd3cbd9dae56cead0d69cb54f6af6aaecba544d8": "0x0ff6ffc06ff286230ff6ffc06ff2862300", + "0xdfaac108e0d4bc78fc9419a7fcfa84dc": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d6568655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde789c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0x3ae31af9a378162eb2736f26855c9ad8": "0x4545454545454545454545454545454545454545454545454545454545454545", "0x3a65787472696e7369635f696e646578": "0x00000000", - "0xa5e869ecc1b914a6b0cf5f02b874f5eb90f1739fbd3edd01e5835d1517fd9f72": "0x781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276", - "0x4e62513de81454ce76df887573f7f98b101eb4585b1485a222b7db599f4e93e2": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0e", - "0x366a192e1ce90bf109f11cf4d4bdab1ce310d835c09411b1be3ad53814e33196": "0x0c000001547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", - "0x8b4621d5f16433d6024b5a31547c59ee24e749e051dbb4bc7e64502f2a4f62fb": "0x66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f", - "0x9651d20f401bfac47731a01d6eba33b4": "0x00000000", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797346c8960f8387b17441ee2be48a0896e48d3580e922c6e1cd8f53a621370c1e49": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", "0x7e6064dc0e78ffebb59b3053826a9467": "0x109c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d1268655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0x75f6361fd25fec35714be80f2d9870af8c92e73cb6d299ba4774f5b0ad842275": "0x00", + "0xc1fdc3d212357bc2fa98f2a77b941f0c": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d6568655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde789c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797301dd273832961ca94116fd224019ea1370c0e3d27bebb1041b35651146d17832": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0x686f6c72b7b80bad8dba022335cb7c9e4556ac7ea200008da8046e3178eb89c1": "0x0ff6ffc06ff286230ff6ffc06ff2862300", + "0x2d5205eddfc20f1a616c0391abb78a3920e823abe7ed33cfd7945dd1a1bf8651": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0f", + "0x040ff70c23416b89ce6afb75ee0d362e": "0x00000000", "0x121725e2f949944d00a8c011c0db54ae07b84a6ca772adf3c65417345d91522d": "0x0000c16ff28623000000000000000000", - "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b65797394f72a73893fbd00b11fcce65a014cc5b9ff5066ec15aa6be068b4cabfe67fdb": "0x3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378", + "0x9c16fd03b96712dc0751bb0d63bc05aa": "0x00e1f505", "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973d1ae046d940202772415992434f839d8c546542e3055143c430f7eec87f7cb69": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579732c1312343dce08149336968907c27cc602536aaf7a2b105d6fa07058a3803d31": "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 fca4c78b892ee5344b4292a6359a22d7173f6b51..721fdbaf99576c11c5f7e9c24171993e36794298 100644 --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -16,28 +16,47 @@ //! Substrate chain configurations. -use primitives::{Pair, Public, crypto::UncheckedInto}; -pub use node_primitives::{AccountId, Balance}; +use chain_spec::ChainSpecExtension; +use primitives::{Pair, Public, crypto::UncheckedInto, sr25519}; +use serde::{Serialize, Deserialize}; use node_runtime::{ 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 sr_primitives::Perbill; +use im_online::sr25519::{AuthorityId as ImOnlineId}; +use sr_primitives::{traits::Verify, Perbill}; + +pub use node_primitives::{AccountId, Balance, Signature}; +pub use node_runtime::GenesisConfig; +use sr_primitives::traits::IdentifyAccount; + +type AccountPublic = ::Signer; 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")[..]) @@ -56,9 +75,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig { let initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId)> = vec![( // 5Fbsd6WXDGiLTxunqeK5BATNiocfCqu9bS1yArVjCgeBLkVy - hex!["9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12"].unchecked_into(), + hex!["9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12"].into(), // 5EnCiV7wSHeNhjW3FSUwiJNkcc2SBkPLn5Nj93FmbLtBjQUq - hex!["781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276"].unchecked_into(), + hex!["781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276"].into(), // 5Fb9ayurnxnaXj56CjmyQLBiadfRCqUbL2VWNbbe1nZU6wiC hex!["9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe9699332"].unchecked_into(), // 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8 @@ -67,9 +86,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig { hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(), ),( // 5ERawXCzCWkjVq3xz1W5KGNtVx2VdefvZ62Bw1FEuZW4Vny2 - hex!["68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78"].unchecked_into(), + hex!["68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78"].into(), // 5Gc4vr42hH1uDZc93Nayk5G7i687bAQdHHc9unLuyeawHipF - hex!["c8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e"].unchecked_into(), + hex!["c8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e"].into(), // 5EockCXN6YkiNCDjpqqnbcqd4ad35nU4RmA1ikM4YeRN4WcE hex!["7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f"].unchecked_into(), // 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ @@ -78,9 +97,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig { hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(), ),( // 5DyVtKWPidondEu8iHZgi6Ffv9yrJJ1NDNLom3X9cTDi98qp - hex!["547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65"].unchecked_into(), + hex!["547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65"].into(), // 5FeD54vGVNpFX3PndHPXJ2MDakc462vBCD5mgtWRnWYCpZU9 - hex!["9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526"].unchecked_into(), + hex!["9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526"].into(), // 5E1jLYfLdUQKrFrtqoKgFrRvxM3oQPMbf6DfcsrugZZ5Bn8d hex!["5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440"].unchecked_into(), // 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH @@ -89,9 +108,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig { hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(), ),( // 5HYZnKWe5FVZQ33ZRJK1rG3WaLMztxWrrNDb1JRwaHHVWyP9 - hex!["f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663"].unchecked_into(), + hex!["f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663"].into(), // 5EPQdAQ39WQNLCRjWsCk5jErsCitHiY5ZmjfWzzbXDoAoYbn - hex!["66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f"].unchecked_into(), + hex!["66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f"].into(), // 5DMa31Hd5u1dwoRKgC4uvqyrdK45RHv3CpwvpUC1EzuwDit4 hex!["3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef"].unchecked_into(), // 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x @@ -101,83 +120,19 @@ fn staging_testnet_config_genesis() -> GenesisConfig { )]; // generated with secret: subkey inspect "$secret"/fir - let endowed_accounts: Vec = vec![ + let root_key: AccountId = hex![ // 5Ff3iXP75ruzroPWRP2FYBHWnmGGBSb63857BgnzCoXNxfPo - hex!["9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809"].unchecked_into(), - ]; + "9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809" + ].into(); - const ENDOWMENT: Balance = 10_000_000 * DOLLARS; - const STASH: Balance = 100 * DOLLARS; + let endowed_accounts: Vec = vec![root_key.clone()]; - GenesisConfig { - system: Some(SystemConfig { - code: WASM_BINARY.to_vec(), - changes_trie_config: Default::default(), - }), - balances: Some(BalancesConfig { - balances: endowed_accounts.iter().cloned() - .map(|k| (k, ENDOWMENT)) - .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) - .collect(), - vesting: vec![], - }), - indices: Some(IndicesConfig { - ids: endowed_accounts.iter().cloned() - .chain(initial_authorities.iter().map(|x| x.0.clone())) - .collect::>(), - }), - session: Some(SessionConfig { - keys: initial_authorities.iter().map(|x| { - (x.0.clone(), session_keys(x.2.clone(), x.3.clone(), x.4.clone())) - }).collect::>(), - }), - staking: Some(StakingConfig { - current_era: 0, - validator_count: 7, - 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()), - collective_Instance1: Some(CouncilConfig { - members: vec![], - phantom: Default::default(), - }), - collective_Instance2: Some(TechnicalCommitteeConfig { - members: vec![], - phantom: Default::default(), - }), - elections: Some(ElectionsConfig { - members: vec![], - presentation_duration: 1 * DAYS, - term_duration: 28 * DAYS, - desired_seats: 0, - }), - contracts: Some(ContractsConfig { - current_schedule: Default::default(), - gas_price: 1 * MILLICENTS, - }), - sudo: Some(SudoConfig { - key: endowed_accounts[0].clone(), - }), - babe: Some(BabeConfig { - authorities: vec![], - }), - im_online: Some(ImOnlineConfig { - keys: vec![], - }), - authority_discovery: Some(AuthorityDiscoveryConfig{ - keys: vec![], - }), - grandpa: Some(GrandpaConfig { - authorities: vec![], - }), - membership_Instance1: Some(Default::default()), - } + testnet_genesis( + initial_authorities, + root_key, + Some(endowed_accounts), + false, + ) } /// Staging testnet config. @@ -191,7 +146,7 @@ pub fn staging_testnet_config() -> ChainSpec { Some(TelemetryEndpoints::new(vec![(STAGING_TELEMETRY_URL.to_string(), 0)])), None, None, - None, + Default::default(), ) } @@ -202,12 +157,18 @@ pub fn get_from_seed(seed: &str) -> ::Pu .public() } +/// Helper function to generate an account ID from seed +pub fn get_account_id_from_seed(seed: &str) -> AccountId where + AccountPublic: From<::Public> +{ + AccountPublic::from(get_from_seed::(seed)).into_account() +} /// Helper function to generate stash, controller and session key from seed pub fn get_authority_keys_from_seed(seed: &str) -> (AccountId, AccountId, GrandpaId, BabeId, ImOnlineId) { ( - get_from_seed::(&format!("{}//stash", seed)), - get_from_seed::(seed), + get_account_id_from_seed::(&format!("{}//stash", seed)), + get_account_id_from_seed::(seed), get_from_seed::(seed), get_from_seed::(seed), get_from_seed::(seed), @@ -223,38 +184,41 @@ pub fn testnet_genesis( ) -> GenesisConfig { let endowed_accounts: Vec = endowed_accounts.unwrap_or_else(|| { 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"), + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + get_account_id_from_seed::("Dave"), + get_account_id_from_seed::("Eve"), + get_account_id_from_seed::("Ferdie"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + get_account_id_from_seed::("Charlie//stash"), + get_account_id_from_seed::("Dave//stash"), + get_account_id_from_seed::("Eve//stash"), + get_account_id_from_seed::("Ferdie//stash"), ] }); const ENDOWMENT: Balance = 10_000_000 * DOLLARS; const STASH: Balance = 100 * DOLLARS; - let desired_seats = (endowed_accounts.len() / 2 - initial_authorities.len()) as u32; - GenesisConfig { system: Some(SystemConfig { code: WASM_BINARY.to_vec(), changes_trie_config: Default::default(), }), - indices: Some(IndicesConfig { - ids: endowed_accounts.clone(), - }), balances: Some(BalancesConfig { - balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(), + balances: endowed_accounts.iter().cloned() + .map(|k| (k, ENDOWMENT)) + .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) + .collect(), vesting: vec![], }), + indices: Some(IndicesConfig { + ids: endowed_accounts.iter().cloned() + .chain(initial_authorities.iter().map(|x| x.0.clone())) + .collect::>(), + }), session: Some(SessionConfig { keys: initial_authorities.iter().map(|x| { (x.0.clone(), session_keys(x.2.clone(), x.3.clone(), x.4.clone())) @@ -262,8 +226,8 @@ pub fn testnet_genesis( }), staking: Some(StakingConfig { current_era: 0, - minimum_validator_count: 1, - validator_count: 2, + validator_count: initial_authorities.len() as u32 * 2, + minimum_validator_count: initial_authorities.len() as u32, stakers: initial_authorities.iter().map(|x| { (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator) }).collect(), @@ -280,13 +244,11 @@ pub fn testnet_genesis( members: vec![], phantom: Default::default(), }), - elections: Some(ElectionsConfig { - members: endowed_accounts.iter() - .filter(|&endowed| initial_authorities.iter().find(|&(_, controller, ..)| controller == endowed).is_none()) - .map(|a| (a.clone(), 1000000)).collect(), - presentation_duration: 10, - term_duration: 1000000, - desired_seats: desired_seats, + elections_phragmen: Some(ElectionsConfig { + members: endowed_accounts.iter().take(2).cloned().collect(), + term_duration: 28 * DAYS, + desired_members: 4, + desired_runners_up: 1, }), contracts: Some(ContractsConfig { current_schedule: contracts::Schedule { @@ -311,6 +273,7 @@ pub fn testnet_genesis( authorities: vec![], }), membership_Instance1: Some(Default::default()), + treasury: Some(Default::default()), } } @@ -319,7 +282,7 @@ fn development_config_genesis() -> GenesisConfig { vec![ get_authority_keys_from_seed("Alice"), ], - get_from_seed::("Alice"), + get_account_id_from_seed::("Alice"), None, true, ) @@ -327,7 +290,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 { @@ -336,7 +308,7 @@ fn local_testnet_genesis() -> GenesisConfig { get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob"), ], - get_from_seed::("Alice"), + get_account_id_from_seed::("Alice"), None, false, ) @@ -344,21 +316,31 @@ 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( vec![ get_authority_keys_from_seed("Alice"), ], - get_from_seed::("Alice"), + get_account_id_from_seed::("Alice"), None, false, ) @@ -374,7 +356,7 @@ pub(crate) mod tests { None, None, None, - None, + Default::default(), ) } @@ -388,13 +370,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 e371aef8e0842e8bd72b47756a93c281efa460c0..48fb7b237f1e67b5a6d0613dda0c4ff362fcecac 100644 --- a/node/cli/src/factory_impl.rs +++ b/node/cli/src/factory_impl.rs @@ -23,17 +23,22 @@ 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 node_primitives::Signature; use primitives::{sr25519, crypto::Pair}; -use sr_primitives::{generic::Era, traits::{Block as BlockT, Header as HeaderT, SignedExtension}}; +use sr_primitives::{ + generic::Era, traits::{Block as BlockT, Header as HeaderT, SignedExtension, Verify, IdentifyAccount} +}; use transaction_factory::RuntimeAdapter; use transaction_factory::modes::Mode; use inherents::InherentData; use timestamp; use finality_tracker; -// TODO get via api: ::MinimumPeriod::get(). See #2587. -const MINIMUM_PERIOD: u64 = 99; +type AccountPublic = ::Signer; pub struct FactoryState { block_no: N, @@ -56,7 +61,8 @@ impl FactoryState { system::CheckEra::from(Era::mortal(256, phase)), system::CheckNonce::from(index), system::CheckWeight::new(), - balances::TakeFees::from(0) + transaction_payment::ChargeTransactionPayment::from(0), + Default::default(), ) } } @@ -147,11 +153,11 @@ impl RuntimeAdapter for FactoryState { (*amount).into() ) ) - }, key, (version, 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) @@ -162,12 +168,11 @@ impl RuntimeAdapter for FactoryState { } fn minimum_balance() -> Self::Balance { - // TODO get correct amount via api. See #2587. ExistentialDeposit::get() } fn master_account_id() -> Self::AccountId { - Keyring::Alice.pair().public() + Keyring::Alice.to_account_id() } fn master_account_secret() -> Self::Secret { @@ -177,7 +182,7 @@ impl RuntimeAdapter for FactoryState { /// Generates a random `AccountId` from `seed`. fn gen_random_account_id(seed: &Self::Number) -> Self::AccountId { let pair: sr25519::Pair = sr25519::Pair::from_seed(&gen_seed_bytes(*seed)); - pair.public().into() + AccountPublic::from(pair.public()).into_account() } /// Generates a random `Secret` from `seed`. diff --git a/node/cli/src/lib.rs b/node/cli/src/lib.rs index 4e3cfa7f0109217f81512f29fc3905e5cb1e97a2..d339952ca83ba75494ad7ea23df418ceb2b157e1 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}; @@ -108,11 +108,9 @@ pub struct FactoryCmd { #[structopt( long = "execution", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategyParam::variants()", - case_insensitive = "true", - default_value = r#""NativeElseWasm""# - ) + possible_values = &ExecutionStrategyParam::variants(), + case_insensitive = true, + default_value = "NativeElseWasm" )] pub execution: ExecutionStrategyParam, } @@ -158,8 +156,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 +172,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)?, exit ), _ => run_until_exit( runtime, - service::Factory::new_full(config).map_err(|e| format!("{:?}", e))?, + service::new_full(config)?, 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 +213,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 +227,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 7022d12d69a0f89ed61183db0aad15cd4a10d45b..78b978b72b7ac4b1ee67479f6027fa8f41f63621 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -16,305 +16,339 @@ #![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::{Service, 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 + ); - 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 _)) - }}, - - RpcExtensions = jsonrpc_core::IoHandler - { |client, pool| { - use node_rpc::accounts::{Accounts, AccountsApi}; - - let mut io = jsonrpc_core::IoHandler::default(); - io.extend_with( - AccountsApi::to_delegate(Accounts::new(client, pool)) + 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, ); - io - }}, - } + + 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(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()), + voting_rule: grandpa::VotingRulesBuilder::default().build(), + }; + // 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(), + &inherent_data_providers, + service.network(), + )?; + }, + } + + 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< + Service< + 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_runtime::{BalancesCall, Call, UncheckedExtrinsic}; + use node_primitives::{Block, DigestItem, Signature}; + use node_runtime::{BalancesCall, Call, UncheckedExtrinsic, Address}; use node_runtime::constants::{currency::CENTS, time::SLOT_DURATION}; use codec::{Encode, Decode}; - use primitives::{ - crypto::Pair as CryptoPair, blake2_256, - sr25519::Public as AddressPublic, H256, + use primitives::{crypto::Pair as CryptoPair, H256}; + use sr_primitives::{ + generic::{BlockId, Era, Digest, SignedPayload}, + traits::Block as BlockT, + traits::Verify, + OpaqueExtrinsic, }; - use sr_primitives::{generic::{BlockId, Era, Digest}, traits::Block, 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; + use sr_primitives::traits::IdentifyAccount; + + type AccountPublic = ::Signer; #[cfg(feature = "rhd")] fn test_sync() { @@ -369,8 +403,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, ); @@ -387,130 +427,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( - slot_num, - &parent_header, - &*service.client(), - (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 best_block_id = BlockId::number(service.get().client().info().chain.best_number); - let version = service.get().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); - - let raw_payload = (function, extra.clone(), version, 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: Address = AccountPublic::from(bob.public()).into_account().into(); + let from: Address = AccountPublic::from(charlie.public()).into_account().into(); + 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 payment = transaction_payment::ChargeTransactionPayment::from(0); + let extra = ( + check_version, + check_genesis, + check_era, + check_nonce, + check_weight, + payment, + 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 a9ff25890e30ab899e196748930db57a9b844375..1908443ca9519ba0fe08cbb32e14899f7e106c3e 100644 --- a/node/executor/Cargo.toml +++ b/node/executor/Cargo.toml @@ -22,6 +22,7 @@ test-client = { package = "substrate-test-client", path = "../../core/test-clien sr-primitives = { path = "../../core/sr-primitives" } runtime_support = { package = "srml-support", path = "../../srml/support" } balances = { package = "srml-balances", path = "../../srml/balances" } +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment" } session = { package = "srml-session", path = "../../srml/session" } system = { package = "srml-system", path = "../../srml/system" } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp" } @@ -29,7 +30,7 @@ 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 874c5a1b6db1c3384ba4f083fa813f04f53abe95..39727d1d5503ec8052209846f43c92ec8a8566e7 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -22,7 +22,6 @@ #[cfg(feature = "benchmarks")] extern crate test; pub use substrate_executor::NativeExecutor; -pub use substrate_executor::RuntimesCache; use substrate_executor::native_executor_instance; // Declare an instance of the native executor named `Executor`. Include the wasm binary as the @@ -30,35 +29,36 @@ 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 substrate_executor::error::Result; use super::Executor; use {balances, contracts, indices, system, timestamp}; - use runtime_io; - use substrate_executor::WasmExecutor; use codec::{Encode, Decode, Joiner}; - use runtime_support::{Hashable, StorageValue, StorageMap, assert_eq_error_rate, traits::Currency}; - use state_machine::{CodeExecutor, Externalities, TestExternalities as CoreTestExternalities}; + use runtime_support::{Hashable, StorageValue, StorageMap, traits::Currency}; + use state_machine::TestExternalities as CoreTestExternalities; use primitives::{ - twox_128, blake2_256, Blake2Hasher, NeverNativeValue, NativeOrEncoded, map + Blake2Hasher, NeverNativeValue, NativeOrEncoded, map, + traits::{CodeExecutor, Externalities}, storage::well_known_keys, + }; + use sr_primitives::{ + Fixed64, + traits::{Header as HeaderT, Hash as HashT, Convert}, ApplyResult, + transaction_validity::InvalidTransaction, weights::GetDispatchInfo, }; - use sr_primitives::traits::{Header as HeaderT, Hash as HashT, Convert}; - use sr_primitives::{ApplyOutcome, ApplyError, ApplyResult}; - use sr_primitives::weights::{WeightMultiplier, GetDispatchInfo}; use contracts::ContractAddressFor; + use substrate_executor::{NativeExecutor, WasmExecutionMethod}; use system::{EventRecord, Phase}; - use node_primitives::{Hash, BlockNumber, Balance}; use node_runtime::{ Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, BuildStorage, - System, Event, - TransferFee, TransactionBaseFee, TransactionByteFee, + System, TransactionPayment, Event, TransferFee, TransactionBaseFee, TransactionByteFee, + WeightFeeCoefficient, constants::currency::*, }; - use node_runtime::constants::currency::*; - use node_runtime::impls::WeightToFee; + use node_runtime::impls::LinearWeightToFee; + use node_primitives::{Balance, Hash, BlockNumber}; use node_testing::keyring::*; use wabt; @@ -88,17 +88,15 @@ mod tests { } /// Default transfer fee - fn transfer_fee(extrinsic: &E) -> Balance { + fn transfer_fee(extrinsic: &E, fee_multiplier: Fixed64) -> Balance { let length_fee = TransactionBaseFee::get() + TransactionByteFee::get() * (extrinsic.encode().len() as Balance); let weight = default_transfer_call().get_dispatch_info().weight; - // NOTE: this is really hard to apply, since the multiplier of each block needs to be fetched - // before the block, while we compute this after the block. - // weight = >::next_weight_multiplier().apply_to(weight); - let weight_fee = ::WeightToFee::convert(weight); - length_fee + weight_fee + TransferFee::get() + let weight_fee = ::WeightToFee::convert(weight); + + fee_multiplier.saturated_multiply_accumulate(length_fee + weight_fee) + TransferFee::get() } fn default_transfer_call() -> balances::Call { @@ -116,28 +114,52 @@ mod tests { Header::new(n, Default::default(), Default::default(), [69; 32].into(), Default::default()) } - fn executor() -> ::substrate_executor::NativeExecutor { - substrate_executor::NativeExecutor::new(None) + fn executor() -> NativeExecutor { + NativeExecutor::new(WasmExecutionMethod::Interpreted, 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())); + } + + fn executor_call< + R:Decode + Encode + PartialEq, + NC: FnOnce() -> std::result::Result + std::panic::UnwindSafe + >( + t: &mut TestExternalities, + method: &str, + data: &[u8], + use_native: bool, + native_call: Option, + ) -> (Result>, bool) { + let mut t = t.ext(); + executor().call::<_, R, NC>( + &mut t, + method, + data, + use_native, + native_call, + ) } #[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![])); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), @@ -145,7 +167,7 @@ mod tests { None, ).0; assert!(r.is_ok()); - let v = executor().call::<_, NeverNativeValue, fn() -> _>( + let v = executor_call:: _>( &mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), @@ -153,27 +175,27 @@ 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![])); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), @@ -181,7 +203,7 @@ mod tests { None, ).0; assert!(r.is_ok()); - let v = executor().call::<_, NeverNativeValue, fn() -> _>( + let v = executor_call:: _>( &mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), @@ -189,23 +211,23 @@ 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() -> _>( + let r = executor_call:: _>( &mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), @@ -213,7 +235,10 @@ mod tests { None, ).0; assert!(r.is_ok()); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + + let fm = t.execute_with(TransactionPayment::next_fee_multiplier); + + let r = executor_call:: _>( &mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), @@ -222,8 +247,8 @@ mod tests { ).0; assert!(r.is_ok()); - runtime_io::with_externalities(&mut t, || { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); + t.execute_with(|| { + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } @@ -231,17 +256,17 @@ 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() -> _>( + let r = executor_call:: _>( &mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), @@ -249,7 +274,10 @@ mod tests { None, ).0; assert!(r.is_ok()); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + + let fm = t.execute_with(TransactionPayment::next_fee_multiplier); + + let r = executor_call:: _>( &mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), @@ -258,8 +286,8 @@ mod tests { ).0; assert!(r.is_ok()); - runtime_io::with_externalities(&mut t, || { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); + t.execute_with(|| { + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } @@ -299,7 +327,7 @@ mod tests { }; // execute the block to get the real header. - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( env, "Core_initialize_block", &header.encode(), @@ -308,7 +336,7 @@ mod tests { ).0.unwrap(); for i in extrinsics.iter() { - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( env, "BlockBuilder_apply_extrinsic", &i.encode(), @@ -317,7 +345,7 @@ mod tests { ).0.unwrap(); } - let header = match executor().call::<_, NeverNativeValue, fn() -> _>( + let header = match executor_call:: _>( env, "BlockBuilder_finalize_block", &[0u8;0], @@ -421,7 +449,10 @@ mod tests { let (block1, block2) = blocks(); - executor().call::<_, NeverNativeValue, fn() -> _>( + let mut alice_last_known_balance: Balance = Default::default(); + let mut fm = t.execute_with(TransactionPayment::next_fee_multiplier); + + executor_call:: _>( &mut t, "Core_execute_block", &block1.0, @@ -429,9 +460,10 @@ mod tests { None, ).0.unwrap(); - runtime_io::with_externalities(&mut t, || { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); + t.execute_with(|| { + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); + alice_last_known_balance = Balances::total_balance(&alice()); let events = vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), @@ -456,7 +488,10 @@ mod tests { ]; assert_eq!(System::events(), events); }); - executor().call::<_, NeverNativeValue, fn() -> _>( + + fm = t.execute_with(TransactionPayment::next_fee_multiplier); + + executor_call:: _>( &mut t, "Core_execute_block", &block2.0, @@ -464,18 +499,14 @@ mod tests { None, ).0.unwrap(); - runtime_io::with_externalities(&mut t, || { - // NOTE: fees differ slightly in tests that execute more than one block due to the - // weight update. Hence, using `assert_eq_error_rate`. - assert_eq_error_rate!( + t.execute_with(|| { + assert_eq!( Balances::total_balance(&alice()), - 32 * DOLLARS - 2 * transfer_fee(&xt()), - 10_000 + alice_last_known_balance - 10 * DOLLARS - transfer_fee(&xt(), fm), ); - assert_eq_error_rate!( + assert_eq!( Balances::total_balance(&bob()), - 179 * DOLLARS - transfer_fee(&xt()), - 10_000 + 179 * DOLLARS - transfer_fee(&xt(), fm), ); let events = vec![ EventRecord { @@ -528,25 +559,41 @@ mod tests { let (block1, block2) = blocks(); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block1.0).unwrap(); + let mut alice_last_known_balance: Balance = Default::default(); + let mut fm = t.execute_with(TransactionPayment::next_fee_multiplier); - runtime_io::with_externalities(&mut t, || { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); + executor_call:: _>( + &mut t, + "Core_execute_block", + &block1.0, + false, + None, + ).0.unwrap(); + + t.execute_with(|| { + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); + alice_last_known_balance = Balances::total_balance(&alice()); }); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block2.0).unwrap(); + fm = t.execute_with(TransactionPayment::next_fee_multiplier); + + executor_call:: _>( + &mut t, + "Core_execute_block", + &block2.0, + false, + None, + ).0.unwrap(); - runtime_io::with_externalities(&mut t, || { - assert_eq_error_rate!( + t.execute_with(|| { + assert_eq!( Balances::total_balance(&alice()), - 32 * DOLLARS - 2 * transfer_fee(&xt()), - 10_000 + alice_last_known_balance - 10 * DOLLARS - transfer_fee(&xt(), fm), ); - assert_eq_error_rate!( + assert_eq!( Balances::total_balance(&bob()), - 179 * DOLLARS - 1 * transfer_fee(&xt()), - 10_000 + 179 * DOLLARS - 1 * transfer_fee(&xt(), fm), ); }); } @@ -672,7 +719,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 { @@ -691,9 +738,15 @@ 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:: _>( + &mut t, + "Core_execute_block", + &b.0, + false, + None, + ).0.unwrap(); - runtime_io::with_externalities(&mut t, || { + t.execute_with(|| { // Verify that the contract constructor worked well and code of TRANSFER contract is actually deployed. assert_eq!( &contracts::ContractInfoOf::::get(addr) @@ -709,13 +762,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.ext(), 4); + + let result = executor_call:: _>( &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) }))) } @@ -723,7 +778,7 @@ mod tests { fn native_big_block_import_succeeds() { let mut t = new_test_ext(COMPACT_CODE, false); - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block_with_size(42, 0, 120_000).0, @@ -737,7 +792,7 @@ mod tests { let mut t = new_test_ext(COMPACT_CODE, false); assert!( - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block_with_size(42, 0, 120_000).0, @@ -750,48 +805,71 @@ 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:: _>( + &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:: _>( + &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:: _>( + &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)); - - runtime_io::with_externalities(&mut t, || { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - 1 * transfer_fee(&xt())); + let fm = t.execute_with(TransactionPayment::next_fee_multiplier); + let r = executor_call:: _>( + &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"); + + t.execute_with(|| { + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - 1 * transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } @@ -803,7 +881,7 @@ mod tests { let block = Block::decode(&mut &block_data[..]).unwrap(); let mut t = new_test_ext(COMPACT_CODE, true); - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block.encode(), @@ -811,7 +889,7 @@ mod tests { None, ).0.unwrap(); - assert!(t.storage_changes_root(GENESIS_HASH.into()).unwrap().is_some()); + assert!(t.ext().storage_changes_root(GENESIS_HASH.into()).unwrap().is_some()); } #[test] @@ -819,9 +897,15 @@ 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:: _>( + &mut t, + "Core_execute_block", + &block1.0, + false, + None, + ).0.unwrap(); - assert!(t.storage_changes_root(GENESIS_HASH.into()).unwrap().is_some()); + assert!(t.ext().storage_changes_root(GENESIS_HASH.into()).unwrap().is_some()); } #[test] @@ -838,13 +922,14 @@ mod tests { #[test] - fn weight_multiplier_increases_and_decreases_on_big_weight() { + fn fee_multiplier_increases_and_decreases_on_big_weight() { let mut t = new_test_ext(COMPACT_CODE, false); - let mut prev_multiplier = WeightMultiplier::default(); + // initial fee multiplier must be zero + let mut prev_multiplier = Fixed64::from_parts(0); - runtime_io::with_externalities(&mut t, || { - assert_eq!(System::next_weight_multiplier(), prev_multiplier); + t.execute_with(|| { + assert_eq!(TransactionPayment::next_fee_multiplier(), prev_multiplier); }); let mut tt = new_test_ext(COMPACT_CODE, false); @@ -886,7 +971,7 @@ mod tests { println!("++ Block 1 size: {} / Block 2 size {}", block1.0.encode().len(), block2.0.encode().len()); // execute a big block. - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block1.0, @@ -895,15 +980,15 @@ mod tests { ).0.unwrap(); // weight multiplier is increased for next block. - runtime_io::with_externalities(&mut t, || { - let fm = System::next_weight_multiplier(); + t.execute_with(|| { + let fm = TransactionPayment::next_fee_multiplier(); println!("After a big block: {:?} -> {:?}", prev_multiplier, fm); assert!(fm > prev_multiplier); prev_multiplier = fm; }); // execute a big block. - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block2.0, @@ -912,8 +997,8 @@ mod tests { ).0.unwrap(); // weight multiplier is increased for next block. - runtime_io::with_externalities(&mut t, || { - let fm = System::next_weight_multiplier(); + t.execute_with(|| { + let fm = TransactionPayment::next_fee_multiplier(); println!("After a small block: {:?} -> {:?}", prev_multiplier, fm); assert!(fm < prev_multiplier); }); @@ -926,20 +1011,20 @@ mod tests { // weight of transfer call as of now: 1_000_000 // if weight of the cheapest weight would be 10^7, this would be 10^9, which is: // - 1 MILLICENTS in substrate node. - // - 1 milldot based on current polkadot runtime. + // - 1 milli-dot 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; @@ -948,7 +1033,7 @@ mod tests { function: Call::Balances(default_transfer_call()), }); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), @@ -957,7 +1042,7 @@ mod tests { ).0; assert!(r.is_ok()); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt.clone()), @@ -966,7 +1051,7 @@ mod tests { ).0; assert!(r.is_ok()); - runtime_io::with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(Balances::total_balance(&bob()), (10 + 69) * DOLLARS); // Components deducted from alice's balances: // - Weight fee @@ -981,7 +1066,7 @@ mod tests { balance_alice -= length_fee; let weight = default_transfer_call().get_dispatch_info().weight; - let weight_fee = WeightToFee::convert(weight); + let weight_fee = LinearWeightToFee::::convert(weight); // we know that weight to fee multiplier is effect-less in block 1. assert_eq!(weight_fee as Balance, MILLICENTS); @@ -1000,6 +1085,7 @@ mod tests { fn block_weight_capacity_report() { // Just report how many transfer calls you could fit into a block. The number should at least // be a few hundred (250 at the time of writing but can change over time). Runs until panic. + use node_primitives::Index; // execution ext. let mut t = new_test_ext(COMPACT_CODE, false); @@ -1041,7 +1127,7 @@ mod tests { len / 1024 / 1024, ); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "Core_execute_block", &block.0, @@ -1066,6 +1152,7 @@ mod tests { // Just report how big a block can get. Executes until panic. Should be ignored unless if // manually inspected. The number should at least be a few megabytes (5 at the time of // writing but can change over time). + use node_primitives::Index; // execution ext. let mut t = new_test_ext(COMPACT_CODE, false); @@ -1104,7 +1191,7 @@ mod tests { len / 1024 / 1024, ); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "Core_execute_block", &block.0, diff --git a/node/primitives/Cargo.toml b/node/primitives/Cargo.toml index 248713a8888f63ef7881b192b4deb592ad64b229..25725449a3a5a17f736a65a1c62953cc6847fc71 100644 --- a/node/primitives/Cargo.toml +++ b/node/primitives/Cargo.toml @@ -5,11 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -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", optional = true, features = ["derive"] } sr-primitives = { path = "../../core/sr-primitives", default-features = false } [dev-dependencies] @@ -19,10 +15,6 @@ pretty_assertions = "0.6.1" [features] default = ["std"] std = [ - "client/std", - "codec/std", "primitives/std", - "rstd/std", - "serde", "sr-primitives/std", ] diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index a8c045aea7c58c104bafb3df929e9b179a1ffe71..b6a5ec05655c5ff90cf4e9180ecb90b52dcd020b 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -21,21 +21,20 @@ #![cfg_attr(not(feature = "std"), no_std)] use sr_primitives::{ - generic, traits::{Verify, BlakeTwo256}, OpaqueExtrinsic, AnySignature + generic, traits::{Verify, BlakeTwo256, IdentifyAccount}, OpaqueExtrinsic, MultiSignature }; /// An index to a block. pub type BlockNumber = u32; /// Alias to 512-bit hash when used in the context of a transaction signature on the chain. -pub type Signature = AnySignature; +pub type Signature = MultiSignature; /// 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; +pub type AccountId = <::Signer as IdentifyAccount>::AccountId; -/// The type for looking up accounts. We don't expect more than 4 billion of them, but you -/// never know... +/// The type for looking up accounts. We don't expect more than 4 billion of them. pub type AccountIndex = u32; /// Balance of an account. @@ -60,17 +59,6 @@ pub type DigestItem = generic::DigestItem; /// Header type. pub type Header = generic::Header; /// Block type. -pub type Block = generic::Block; +pub type Block = generic::Block; /// Block ID. pub type BlockId = generic::BlockId; - -/// Opaque, encoded, unchecked extrinsic. -pub type UncheckedExtrinsic = OpaqueExtrinsic; - -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; - } -} diff --git a/node/rpc-client/Cargo.toml b/node/rpc-client/Cargo.toml index bc492bc00339495eb5d7816dd6b8dda804a3b1a6..e377f89359582fb4a86ce28bed569d56e4a56dec 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 = "13.0.0", features = ["http", "ws"] } -log = "0.4" +env_logger = "0.7.0" +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 index 6042380c8379feaa8f68017ea7d47f931ed92f2e..5d2ca81e0ff84fb7c5d541516d74bcc749dcb904 100644 --- a/node/rpc/Cargo.toml +++ b/node/rpc/Cargo.toml @@ -6,20 +6,9 @@ edition = "2018" [dependencies] client = { package = "substrate-client", path = "../../core/client" } -jsonrpc-core = "13.0.0" -jsonrpc-core-client = "13.0.0" -jsonrpc-derive = "13.0.0" -jsonrpc-pubsub = "13.0.0" -keyring = { package = "substrate-keyring", path = "../../core/keyring" } -log = "0.4" +jsonrpc-core = "13.2.0" node-primitives = { path = "../primitives" } -codec = { package = "parity-scale-codec", version = "1.0.0" } -serde = { version = "1.0", features = ["derive"] } sr-primitives = { path = "../../core/sr-primitives" } -substrate-primitives = { path = "../../core/primitives" } +srml-contracts-rpc = { path = "../../srml/contracts/rpc/" } +srml-system-rpc = { path = "../../srml/system/rpc/" } transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } - -[dev-dependencies] -node-testing = { path = "../testing" } -node-runtime = { path = "../runtime" } -env_logger = "0.6" diff --git a/node/rpc/src/lib.rs b/node/rpc/src/lib.rs index e25424397d6cfac11b61ff026796effdca6d8107..398d458e63a20fb0b403ae105520472483862c29 100644 --- a/node/rpc/src/lib.rs +++ b/node/rpc/src/lib.rs @@ -25,8 +25,35 @@ //! 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. +//! be placed here or imported from corresponding `SRML` RPC definitions. #![warn(missing_docs)] -pub mod accounts; +use std::sync::Arc; + +use node_primitives::{Block, AccountId, Index, Balance}; +use sr_primitives::traits::ProvideRuntimeApi; +use transaction_pool::txpool::{ChainApi, Pool}; + +/// 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: srml_system_rpc::AccountNonceApi, + C::Api: srml_contracts_rpc::ContractsRuntimeApi, + P: ChainApi + Sync + Send + 'static, + M: jsonrpc_core::Metadata + Default, +{ + use srml_system_rpc::{System, SystemApi}; + use srml_contracts_rpc::{Contracts, ContractsApi}; + + let mut io = jsonrpc_core::IoHandler::default(); + io.extend_with( + SystemApi::to_delegate(System::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 9424788e2f57a2af01bd8a7b8809734162f18535..5a6a2b6772c1e1ce0f34f112e0d95ea10e43d383 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -6,54 +6,62 @@ 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 } sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } -offchain-primitives = { package = "substrate-offchain-primitives", path = "../../core/offchain/primitives", default-features = false } -authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "../../core/authority-discovery/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 } 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 } +contracts-rpc-runtime-api = { package = "srml-contracts-rpc-runtime-api", path = "../../srml/contracts/rpc/runtime-api/", default-features = false } democracy = { package = "srml-democracy", path = "../../srml/democracy", default-features = false } -elections = { package = "srml-elections", path = "../../srml/elections", default-features = false } +elections-phragmen = { package = "srml-elections-phragmen", path = "../../srml/elections-phragmen", 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 } +randomness-collective-flip = { package = "srml-randomness-collective-flip", path = "../../srml/randomness-collective-flip", 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 } +system-rpc-runtime-api = { package = "srml-system-rpc-runtime-api", path = "../../srml/system/rpc/runtime-api/", 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 } -authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false } -offences = { package = "srml-offences", path = "../../srml/offences", 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 } +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment", default-features = false } [build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2", path = "../../core/utils/wasm-builder-runner" } +wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.4", path = "../../core/utils/wasm-builder-runner" } + +[dev-dependencies] +runtime_io = { package = "sr-io", path = "../../core/sr-io" } [features] default = ["std"] -no_std = [ - "contracts/core", -] std = [ "authority-discovery-primitives/std", "authority-discovery/std", @@ -65,8 +73,9 @@ std = [ "codec/std", "collective/std", "contracts/std", + "contracts-rpc-runtime-api/std", "democracy/std", - "elections/std", + "elections-phragmen/std", "executive/std", "finality-tracker/std", "grandpa/std", @@ -77,6 +86,7 @@ std = [ "offchain-primitives/std", "offences/std", "primitives/std", + "randomness-collective-flip/std", "rstd/std", "rustc-hex", "safe-mix/std", @@ -90,7 +100,10 @@ std = [ "sudo/std", "support/std", "system/std", + "system-rpc-runtime-api/std", "timestamp/std", "treasury/std", + "utility/std", + "transaction-payment/std", "version/std", ] diff --git a/node/runtime/build.rs b/node/runtime/build.rs index a5f22fd0171467ee714f04a3feb583137d5a890c..f5c2f98a75c8abbe2d7fa8cb16058bd0d5cea851 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.8", }, // 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 4108e66bd61d63dada1dc43e6fca77bf275c12a8..fba4c7ac79e563dc06a1fa572df726fe07fed91c 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 = 6000; + 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 = { @@ -58,19 +66,3 @@ pub mod time { pub const HOURS: BlockNumber = MINUTES * 60; pub const DAYS: BlockNumber = HOURS * 24; } - -// CRITICAL NOTE: The system module maintains two constants: a _maximum_ block weight and a -// _ratio_ of it yielding the portion which is accessible to normal transactions (reserving the rest -// for operational ones). `TARGET_BLOCK_FULLNESS` is entirely independent and the system module is -// not aware of if, nor should it care about it. This constant simply denotes on which ratio of the -// _maximum_ block weight we tweak the fees. It does NOT care about the type of the dispatch. -// -// For the system to be configured in a sane way, `TARGET_BLOCK_FULLNESS` should always be less than -// the ratio that `system` module uses to find normal transaction quota. -/// Fee-related. -pub mod fee { - pub use sr_primitives::Perbill; - - /// The block saturation level. Fees will be updates based on this value. - pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); -} diff --git a/node/runtime/src/impls.rs b/node/runtime/src/impls.rs index 2e1fcc8826e035a174d36b1bbac79cae96015c57..2e9bd38c8f822dbf6eb895ac5ceacfc0a8b86e2d 100644 --- a/node/runtime/src/impls.rs +++ b/node/runtime/src/impls.rs @@ -17,12 +17,11 @@ //! Some configurable implementations as associated type for the substrate runtime. use node_primitives::Balance; -use sr_primitives::weights::{Weight, WeightMultiplier}; +use sr_primitives::weights::Weight; use sr_primitives::traits::{Convert, Saturating}; -use sr_primitives::Fixed64; -use support::traits::{OnUnbalanced, Currency}; -use crate::{Balances, Authorship, MaximumBlockWeight, NegativeImbalance}; -use crate::constants::fee::TARGET_BLOCK_FULLNESS; +use sr_primitives::{Fixed64, Perbill}; +use support::traits::{OnUnbalanced, Currency, Get}; +use crate::{Balances, System, Authorship, MaximumBlockWeight, NegativeImbalance}; pub struct Author; impl OnUnbalanced for Author { @@ -47,48 +46,34 @@ impl Convert for CurrencyToVoteHandler { fn convert(x: u128) -> Balance { x * Self::factor() } } -/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the -/// node's balance type. -/// -/// This should typically create a mapping between the following ranges: -/// - [0, system::MaximumBlockWeight] -/// - [Balance::min, Balance::max] -/// -/// Yet, it can be used for any other sort of change to weight-fee. Some examples being: -/// - Setting it to `0` will essentially disable the weight fee. -/// - Setting it to `1` will cause the literal `#[weight = x]` values to be charged. -/// -/// By default, substrate node will have a weight range of [0, 1_000_000_000]. -pub struct WeightToFee; -impl Convert for WeightToFee { - fn convert(x: Weight) -> Balance { +/// Convert from weight to balance via a simple coefficient multiplication +/// The associated type C encapsulates a constant in units of balance per weight +pub struct LinearWeightToFee(rstd::marker::PhantomData); + +impl> Convert for LinearWeightToFee { + fn convert(w: Weight) -> Balance { // substrate-node a weight of 10_000 (smallest non-zero weight) to be mapped to 10^7 units of // fees, hence: - Balance::from(x).saturating_mul(1_000) + let coefficient = C::get(); + Balance::from(w).saturating_mul(coefficient) } } -/// A struct that updates the weight multiplier based on the saturation level of the previous block. -/// This should typically be called once per-block. -/// -/// This assumes that weight is a numeric value in the u32 range. +/// Update the given multiplier based on the following formula /// -/// Given `TARGET_BLOCK_FULLNESS = 1/2`, a block saturation greater than 1/2 will cause the system -/// fees to slightly grow and the opposite for block saturations less than 1/2. -/// -/// Formula: -/// diff = (target_weight - current_block_weight) +/// diff = (target_weight - previous_block_weight) /// v = 0.00004 /// next_weight = weight * (1 + (v . diff) + (v . diff)^2 / 2) /// +/// Where `target_weight` must be given as the `Get` implementation of the `T` generic type. /// https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#relay-chain-transaction-fees -pub struct WeightMultiplierUpdateHandler; +pub struct TargetedFeeAdjustment(rstd::marker::PhantomData); -impl Convert<(Weight, WeightMultiplier), WeightMultiplier> for WeightMultiplierUpdateHandler { - fn convert(previous_state: (Weight, WeightMultiplier)) -> WeightMultiplier { - let (block_weight, multiplier) = previous_state; +impl> Convert for TargetedFeeAdjustment { + fn convert(multiplier: Fixed64) -> Fixed64 { + let block_weight = System::all_extrinsics_weight(); let max_weight = MaximumBlockWeight::get(); - let target_weight = (TARGET_BLOCK_FULLNESS * max_weight) as u128; + let target_weight = (T::get() * max_weight) as u128; let block_weight = block_weight as u128; // determines if the first_term is positive @@ -100,8 +85,8 @@ impl Convert<(Weight, WeightMultiplier), WeightMultiplier> for WeightMultiplierU // 0.00004 = 4/100_000 = 40_000/10^9 let v = Fixed64::from_rational(4, 100_000); - // 0.00004^2 = 16/10^10 ~= 2/10^9. Taking the future /2 into account, then it is just 1 parts - // from a billionth. + // 0.00004^2 = 16/10^10 ~= 2/10^9. Taking the future /2 into account, then it is just 1 + // parts from a billionth. let v_squared_2 = Fixed64::from_rational(1, 1_000_000_000); let first_term = v.saturating_mul(diff); @@ -113,17 +98,17 @@ impl Convert<(Weight, WeightMultiplier), WeightMultiplier> for WeightMultiplierU // Note: this is merely bounded by how big the multiplier and the inner value can go, // not by any economical reasoning. let excess = first_term.saturating_add(second_term); - multiplier.saturating_add(WeightMultiplier::from_fixed(excess)) + multiplier.saturating_add(excess) } else { - // first_term > second_term + // Proof: first_term > second_term. Safe subtraction. let negative = first_term - second_term; - multiplier.saturating_sub(WeightMultiplier::from_fixed(negative)) + multiplier.saturating_sub(negative) // despite the fact that apply_to saturates weight (final fee cannot go below 0) // it is crucially important to stop here and don't further reduce the weight fee // multiplier. While at -1, it means that the network is so un-congested that all // transactions have no weight fee. We stop here and only increase if the network // became more busy. - .max(WeightMultiplier::from_rational(-1, 1)) + .max(Fixed64::from_rational(-1, 1)) } } } @@ -132,21 +117,20 @@ impl Convert<(Weight, WeightMultiplier), WeightMultiplier> for WeightMultiplierU mod tests { use super::*; use sr_primitives::weights::Weight; - use sr_primitives::Perbill; + use sr_primitives::assert_eq_error_rate; use crate::{MaximumBlockWeight, AvailableBlockRatio, Runtime}; - use crate::constants::currency::*; + use crate::{constants::currency::*, TransactionPayment, TargetBlockFullness}; fn max() -> Weight { MaximumBlockWeight::get() } fn target() -> Weight { - TARGET_BLOCK_FULLNESS * max() + TargetBlockFullness::get() * max() } // poc reference implementation. - #[allow(dead_code)] - fn weight_multiplier_update(block_weight: Weight) -> Perbill { + fn fee_multiplier_update(block_weight: Weight, previous: Fixed64) -> Fixed64 { let block_weight = block_weight as f32; let v: f32 = 0.00004; @@ -157,146 +141,225 @@ mod tests { // Current saturation in terms of weight let s = block_weight; - let fm = 1.0 + (v * (s/m - ss/m)) + (v.powi(2) * (s/m - ss/m).powi(2)) / 2.0; - // return a per-bill-like value. - let fm = if fm >= 1.0 { fm - 1.0 } else { 1.0 - fm }; - Perbill::from_parts((fm * 1_000_000_000_f32) as u32) + let fm = v * (s/m - ss/m) + v.powi(2) * (s/m - ss/m).powi(2) / 2.0; + let addition_fm = Fixed64::from_parts((fm * 1_000_000_000_f32).round() as i64); + previous.saturating_add(addition_fm) + } + + fn feemul(parts: i64) -> Fixed64 { + Fixed64::from_parts(parts) } - fn wm(parts: i64) -> WeightMultiplier { - WeightMultiplier::from_parts(parts) + fn run_with_system_weight(w: Weight, assertions: F) where F: Fn() -> () { + let mut t: runtime_io::TestExternalities = + system::GenesisConfig::default().build_storage::().unwrap().into(); + t.execute_with(|| { + System::set_block_limits(w, 0); + assertions() + }); + } + + #[test] + fn fee_multiplier_update_poc_works() { + let fm = Fixed64::from_rational(0, 1); + let test_set = vec![ + (0, fm.clone()), + (100, fm.clone()), + (target(), fm.clone()), + (max() / 2, fm.clone()), + (max(), fm.clone()), + ]; + test_set.into_iter().for_each(|(w, fm)| { + run_with_system_weight(w, || { + assert_eq_error_rate!( + fee_multiplier_update(w, fm).into_inner(), + TargetedFeeAdjustment::::convert(fm).into_inner(), + 5, + ); + }) + }) } #[test] fn empty_chain_simulation() { // just a few txs per_block. - let block_weight = 1000; - let mut wm = WeightMultiplier::default(); - let mut iterations: u64 = 0; - loop { - let next = WeightMultiplierUpdateHandler::convert((block_weight, wm)); - wm = next; - if wm == WeightMultiplier::from_rational(-1, 1) { break; } - iterations += 1; - } - println!("iteration {}, new wm = {:?}. Weight fee is now zero", iterations, wm); + let block_weight = 0; + run_with_system_weight(block_weight, || { + let mut fm = Fixed64::default(); + let mut iterations: u64 = 0; + loop { + let next = TargetedFeeAdjustment::::convert(fm); + fm = next; + if fm == Fixed64::from_rational(-1, 1) { break; } + iterations += 1; + } + println!("iteration {}, new fm = {:?}. Weight fee is now zero", iterations, fm); + assert!(iterations > 50_000, "This assertion is just a warning; Don't panic. \ + Current substrate/polkadot node are configured with a _slow adjusting fee_ \ + mechanism. Hence, it is really unlikely that fees collapse to zero even on an \ + empty chain in less than at least of couple of thousands of empty blocks. But this \ + simulation indicates that fees collapsed to zero after {} almost-empty blocks. \ + Check it", + iterations, + ); + }) } #[test] #[ignore] fn congested_chain_simulation() { // `cargo test congested_chain_simulation -- --nocapture` to get some insight. + // almost full. The entire quota of normal transactions is taken. - let block_weight = AvailableBlockRatio::get() * max(); - let tx_weight = 1000; - let mut wm = WeightMultiplier::default(); - let mut iterations: u64 = 0; - loop { - let next = WeightMultiplierUpdateHandler::convert((block_weight, wm)); - if wm == next { break; } - wm = next; - iterations += 1; - let fee = ::WeightToFee::convert(wm.apply_to(tx_weight)); - println!( - "iteration {}, new wm = {:?}. Fee at this point is: {} millicents, {} cents, {} dollars", - iterations, - wm, - fee / MILLICENTS, - fee / CENTS, - fee / DOLLARS - ); - } + let block_weight = AvailableBlockRatio::get() * max() - 100; + + // Default substrate minimum. + let tx_weight = 10_000; + + run_with_system_weight(block_weight, || { + // initial value configured on module + let mut fm = Fixed64::default(); + assert_eq!(fm, TransactionPayment::next_fee_multiplier()); + + let mut iterations: u64 = 0; + loop { + let next = TargetedFeeAdjustment::::convert(fm); + // if no change, panic. This should never happen in this case. + if fm == next { panic!("The fee should ever increase"); } + fm = next; + iterations += 1; + let fee = ::WeightToFee::convert(tx_weight); + let adjusted_fee = fm.saturated_multiply_accumulate(fee); + println!( + "iteration {}, new fm = {:?}. Fee at this point is: {} units / {} millicents, \ + {} cents, {} dollars", + iterations, + fm, + adjusted_fee, + adjusted_fee / MILLICENTS, + adjusted_fee / CENTS, + adjusted_fee / DOLLARS, + ); + } + }); } #[test] fn stateless_weight_mul() { - // Light block. Fee is reduced a little. - assert_eq!( - WeightMultiplierUpdateHandler::convert((target() / 4, WeightMultiplier::default())), - wm(-7500) - ); - // a bit more. Fee is decreased less, meaning that the fee increases as the block grows. - assert_eq!( - WeightMultiplierUpdateHandler::convert((target() / 2, WeightMultiplier::default())), - wm(-5000) - ); - // ideal. Original fee. No changes. - assert_eq!( - WeightMultiplierUpdateHandler::convert((target(), WeightMultiplier::default())), - wm(0) - ); - // // More than ideal. Fee is increased. - assert_eq!( - WeightMultiplierUpdateHandler::convert(((target() * 2), WeightMultiplier::default())), - wm(10000) - ); + run_with_system_weight(target() / 4, || { + // Light block. Fee is reduced a little. + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(-7500), + ); + }); + run_with_system_weight(target() / 2, || { + // a bit more. Fee is decreased less, meaning that the fee increases as the block grows. + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(-5000), + ); + + }); + run_with_system_weight(target(), || { + // ideal. Original fee. No changes. + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(0), + ); + }); + run_with_system_weight(target() * 2, || { + // // More than ideal. Fee is increased. + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(10000), + ); + }); } #[test] fn stateful_weight_mul_grow_to_infinity() { - assert_eq!( - WeightMultiplierUpdateHandler::convert((target() * 2, WeightMultiplier::default())), - wm(10000) - ); - assert_eq!( - WeightMultiplierUpdateHandler::convert((target() * 2, wm(10000))), - wm(20000) - ); - assert_eq!( - WeightMultiplierUpdateHandler::convert((target() * 2, wm(20000))), - wm(30000) - ); - // ... - assert_eq!( - WeightMultiplierUpdateHandler::convert((target() * 2, wm(1_000_000_000))), - wm(1_000_000_000 + 10000) - ); + run_with_system_weight(target() * 2, || { + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(10000) + ); + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(10000)), + feemul(20000) + ); + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(20000)), + feemul(30000) + ); + // ... + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(1_000_000_000)), + feemul(1_000_000_000 + 10000) + ); + }); } #[test] fn stateful_weight_mil_collapse_to_minus_one() { - assert_eq!( - WeightMultiplierUpdateHandler::convert((0, WeightMultiplier::default())), - wm(-10000) - ); - assert_eq!( - WeightMultiplierUpdateHandler::convert((0, wm(-10000))), - wm(-20000) - ); - assert_eq!( - WeightMultiplierUpdateHandler::convert((0, wm(-20000))), - wm(-30000) - ); - // ... - assert_eq!( - WeightMultiplierUpdateHandler::convert((0, wm(1_000_000_000 * -1))), - wm(-1_000_000_000) - ); + run_with_system_weight(0, || { + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(-10000) + ); + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(-10000)), + feemul(-20000) + ); + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(-20000)), + feemul(-30000) + ); + // ... + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(1_000_000_000 * -1)), + feemul(-1_000_000_000) + ); + }) } #[test] fn weight_to_fee_should_not_overflow_on_large_weights() { let kb = 1024 as Weight; let mb = kb * kb; - let max_fm = WeightMultiplier::from_fixed(Fixed64::from_natural(i64::max_value())); - - vec![0, 1, 10, 1000, kb, 10 * kb, 100 * kb, mb, 10 * mb, Weight::max_value() / 2, Weight::max_value()] - .into_iter() - .for_each(|i| { - WeightMultiplierUpdateHandler::convert((i, WeightMultiplier::default())); + let max_fm = Fixed64::from_natural(i64::max_value()); + + // check that for all values it can compute, correctly. + vec![ + 0, + 1, + 10, + 1000, + kb, + 10 * kb, + 100 * kb, + mb, + 10 * mb, + Weight::max_value() / 2, + Weight::max_value() + ].into_iter().for_each(|i| { + run_with_system_weight(i, || { + let next = TargetedFeeAdjustment::::convert(Fixed64::default()); + let truth = fee_multiplier_update(i, Fixed64::default()); + assert_eq_error_rate!(truth.into_inner(), next.into_inner(), 5); }); + }); // Some values that are all above the target and will cause an increase. let t = target(); vec![t + 100, t * 2, t * 4] .into_iter() .for_each(|i| { - let fm = WeightMultiplierUpdateHandler::convert(( - i, - max_fm - )); - // won't grow. The convert saturates everything. - assert_eq!(fm, max_fm); + run_with_system_weight(i, || { + let fm = TargetedFeeAdjustment::::convert(max_fm); + // won't grow. The convert saturates everything. + assert_eq!(fm, max_fm); + }) }); } } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index e80d5fa83ab381278c83756b2e4a45b7781694d4..3b72ff40faafc4549305566cbc30ec1b44ab0d18 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -22,46 +22,49 @@ use rstd::prelude::*; use support::{ - construct_runtime, parameter_types, traits::{SplitTwoWays, Currency} + construct_runtime, parameter_types, traits::{SplitTwoWays, Currency, Randomness} }; use primitives::u32_trait::{_1, _2, _3, _4}; use node_primitives::{ AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, Moment, Signature, }; -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; #[cfg(any(feature = "std", test))] 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; /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; -use impls::{CurrencyToVoteHandler, WeightMultiplierUpdateHandler, Author, WeightToFee}; +use impls::{CurrencyToVoteHandler, Author, LinearWeightToFee, TargetedFeeAdjustment}; /// Constant values used within the runtime. pub mod constants; @@ -80,8 +83,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: 149, - impl_version: 149, + spec_version: 184, + impl_version: 185, apis: RUNTIME_API_VERSIONS, }; @@ -106,9 +109,9 @@ pub type DealWithFees = SplitTwoWays< parameter_types! { pub const BlockHashCount: BlockNumber = 250; 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; + pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); } impl system::Trait for Runtime { @@ -121,7 +124,6 @@ impl system::Trait for Runtime { type AccountId = AccountId; type Lookup = Indices; type Header = generic::Header; - type WeightMultiplierUpdate = WeightMultiplierUpdateHandler; type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -130,6 +132,11 @@ impl system::Trait for Runtime { type Version = Version; } +impl utility::Trait for Runtime { + type Event = Event; + type Call = Call; +} + parameter_types! { pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS; pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; @@ -138,6 +145,7 @@ parameter_types! { impl babe::Trait for Runtime { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; + type EpochChangeTrigger = babe::ExternalTrigger; } impl indices::Trait for Runtime { @@ -151,8 +159,6 @@ parameter_types! { pub const ExistentialDeposit: Balance = 1 * DOLLARS; pub const TransferFee: Balance = 1 * CENTS; pub const CreationFee: Balance = 1 * CENTS; - pub const TransactionBaseFee: Balance = 1 * CENTS; - pub const TransactionByteFee: Balance = 10 * MILLICENTS; } impl balances::Trait for Runtime { @@ -160,15 +166,29 @@ impl balances::Trait for Runtime { type OnFreeBalanceZero = ((Staking, Contracts), Session); type OnNewAccount = Indices; type Event = Event; - type TransactionPayment = DealWithFees; type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; +} + +parameter_types! { + pub const TransactionBaseFee: Balance = 1 * CENTS; + pub const TransactionByteFee: Balance = 10 * MILLICENTS; + // setting this to zero will disable the weight fee. + pub const WeightFeeCoefficient: Balance = 1_000; + // for a sane configuration, this should always be less than `AvailableBlockRatio`. + pub const TargetBlockFullness: Perbill = Perbill::from_percent(25); +} + +impl transaction_payment::Trait for Runtime { + type Currency = Balances; + type OnTransactionPayment = DealWithFees; type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; - type WeightToFee = WeightToFee; + type WeightToFee = LinearWeightToFee; + type FeeMultiplierUpdate = TargetedFeeAdjustment; } parameter_types! { @@ -191,7 +211,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 { @@ -209,6 +229,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; @@ -216,9 +239,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 { @@ -226,9 +250,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: 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 { @@ -242,6 +278,7 @@ impl staking::Trait for Runtime { type SessionsPerEra = SessionsPerEra; type BondingDuration = BondingDuration; type SessionInterface = Self; + type RewardCurve = RewardCurve; } parameter_types! { @@ -290,31 +327,18 @@ impl collective::Trait for Runtime { parameter_types! { pub const CandidacyBond: Balance = 10 * DOLLARS; pub const VotingBond: Balance = 1 * DOLLARS; - pub const VotingFee: Balance = 2 * 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. - pub const InactiveGracePeriod: VoteIndex = 1; - pub const ElectionsVotingPeriod: BlockNumber = 2 * DAYS; - pub const DecayRatio: u32 = 0; } -impl elections::Trait for Runtime { +impl elections_phragmen::Trait for Runtime { type Event = Event; type Currency = Balances; - type BadPresentation = (); - type BadReaper = (); - type BadVoterIndex = (); - type LoserCandidate = (); - type ChangeMembers = Council; + type CurrencyToVote = CurrencyToVoteHandler; type CandidacyBond = CandidacyBond; type VotingBond = VotingBond; - type VotingFee = VotingFee; - type PresentSlashPerVoter = PresentSlashPerVoter; - type CarryCount = CarryCount; - type InactiveGracePeriod = InactiveGracePeriod; - type VotingPeriod = ElectionsVotingPeriod; - type DecayRatio = DecayRatio; + type LoserCandidate = (); + type BadReport = (); + type KickedMember = (); + type ChangeMembers = Council; } type TechnicalCollective = collective::Instance2; @@ -360,29 +384,36 @@ 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 Randomness = RandomnessCollectiveFlip; type Call = Call; type Event = Event; type DetermineContractAddress = contracts::SimpleAddressDeterminator; type ComputeDispatchFee = contracts::DefaultDispatchFeeComputor; type TrieIdGenerator = contracts::TrieIdFromParentCounter; type GasPayment = (); + type RentPayment = (); 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; @@ -393,12 +424,14 @@ 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; - type CurrentElectedSet = staking::CurrentElectedStashAccounts; } impl offences::Trait for Runtime { @@ -407,15 +440,17 @@ impl offences::Trait for Runtime { type OnOffenceHandler = Staking; } -impl authority_discovery::Trait for Runtime {} +impl authority_discovery::Trait for Runtime { + type AuthorityId = BabeId; +} impl grandpa::Trait for Runtime { type Event = Event; } 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 { @@ -424,6 +459,36 @@ impl finality_tracker::Trait for Runtime { type ReportLatency = ReportLatency; } +impl system::offchain::CreateTransaction for Runtime { + type Public = ::Signer; + type Signature = Signature; + + fn create_transaction>( + call: Call, + public: Self::Public, + 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(), + transaction_payment::ChargeTransactionPayment::::from(tip), + Default::default(), + ); + let raw_payload = SignedPayload::new(call, extra).ok()?; + let signature = F::sign(public, &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, @@ -431,26 +496,29 @@ 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}, + TransactionPayment: transaction_payment::{Module, Storage}, Staking: staking::{default, OfflineWorker}, Session: session::{Module, Call, Storage, Event, Config}, Democracy: democracy::{Module, Call, Storage, Config, Event}, Council: collective::::{Module, Call, Storage, Origin, Event, Config}, TechnicalCommittee: collective::::{Module, Call, Storage, Origin, Event, Config}, - Elections: elections::{Module, Call, Storage, Event, Config}, + Elections: elections_phragmen::{Module, Call, Storage, Event, Config}, TechnicalMembership: membership::::{Module, Call, Storage, Event, Config}, FinalityTracker: finality_tracker::{Module, Call, Inherent}, Grandpa: grandpa::{Module, Call, Storage, Config, Event}, - Treasury: treasury::{Module, Call, Storage, Event}, + Treasury: treasury::{Module, Call, Storage, Config, Event}, Contracts: contracts, Sudo: sudo, - ImOnline: im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, - AuthorityDiscovery: authority_discovery::{Module, Call, Config}, + ImOnline: im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, + AuthorityDiscovery: authority_discovery::{Module, Call, Config}, Offences: offences::{Module, Call, Storage, Event}, + RandomnessCollectiveFlip: randomness_collective_flip::{Module, Call, Storage}, } ); @@ -471,10 +539,13 @@ pub type SignedExtra = ( system::CheckEra, system::CheckNonce, system::CheckWeight, - balances::TakeFees + transaction_payment::ChargeTransactionPayment, + 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. @@ -519,7 +590,7 @@ impl_runtime_apis! { } fn random_seed() -> ::Hash { - System::random_seed() + RandomnessCollectiveFlip::random_seed() } } @@ -536,72 +607,91 @@ 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), - } - } - - fn epoch() -> babe_primitives::Epoch { - babe_primitives::Epoch { - start_slot: Babe::epoch_start_slot(), - authorities: Babe::authorities(), - epoch_index: Babe::epoch_index(), + epoch_length: EpochDuration::get(), + c: PRIMARY_PROBABILITY, + genesis_authorities: Babe::authorities(), randomness: Babe::randomness(), - duration: EpochDuration::get(), - secondary_slots: Babe::secondary_slots().0, + secondary_slots: true, } } } - impl authority_discovery_primitives::AuthorityDiscoveryApi for Runtime { - fn authority_id() -> Option { - AuthorityDiscovery::authority_id() - } - fn authorities() -> Vec { - AuthorityDiscovery::authorities() + impl authority_discovery_primitives::AuthorityDiscoveryApi for Runtime { + fn authorities() -> Vec { + AuthorityDiscovery::authorities().into_iter() + .map(|id| id.encode()) + .map(EncodedAuthorityId) + .collect() } - fn sign(payload: Vec, authority_id: im_online::AuthorityId) -> Option> { - AuthorityDiscovery::sign(payload, authority_id) + fn sign(payload: &Vec) -> Option<(EncodedSignature, EncodedAuthorityId)> { + AuthorityDiscovery::sign(payload).map(|(sig, id)| { + (EncodedSignature(sig.encode()), EncodedAuthorityId(id.encode())) + }) } - fn verify(payload: Vec, signature: Vec, public_key: im_online::AuthorityId) -> bool { - AuthorityDiscovery::verify(payload, signature, public_key) + 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 { + impl system_rpc_runtime_api::AccountNonceApi for Runtime { fn account_nonce(account: AccountId) -> Index { System::account_nonce(account) } } + impl contracts_rpc_runtime_api::ContractsApi for Runtime { + fn call( + origin: AccountId, + dest: AccountId, + value: Balance, + gas_limit: u64, + input_data: Vec, + ) -> contracts_rpc_runtime_api::ContractExecResult { + use contracts_rpc_runtime_api::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, + } + } + } + impl substrate_session::SessionKeys for Runtime { fn generate_session_keys(seed: Option>) -> Vec { let seed = seed.as_ref().map(|s| rstd::str::from_utf8(&s).expect("Seed is an utf8 string")); @@ -609,3 +699,24 @@ impl_runtime_apis! { } } } +#[cfg(test)] +mod tests { + use super::*; + use system::offchain::SubmitSignedTransaction; + + fn is_submit_signed_transaction(_arg: T) where + T: SubmitSignedTransaction< + Runtime, + Call, + Extrinsic=UncheckedExtrinsic, + CreateTransaction=Runtime, + Signer=ImOnlineId, + >, + {} + + #[test] + fn validate_bounds() { + let x = SubmitTransaction::default(); + is_submit_signed_transaction(x); + } +} diff --git a/node/src/main.rs b/node/src/main.rs index ca4a6b4c601de658896d0d9dbc43f006c2462ca7..9f76cf638c9641edfea85e73bba63bbf9ae6ee6f 100644 --- a/node/src/main.rs +++ b/node/src/main.rs @@ -43,7 +43,7 @@ impl cli::IntoExit for Exit { } } -fn main() { +fn main() -> Result<(), cli::error::Error> { let version = VersionInfo { name: "Substrate Node", commit: env!("VERGEN_SHA_SHORT"), @@ -54,8 +54,5 @@ fn main() { support_url: "https://github.com/paritytech/substrate/issues/new", }; - if let Err(e) = cli::run(::std::env::args(), Exit, version) { - eprintln!("Fatal error: {}\n\n{:?}", e, e); - std::process::exit(1) - } + cli::run(std::env::args(), Exit, version) } diff --git a/node/testing/Cargo.toml b/node/testing/Cargo.toml index 7f473d1be9b5042f64a5410a50b2656a1598c57a..8a4c08ed11bd2e53d0d844cd0fb64f721858dba1 100644 --- a/node/testing/Cargo.toml +++ b/node/testing/Cargo.toml @@ -27,4 +27,5 @@ 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.7.4" +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment" } +wabt = "0.9.2" diff --git a/node/testing/src/genesis.rs b/node/testing/src/genesis.rs index 35ff93d1a69ae65797a2bca6d592bc65e0e474bd..5220d1774be897218ea453439d2dde22b4d7c7db 100644 --- a/node/testing/src/genesis.rs +++ b/node/testing/src/genesis.rs @@ -94,7 +94,8 @@ pub fn config(support_changes_trie: bool, code: Option<&[u8]>) -> GenesisConfig collective_Instance1: Some(Default::default()), collective_Instance2: Some(Default::default()), membership_Instance1: Some(Default::default()), - elections: Some(Default::default()), + elections_phragmen: Some(Default::default()), sudo: Some(Default::default()), + treasury: Some(Default::default()), } } diff --git a/node/testing/src/keyring.rs b/node/testing/src/keyring.rs index 12a3e7c2d4d43e445ec94b914dff8f1ba0d82784..ca44a53880fc1f661443987406e6158e2a8778aa 100644 --- a/node/testing/src/keyring.rs +++ b/node/testing/src/keyring.rs @@ -23,9 +23,7 @@ use sr_primitives::generic::Era; use codec::Encode; /// Alice's account id. -pub fn alice() -> AccountId { - AccountKeyring::Alice.into() -} +pub fn alice() -> AccountId { AccountKeyring::Alice.into() } /// Bob's account id. pub fn bob() -> AccountId { @@ -72,7 +70,8 @@ pub fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra { system::CheckEra::from(Era::mortal(256, 0)), system::CheckNonce::from(nonce), system::CheckWeight::new(), - balances::TakeFees::from(extra_fee) + transaction_payment::ChargeTransactionPayment::from(extra_fee), + Default::default(), ) } @@ -81,7 +80,7 @@ pub fn sign(xt: CheckedExtrinsic, version: u32, genesis_hash: [u8; 32]) -> Unche 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 key = AccountKeyring::from_account_id(&signed).unwrap(); let signature = payload.using_encoded(|b| { if b.len() > 256 { key.sign(&sr_io::blake2_256(b)) 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/gitlab/check_runtime.sh b/scripts/gitlab/check_runtime.sh index 725c5077c56494838ba283a59bddf991585bbdef..cd988718d05db52814bf107e15a7e6c63038b0ee 100755 --- a/scripts/gitlab/check_runtime.sh +++ b/scripts/gitlab/check_runtime.sh @@ -32,7 +32,7 @@ github_label () { # check if the wasm sources changed if ! git diff --name-only origin/master...${CI_COMMIT_SHA} \ - | grep -q -e '^node/src/runtime' -e '^srml/' -e '^core/sr-' + | grep -q -e '^node/src/runtime' -e '^srml/' -e '^core/sr-' | grep -v -e '^core/sr-arithmetic/fuzzer' then cat <<-EOT diff --git a/scripts/init.sh b/scripts/init.sh index cf5ecf97926fea7a5e8fd2a91df96853f90e8ee7..1405a41ef333e6af863080d83f854d3edb5fb4fa 100755 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -10,7 +10,3 @@ if [ -z $CI_PROJECT_NAME ] ; then fi rustup target add wasm32-unknown-unknown --toolchain nightly - -# Install wasm-gc. It's useful for stripping slimming down wasm binaries. -command -v wasm-gc || \ - cargo +nightly install --git https://github.com/alexcrichton/wasm-gc --force diff --git a/scripts/node-template-release/Cargo.toml b/scripts/node-template-release/Cargo.toml index 34aadc971f1aaa78b2f53860e668d294cee52eb0..8a43435b20d83be0f69007eedb6888acbc2c3282 100644 --- a/scripts/node-template-release/Cargo.toml +++ b/scripts/node-template-release/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" toml = "0.4" tar = "0.4" glob = "0.2" -structopt = "0.2" +structopt = "0.3" tempfile = "3" fs_extra = "1" git2 = "0.8" 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..052a3045b21647e9251546ed0ae37dd8d86f5632 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,6 @@ std = [ "serde", "codec/std", "sr-primitives/std", - "srml-support/std", + "support/std", "system/std", ] diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index c8b24662be1789ce5fa91ca62d16db49c63fd8bc..528428000eb586c1c8cf54e43c20631a33fefa37 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. @@ -214,7 +215,7 @@ decl_storage! { /// The number of units of assets held by any given account. Balances: map (T::AssetId, T::AccountId) => T::Balance; /// The next asset identifier up for grabs. - NextAssetId get(next_asset_id): T::AssetId; + NextAssetId get(fn next_asset_id): T::AssetId; /// The total unit supply of an asset. TotalSupply: map T::AssetId => T::Balance; } @@ -239,9 +240,8 @@ impl Module { mod tests { use super::*; - use runtime_io::with_externalities; - use srml_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types}; - use primitives::{H256, Blake2Hasher}; + use support::{impl_outer_origin, assert_ok, assert_noop, parameter_types}; + use primitives::H256; // 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. use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; @@ -271,7 +271,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -288,13 +287,13 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { system::GenesisConfig::default().build_storage::().unwrap().into() } #[test] fn issuing_asset_units_to_issuer_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); }); @@ -302,7 +301,7 @@ mod tests { #[test] fn querying_total_supply_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); @@ -319,7 +318,7 @@ mod tests { #[test] fn transferring_amount_above_available_balance_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); @@ -330,7 +329,7 @@ mod tests { #[test] fn transferring_amount_less_than_available_balance_should_not_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); @@ -344,7 +343,7 @@ mod tests { #[test] fn transferring_less_than_one_unit_should_not_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 0), "transfer amount should be non-zero"); @@ -353,7 +352,7 @@ mod tests { #[test] fn transferring_more_units_than_total_supply_should_not_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 101), "origin account balance must be greater than or equal to the transfer amount"); @@ -362,7 +361,7 @@ mod tests { #[test] fn destroying_asset_balance_with_positive_balance_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::destroy(Origin::signed(1), 0)); @@ -371,7 +370,7 @@ mod tests { #[test] fn destroying_asset_balance_with_zero_balance_should_not_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 2), 0); assert_noop!(Assets::destroy(Origin::signed(2), 0), "origin balance should be non-zero"); diff --git a/srml/aura/Cargo.toml b/srml/aura/Cargo.toml index 06a5a94635a59cc8c7e9441bcd32bb470bf13129..f1c37b7c08d45fe7ec2cadcf608d1c407e7dbc15 100644 --- a/srml/aura/Cargo.toml +++ b/srml/aura/Cargo.toml @@ -10,17 +10,17 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = 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", optional = true } +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 } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false, features = [ "wasm-nice-panic-message" ] } -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 } [dev-dependencies] -lazy_static = "1.0" +lazy_static = "1.4.0" parking_lot = "0.9.0" [features] @@ -29,12 +29,12 @@ std = [ "app-crypto/std", "codec/std", "inherents/std", - "runtime_io/std", + "runtime-io/std", "primitives/std", "rstd/std", "serde", "sr-primitives/std", - "srml-support/std", + "support/std", "substrate-consensus-aura-primitives/std", "system/std", "timestamp/std", diff --git a/srml/aura/src/lib.rs b/srml/aura/src/lib.rs index e02a2e1f0a0ec67192d52461ad1e1cd5fec6d918..f9034c7ca046bdc39c5966682ac8787d9aea7948 100644 --- a/srml/aura/src/lib.rs +++ b/srml/aura/src/lib.rs @@ -49,12 +49,12 @@ pub use timestamp; use rstd::{result, prelude::*}; use codec::{Encode, Decode}; -use srml_support::{ - decl_storage, decl_module, Parameter, storage::StorageValue, traits::{Get, FindAuthor}, +use support::{ + decl_storage, decl_module, Parameter, traits::{Get, FindAuthor}, ConsensusEngineId, }; -use app_crypto::AppPublic; use sr_primitives::{ + RuntimeAppPublic, traits::{SaturatedConversion, Saturating, Zero, Member, IsMember}, generic::DigestItem, }; use timestamp::OnTimestampSet; @@ -142,28 +142,20 @@ impl ProvideInherentData for InherentDataProvider { pub trait Trait: timestamp::Trait { /// The identifier type for an authority. - type AuthorityId: Member + Parameter + AppPublic + Default; + type AuthorityId: Member + Parameter + RuntimeAppPublic + Default; } decl_storage! { trait Store for Module as Aura { /// The last timestamp. - LastTimestamp get(last) build(|_| 0.into()): T::Moment; + LastTimestamp get(fn last) build(|_| 0.into()): T::Moment; /// The current authorities - pub Authorities get(authorities): Vec; + pub Authorities get(fn authorities): Vec; } add_extra_genesis { config(authorities): Vec; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig - | { - runtime_io::with_storage( - storage, - || Module::::initialize_authorities(&config.authorities), - ); - }) + build(|config| Module::::initialize_authorities(&config.authorities)) } } @@ -185,7 +177,7 @@ impl Module { fn initialize_authorities(authorities: &[T::AuthorityId]) { if !authorities.is_empty() { assert!(>::get().is_empty(), "Authorities are already initialized!"); - >::put_ref(authorities); + >::put(authorities); } } } @@ -258,7 +250,7 @@ impl Module { 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; @@ -266,7 +258,7 @@ impl Module { assert!(!slot_duration.is_zero(), "Aura slot duration cannot be zero."); - let last_slot = last / slot_duration.clone(); + 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."); diff --git a/srml/aura/src/mock.rs b/srml/aura/src/mock.rs index 5861b11e07fbff5e4694a6039e301f21883c84a9..5c55e8bdd58dfbdbede54cdf3605cef317f88ebf 100644 --- a/srml/aura/src/mock.rs +++ b/srml/aura/src/mock.rs @@ -24,9 +24,9 @@ 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}; +use primitives::H256; impl_outer_origin!{ pub enum Origin for Test {} @@ -54,7 +54,6 @@ impl system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -73,7 +72,7 @@ impl Trait for Test { type AuthorityId = AuthorityId; } -pub fn new_test_ext(authorities: Vec) -> runtime_io::TestExternalities { +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()).collect(), diff --git a/srml/aura/src/tests.rs b/srml/aura/src/tests.rs index a90eddf18f73095fd2072c715962a907f90a8050..a90ec3a861e84f1d2ac1702efb315ff3fdd150f9 100644 --- a/srml/aura/src/tests.rs +++ b/srml/aura/src/tests.rs @@ -18,12 +18,11 @@ #![cfg(test)] -use runtime_io::with_externalities; use crate::mock::{Aura, new_test_ext}; #[test] fn initial_values() { - with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + new_test_ext(vec![0, 1, 2, 3]).execute_with(|| { 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 index 5d52bdb2461fab58f11df08ebad9fb769db0b67f..3968ab52aec6638aa6b03ce7edb756e2c042c900 100644 --- a/srml/authority-discovery/Cargo.toml +++ b/srml/authority-discovery/Cargo.toml @@ -5,30 +5,32 @@ 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"] } -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 } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -serde = { version = "1.0", optional = true } +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 } -im-online = { package = "srml-im-online", path = "../im-online", default-features = false } -srml-support = { path = "../support", default-features = false } -sr-io = { package = "sr-io", path = "../../core/sr-io", 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", - "sr-primitives/std", "primitives/std", "rstd/std", + "runtime-io/std", "serde", "session/std", - "im-online/std", - "srml-support/std", - "sr-io/std", + "sr-primitives/std", + "support/std", "system/std", - "app-crypto/std", ] diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index 00912aeffed8b0104de23b776291b41ad4956471..c82d580fd9e2fa7e6cf1b236117199d1f5c47194 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -22,35 +22,30 @@ //! //! ## Dependencies //! -//! This module depends on the [I’m online module](../srml_im_online/index.html) -//! using its session key. +//! 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::{Decode, Encode}; +use codec::FullCodec; use rstd::prelude::*; -use srml_support::{decl_module, decl_storage, StorageValue}; +use support::{decl_module, decl_storage}; -pub trait Trait: system::Trait + session::Trait {} +/// 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; + Keys get(fn keys): Vec; } add_extra_genesis { - config(keys): Vec; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig - | { - sr_io::with_storage( - storage, - || Module::::initialize_keys(&config.keys), - ); - }) + config(keys): Vec; + build(|config| Module::::initialize_keys(&config.keys)) } } @@ -64,10 +59,10 @@ impl Module { /// set, otherwise this function returns None. The restriction might be /// softened in the future in case a consumer needs to learn own authority /// identifier. - pub fn authority_id() -> Option { - let authorities = Keys::get(); + fn authority_id() -> Option { + let authorities = Keys::::get(); - let local_keys = im_online::AuthorityId::all(); + let local_keys = T::AuthorityId::all(); authorities.into_iter().find_map(|authority| { if local_keys.contains(&authority) { @@ -79,41 +74,45 @@ impl Module { } /// Retrieve authority identifiers of the current authority set. - pub fn authorities() -> Vec { - Keys::get() + 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, authority_id: im_online::AuthorityId) -> Option> { - authority_id.sign(&payload).map(|s| s.encode()) + 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: Vec, - authority_id: im_online::AuthorityId, + payload: &Vec, + signature: <::AuthorityId as RuntimeAppPublic>::Signature, + authority_id: T::AuthorityId, ) -> bool { - im_online::AuthoritySignature::decode(&mut &signature[..]) - .map(|s| authority_id.verify(&payload, &s)) - .unwrap_or(false) + authority_id.verify(payload, &signature) } - fn initialize_keys(keys: &[im_online::AuthorityId]) { + fn initialize_keys(keys: &[T::AuthorityId]) { if !keys.is_empty() { - assert!(Keys::get().is_empty(), "Keys are already initialized!"); - Keys::put_ref(keys); + assert!(Keys::::get().is_empty(), "Keys are already initialized!"); + Keys::::put(keys); } } } impl session::OneSessionHandler for Module { - type Key = im_online::AuthorityId; + type Key = T::AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) where - I: Iterator, + I: Iterator, { let keys = validators.map(|x| x.1).collect::>(); Self::initialize_keys(&keys); @@ -121,10 +120,10 @@ impl session::OneSessionHandler for Module { fn on_new_session<'a, I: 'a>(_changed: bool, _validators: I, next_validators: I) where - I: Iterator, + I: Iterator, { // Remember who the authorities are for the new session. - Keys::put(next_validators.map(|x| x.1).collect::>()); + Keys::::put(next_validators.map(|x| x.1).collect::>()); } fn on_disabled(_i: usize) { @@ -136,40 +135,51 @@ impl session::OneSessionHandler for Module { mod tests { use super::*; use app_crypto::Pair; - use primitives::testing::KeyStore; - use primitives::{crypto::key_types, sr25519, traits::BareCryptoStore, H256}; - use sr_io::{with_externalities, TestExternalities}; - use sr_primitives::testing::{Header, UintAuthorityId}; - use sr_primitives::traits::{ConvertInto, IdentityLookup, OpaqueKeys}; - use sr_primitives::Perbill; - use srml_support::{impl_outer_origin, parameter_types}; + use primitives::{testing::KeyStore, crypto::key_types, sr25519, H256, traits::KeystoreExt}; + use runtime_io::TestExternalities; + use sr_primitives::{ + testing::{Header, UintAuthorityId}, traits::{ConvertInto, IdentityLookup, OpaqueKeys}, + 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 {} + 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> { + 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 = im_online::AuthorityId; + 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; @@ -191,10 +201,9 @@ mod tests { type Call = (); type Hash = H256; type Hashing = ::sr_primitives::traits::BlakeTwo256; - type AccountId = im_online::AuthorityId; + type AccountId = AuthorityId; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -208,17 +217,17 @@ mod tests { } pub struct TestSessionHandler; - impl session::SessionHandler for TestSessionHandler { + impl session::SessionHandler for TestSessionHandler { fn on_new_session( _changed: bool, - _validators: &[(im_online::AuthorityId, Ks)], - _queued_validators: &[(im_online::AuthorityId, Ks)], + _validators: &[(AuthorityId, Ks)], + _queued_validators: &[(AuthorityId, Ks)], ) { } fn on_disabled(_validator_index: usize) {} - fn on_genesis_session(_validators: &[(im_online::AuthorityId, Ks)]) {} + fn on_genesis_session(_validators: &[(AuthorityId, Ks)]) {} } #[test] @@ -227,33 +236,33 @@ mod tests { let key_store = KeyStore::new(); key_store .write() - .sr25519_generate_new(key_types::IM_ONLINE, None) + .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::IM_ONLINE) + .sr25519_public_keys(key_types::BABE) .pop() .unwrap(); - let authority_id = im_online::AuthorityId::from(public_key); + let authority_id = AuthorityId::from(public_key); // Build genesis. let mut t = system::GenesisConfig::default() .build_storage::() .unwrap(); - GenesisConfig { + GenesisConfig:: { keys: vec![authority_id.clone()], } - .assimilate_storage::(&mut t) + .assimilate_storage(&mut t) .unwrap(); // Create externalities. let mut externalities = TestExternalities::new(t); - externalities.set_keystore(key_store); + externalities.register_extension(KeystoreExt(key_store)); - with_externalities(&mut externalities, || { + externalities.execute_with(|| { assert_eq!( authority_id, AuthorityDiscovery::authority_id().expect("Retrieving public key.") @@ -267,7 +276,7 @@ mod tests { let key_store = KeyStore::new(); key_store .write() - .sr25519_generate_new(key_types::IM_ONLINE, None) + .sr25519_generate_new(key_types::BABE, None) .expect("Generates key."); // Build genesis. @@ -279,18 +288,18 @@ mod tests { let keys = vec![(); 5] .iter() .map(|_x| sr25519::Pair::generate_with_phrase(None).0.public()) - .map(im_online::AuthorityId::from) + .map(AuthorityId::from) .collect(); - GenesisConfig { keys: keys } - .assimilate_storage::(&mut t) + GenesisConfig:: { keys: keys } + .assimilate_storage(&mut t) .unwrap(); // Create externalities. let mut externalities = TestExternalities::new(t); - externalities.set_keystore(key_store); + externalities.register_extension(KeystoreExt(key_store)); - with_externalities(&mut externalities, || { + externalities.execute_with(|| { assert_eq!(None, AuthorityDiscovery::authority_id()); }); } @@ -301,48 +310,46 @@ mod tests { let key_store = KeyStore::new(); key_store .write() - .sr25519_generate_new(key_types::IM_ONLINE, None) + .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::IM_ONLINE) + .sr25519_public_keys(key_types::BABE) .pop() .unwrap(); - let authority_id = im_online::AuthorityId::from(public_key); + let authority_id = AuthorityId::from(public_key); // Build genesis. let mut t = system::GenesisConfig::default() .build_storage::() .unwrap(); - GenesisConfig { + GenesisConfig:: { keys: vec![authority_id.clone()], } - .assimilate_storage::(&mut t) + .assimilate_storage(&mut t) .unwrap(); // Create externalities. let mut externalities = TestExternalities::new(t); - externalities.set_keystore(key_store); + externalities.register_extension(KeystoreExt(key_store)); - with_externalities(&mut externalities, || { - let authority_id = AuthorityDiscovery::authority_id().expect("authority id"); + externalities.execute_with(|| { let payload = String::from("test payload").into_bytes(); - let sig = - AuthorityDiscovery::sign(payload.clone(), authority_id.clone()).expect("signature"); + let (sig, authority_id) = AuthorityDiscovery::sign(&payload).expect("signature"); assert!(AuthorityDiscovery::verify( - payload, + &payload, sig.clone(), - authority_id.clone() + authority_id.clone(), )); assert!(!AuthorityDiscovery::verify( - String::from("other payload").into_bytes(), + &String::from("other payload").into_bytes(), sig, - authority_id + 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 424223a2c9a647b231fb52cd171688f79577bf54..173af5f729cbb8df5b306e40916b01eb6f38a71b 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 @@ -218,8 +195,8 @@ where } } -#[derive(Encode, Decode)] -#[cfg_attr(any(feature = "std", test), derive(PartialEq, Debug))] +#[derive(Encode, Decode, sr_primitives::RuntimeDebug)] +#[cfg_attr(any(feature = "std", test), derive(PartialEq))] enum UncleEntryItem { InclusionHeight(BlockNumber), Uncle(Hash, Option), @@ -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 { @@ -438,13 +412,11 @@ impl ProvideInherent for Module { #[cfg(test)] mod tests { use super::*; - use runtime_io::with_externalities; - use primitives::{H256, Blake2Hasher}; - use sr_primitives::traits::{BlakeTwo256, IdentityLookup}; - use sr_primitives::testing::Header; - use sr_primitives::generic::DigestItem; - use sr_primitives::Perbill; - use srml_support::{parameter_types, impl_outer_origin, ConsensusEngineId}; + use primitives::H256; + use sr_primitives::{ + traits::{BlakeTwo256, IdentityLookup}, testing::Header, generic::DigestItem, Perbill, + }; + use support::{parameter_types, impl_outer_origin, ConsensusEngineId}; impl_outer_origin!{ pub enum Origin for Test {} @@ -470,7 +442,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -561,7 +532,7 @@ mod tests { ) } - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let t = system::GenesisConfig::default().build_storage::().unwrap(); t.into() } @@ -569,20 +540,26 @@ 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)]); + new_test_ext().execute_with(|| { + 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] fn rejects_bad_uncles() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let author_a = 69; struct CanonChain { @@ -695,7 +672,7 @@ mod tests { #[test] fn sets_author_lazily() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let author = 42; let mut header = seal_header( create_header(1, Default::default(), [1; 32].into()), diff --git a/srml/babe/Cargo.toml b/srml/babe/Cargo.toml index 039ccea3df853a0f1fc8b50781a237187551af82..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 } sr-staking-primitives = { path = "../../core/sr-staking-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 } 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,7 +32,7 @@ std = [ "serde", "codec/std", "rstd/std", - "srml-support/std", + "support/std", "sr-primitives/std", "sr-staking-primitives/std", "system/std", @@ -38,5 +40,5 @@ std = [ "inherents/std", "babe-primitives/std", "session/std", - "runtime_io/std", + "runtime-io/std", ] diff --git a/srml/babe/src/lib.rs b/srml/babe/src/lib.rs index b58fb26b5a127419976e34687e3a04f734c5afac..ee2d66fbe690fd3bf12a088c9d1f2c18930ec27d 100644 --- a/srml/babe/src/lib.rs +++ b/srml/babe/src/lib.rs @@ -18,32 +18,36 @@ //! from VRF outputs and manages epoch transitions. #![cfg_attr(not(feature = "std"), no_std)] -#![forbid(unused_must_use, unsafe_code, unused_variables)] - -// TODO: @marcio uncomment this when BabeEquivocation is integrated. -// #![forbid(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 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}, }; -use sr_primitives::weights::SimpleDispatchInfo; #[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, BabeAuthorityWeight, Epoch, RawBabePreDigest}; +use babe_primitives::{ + BABE_ENGINE_ID, ConsensusLog, BabeAuthorityWeight, NextEpochDescriptor, RawBabePreDigest, + SlotNumber, +}; pub use babe_primitives::{AuthorityId, VRF_OUTPUT_LENGTH, PUBLIC_KEY_LENGTH}; -use system::ensure_root; + +#[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"; @@ -118,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 @@ -127,29 +175,22 @@ 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; + pub EpochIndex get(fn epoch_index): u64; /// Current epoch authorities. - pub Authorities get(authorities): Vec<(AuthorityId, BabeAuthorityWeight)>; + pub Authorities get(fn 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(fn genesis_slot): u64; /// Current slot number. - pub CurrentSlot get(current_slot): u64; - - /// Whether secondary slots are enabled in case the VRF-based slot is - /// empty for the current epoch and the next epoch, respectively. - pub SecondarySlots get(secondary_slots): (bool, bool) = (true, true); - - /// Pending change to enable/disable secondary slots which will be - /// triggered at `current_epoch + 2`. - pub PendingSecondarySlotsChange get(pending_secondary_slots_change): Option = None; + pub CurrentSlot get(fn current_slot): u64; /// The epoch randomness for the *current* epoch. /// @@ -164,7 +205,7 @@ decl_storage! { // NOTE: the following fields don't use the constants to define the // array size because the metadata API currently doesn't resolve the // variable to its underlying value. - pub Randomness get(randomness): [u8; 32 /* RANDOMNESS_LENGTH */]; + pub Randomness get(fn randomness): [u8; 32 /* RANDOMNESS_LENGTH */]; /// Next epoch randomness. NextRandomness: [u8; 32 /* RANDOMNESS_LENGTH */]; @@ -181,21 +222,13 @@ decl_storage! { SegmentIndex build(|_| 0): u32; UnderConstruction: map u32 => Vec<[u8; 32 /* VRF_OUTPUT_LENGTH */]>; - /// Temporary value (cleared at block finalization) which is true + /// Temporary value (cleared at block finalization) which is `Some` /// if per-block initialization has already been called for current block. - Initialized get(initialized): Option; + Initialized get(fn initialized): Option; } add_extra_genesis { config(authorities): Vec<(AuthorityId, BabeAuthorityWeight)>; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig - | { - runtime_io::with_storage( - storage, - || Module::::initialize_authorities(&config.authorities), - ); - }) + build(|config| Module::::initialize_authorities(&config.authorities)) } } @@ -214,26 +247,19 @@ decl_module! { const ExpectedBlockTime: T::Moment = T::ExpectedBlockTime::get(); /// Initialization - fn on_initialize() { - Self::do_initialize(); + fn on_initialize(now: T::BlockNumber) { + Self::do_initialize(now); } /// Block finalization fn on_finalize() { - Initialized::kill(); - } - - /// Sets a pending change to enable / disable secondary slot assignment. - /// The pending change will be set at the end of the current epoch and - /// will be enacted at `current_epoch + 2`. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] - fn set_pending_secondary_slots_change(origin, change: Option) { - ensure_root(origin)?; - match change { - Some(change) => PendingSecondarySlotsChange::put(change), - None => { - PendingSecondarySlotsChange::take(); - }, + // 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); } } } @@ -277,15 +303,14 @@ impl IsMember for Module { } impl session::ShouldEndSession for Module { - fn should_end_session(_: T::BlockNumber) -> bool { + 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(); + // that we have synced with digest before checking if session should be ended. + Self::do_initialize(now); - let diff = CurrentSlot::get().saturating_sub(EpochStartSlot::get()); - diff >= T::EpochDuration::get() + Self::should_epoch_change(now) } } @@ -344,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); @@ -363,21 +454,20 @@ 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() { + 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().unwrap_or(false); + let initialized = Self::initialized().is_some(); if initialized { return; } - Initialized::put(true); - for digest in Self::get_inherent_digests() + let maybe_pre_digest = >::digest() .logs .iter() .filter_map(|s| s.as_pre_runtime()) @@ -386,19 +476,43 @@ impl Module { } else { None }) - { - if EpochStartSlot::get() == 0 { - EpochStartSlot::put(digest.slot_number()); + .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 { - Self::deposit_vrf_output(&vrf_output); + // 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 } + }); - return; - } + 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 @@ -423,7 +537,7 @@ impl Module { fn initialize_authorities(authorities: &[(AuthorityId, BabeAuthorityWeight)]) { if !authorities.is_empty() { assert!(Authorities::get().is_empty(), "Authorities are already initialized!"); - Authorities::put_ref(authorities); + Authorities::put(authorities); } } } @@ -445,82 +559,15 @@ impl session::OneSessionHandler for Module { fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, queued_validators: I) where I: Iterator { - // 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); - - // Update authorities. 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, 1) }).collect::>(); - let next_epoch_start_slot = EpochStartSlot::get().saturating_add(T::EpochDuration::get()); - let next_randomness = NextRandomness::get(); - - // Update any pending secondary slots change - let mut secondary_slots = SecondarySlots::get(); - - // change for E + 1 now becomes change at E - secondary_slots.0 = secondary_slots.1; - - if let Some(change) = PendingSecondarySlotsChange::take() { - // if there's a pending change schedule it for E + 1 - secondary_slots.1 = change; - } else { - // otherwise E + 1 will have the same value as E - secondary_slots.1 = secondary_slots.0; - } - - SecondarySlots::mutate(|secondary| { - *secondary = secondary_slots; - }); - - let next = Epoch { - epoch_index: next_epoch_index, - start_slot: next_epoch_start_slot, - duration: T::EpochDuration::get(), - authorities: next_authorities, - randomness: next_randomness, - secondary_slots: secondary_slots.1, - }; - - 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..5a6b80a2a67172614306607ae688cb5c23237ab6 --- /dev/null +++ b/srml/babe/src/mock.rs @@ -0,0 +1,112 @@ +// 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 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..f860375de487a646cf7ed89efec13bb9a859d0ef --- /dev/null +++ b/srml/babe/src/tests.rs @@ -0,0 +1,126 @@ +// 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 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() { + new_test_ext(vec![0, 1, 2, 3]).execute_with(|| { + assert_eq!(Babe::authorities().len(), 4) + }) +} + +#[test] +fn check_module() { + new_test_ext(vec![0, 1, 2, 3]).execute_with(|| { + 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() { + new_test_ext(vec![0, 1, 2, 3]).execute_with(|| { + 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() { + new_test_ext(vec![0, 1, 2, 3]).execute_with(|| { + 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..f7f6041c6bb1629b99c3571f27925050a5669a62 100644 --- a/srml/balances/Cargo.toml +++ b/srml/balances/Cargo.toml @@ -5,18 +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 } 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" } +transaction-payment = { package = "srml-transaction-payment", path = "../transaction-payment" } [features] default = ["std"] @@ -26,7 +27,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 d3961e53c96670b0a0f6e05b8c41f941f36b14b0..3c354da50881b8930ac208fef6a6f09f31fe850e 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -86,17 +86,6 @@ //! //! - `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. @@ -106,7 +95,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; //! # } @@ -120,14 +109,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 "; @@ -159,21 +148,25 @@ #![cfg_attr(not(feature = "std"), no_std)] use rstd::prelude::*; -use rstd::{cmp, result, mem}; +use rstd::{cmp, result, mem, fmt::Debug}; 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::{ + RuntimeDebug, + traits::{ + Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, + Saturating, Bounded, + }, + weights::SimpleDispatchInfo, }; -use sr_primitives::transaction_validity::{TransactionPriority, ValidTransaction}; -use sr_primitives::weights::{DispatchInfo, SimpleDispatchInfo, Weight}; use system::{IsDeadAccount, OnNewAccount, ensure_signed, ensure_root}; mod mock; @@ -181,16 +174,10 @@ 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 + - MaybeSerializeDebug + From; + MaybeSerializeDeserialize + Debug + From; /// A function that is invoked when the free-balance has fallen below the existential deposit and /// has been reduced to zero. @@ -209,21 +196,12 @@ pub trait Subtrait: system::Trait { /// The fee required to create an account. type CreationFee: Get; - - /// The fee to be paid for making a transaction; the base. - type TransactionBaseFee: Get; - - /// The fee to be paid for making a transaction; the per-byte portion. - type TransactionByteFee: Get; - - /// Convert a weight value into a deductible fee based on the currency type. - type WeightToFee: Convert; } pub trait Trait: system::Trait { /// The balance of an account. type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + - MaybeSerializeDebug + From; + MaybeSerializeDeserialize + Debug + From; /// A function that is invoked when the free-balance has fallen below the existential deposit and /// has been reduced to zero. @@ -234,9 +212,6 @@ pub trait Trait: system::Trait { /// Handler for when a new account is created. type OnNewAccount: OnNewAccount; - /// Handler for the unbalanced reduction when taking transaction fees. - type TransactionPayment: OnUnbalanced>; - /// Handler for the unbalanced reduction when taking fees associated with balance /// transfer (which may also include account creation). type TransferPayment: OnUnbalanced>; @@ -255,15 +230,6 @@ pub trait Trait: system::Trait { /// The fee required to create an account. type CreationFee: Get; - - /// The fee to be paid for making a transaction; the base. - type TransactionBaseFee: Get; - - /// The fee to be paid for making a transaction; the per-byte portion. - type TransactionByteFee: Get; - - /// Convert a weight value into a deductible fee based on the currency type. - type WeightToFee: Convert; } impl, I: Instance> Subtrait for T { @@ -273,9 +239,6 @@ impl, I: Instance> Subtrait for T { type ExistentialDeposit = T::ExistentialDeposit; type TransferFee = T::TransferFee; type CreationFee = T::CreationFee; - type TransactionBaseFee = T::TransactionBaseFee; - type TransactionByteFee = T::TransactionByteFee; - type WeightToFee = T::WeightToFee; } decl_event!( @@ -293,8 +256,7 @@ decl_event!( ); /// Struct to encode the vesting schedule of an individual account. -#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug)] pub struct VestingSchedule { /// Locked amount at genesis. pub locked: Balance, @@ -321,8 +283,7 @@ impl Ves } } -#[derive(Encode, Decode, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] pub struct BalanceLock { pub id: LockIdentifier, pub amount: Balance, @@ -333,12 +294,12 @@ pub struct BalanceLock { decl_storage! { trait Store for Module, I: Instance=DefaultInstance> as Balances { /// The total units issued in the system. - pub TotalIssuance get(total_issuance) build(|config: &GenesisConfig| { + pub TotalIssuance get(fn total_issuance) build(|config: &GenesisConfig| { config.balances.iter().fold(Zero::zero(), |acc: T::Balance, &(_, n)| acc + n) }): T::Balance; /// Information regarding the vesting of a given account. - pub Vesting get(vesting) build(|config: &GenesisConfig| { + pub Vesting get(fn vesting) build(|config: &GenesisConfig| { // Generate initial vesting configuration // * who - Account which we are generating vesting configuration for // * begin - Block when the account will start to vest @@ -375,7 +336,7 @@ decl_storage! { /// /// `system::AccountNonce` is also deleted if `ReservedBalance` is also zero (it also gets /// collapsed to zero if it ever becomes less than `ExistentialDeposit`. - pub FreeBalance get(free_balance) + pub FreeBalance get(fn free_balance) build(|config: &GenesisConfig| config.balances.clone()): map T::AccountId => T::Balance; @@ -390,10 +351,10 @@ decl_storage! { /// /// `system::AccountNonce` is also deleted if `FreeBalance` is also zero (it also gets /// collapsed to zero if it ever becomes less than `ExistentialDeposit`.) - pub ReservedBalance get(reserved_balance): map T::AccountId => T::Balance; + pub ReservedBalance get(fn reserved_balance): map T::AccountId => T::Balance; /// Any liquidity locks on some account balances. - pub Locks get(locks): map T::AccountId => Vec>; + pub Locks get(fn locks): map T::AccountId => Vec>; } add_extra_genesis { config(balances): Vec<(T::AccountId, T::Balance)>; @@ -413,13 +374,7 @@ decl_module! { /// The fee required to create an account. const CreationFee: T::Balance = T::CreationFee::get(); - /// The fee to be paid for making a transaction; the base. - const TransactionBaseFee: T::Balance = T::TransactionBaseFee::get(); - - /// 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. /// @@ -468,7 +423,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, @@ -494,6 +449,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)?; + } } } @@ -760,7 +730,7 @@ mod imbalances { // This works as long as `increase_total_issuance_by` doesn't use the Imbalance // types (basically for charging fees). // This should eventually be refactored so that the three type items that do -// depend on the Imbalance type (TransactionPayment, TransferPayment, DustRemoval) +// depend on the Imbalance type (TransferPayment, DustRemoval) // are placed in their own SRML module. struct ElevatedTrait, I: Instance>(T, I); impl, I: Instance> Clone for ElevatedTrait { @@ -780,7 +750,6 @@ impl, I: Instance> system::Trait for ElevatedTrait { type AccountId = T::AccountId; type Lookup = T::Lookup; type Header = T::Header; - type WeightMultiplierUpdate = T::WeightMultiplierUpdate; type Event = (); type BlockHashCount = T::BlockHashCount; type MaximumBlockWeight = T::MaximumBlockWeight; @@ -793,20 +762,16 @@ impl, I: Instance> Trait for ElevatedTrait { type OnFreeBalanceZero = T::OnFreeBalanceZero; type OnNewAccount = T::OnNewAccount; type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = T::ExistentialDeposit; type TransferFee = T::TransferFee; type CreationFee = T::CreationFee; - type TransactionBaseFee = T::TransactionBaseFee; - type TransactionByteFee = T::TransactionByteFee; - type WeightToFee = T::WeightToFee; } impl, I: Instance> Currency for Module where - T::Balance: MaybeSerializeDebug + T::Balance: MaybeSerializeDeserialize + Debug { type Balance = T::Balance; type PositiveImbalance = PositiveImbalance; @@ -931,8 +896,15 @@ where reason: WithdrawReason, liveness: ExistenceRequirement, ) -> result::Result { - if let Some(new_balance) = Self::free_balance(who).checked_sub(&value) { - if liveness == ExistenceRequirement::KeepAlive && new_balance < T::ExistentialDeposit::get() { + let old_balance = Self::free_balance(who); + if let Some(new_balance) = old_balance.checked_sub(&value) { + // if we need to keep the account alive... + if liveness == ExistenceRequirement::KeepAlive + // ...and it would be dead afterwards... + && new_balance < T::ExistentialDeposit::get() + // ...yet is was alive before + && old_balance >= T::ExistentialDeposit::get() + { return Err("payment would kill account") } Self::ensure_can_withdraw(who, value, reason, new_balance)?; @@ -1036,7 +1008,7 @@ where impl, I: Instance> ReservableCurrency for Module where - T::Balance: MaybeSerializeDebug + T::Balance: MaybeSerializeDeserialize + Debug { fn can_reserve(who: &T::AccountId, value: Self::Balance) -> bool { Self::free_balance(who) @@ -1099,7 +1071,7 @@ where impl, I: Instance> LockableCurrency for Module where - T::Balance: MaybeSerializeDebug + T::Balance: MaybeSerializeDeserialize + Debug { type Moment = T::BlockNumber; @@ -1171,92 +1143,9 @@ where } } -/// Require the transactor pay for themselves and maybe include a tip to gain additional priority -/// in the queue. -#[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct TakeFees, I: Instance = DefaultInstance>(#[codec(compact)] T::Balance); - -impl, I: Instance> TakeFees { - /// utility constructor. Used only in client/factory code. - #[cfg(feature = "std")] - pub fn from(fee: T::Balance) -> Self { - Self(fee) - } - - /// Compute the final fee value for a particular transaction. - /// - /// The final fee is composed of: - /// - _length-fee_: This is the amount paid merely to pay for size of the transaction. - /// - _weight-fee_: This amount is computed based on the weight of the transaction. Unlike - /// size-fee, this is not input dependent and reflects the _complexity_ of the execution - /// and the time it consumes. - /// - (optional) _tip_: if included in the transaction, it will be added on top. Only signed - /// transactions can have a tip. - fn compute_fee(len: usize, info: DispatchInfo, tip: T::Balance) -> T::Balance { - let len_fee = if info.pay_length_fee() { - let len = T::Balance::from(len as u32); - let base = T::TransactionBaseFee::get(); - let per_byte = T::TransactionByteFee::get(); - base.saturating_add(per_byte.saturating_mul(len)) - } else { - Zero::zero() - }; - - let weight_fee = { - // cap the weight to the maximum defined in runtime, otherwise it will be the `Bounded` - // maximum of its data type, which is not desired. - let capped_weight = info.weight.min(::MaximumBlockWeight::get()); - let weight_update = >::next_weight_multiplier(); - let adjusted_weight = weight_update.apply_to(capped_weight); - T::WeightToFee::convert(adjusted_weight) - }; - - len_fee.saturating_add(weight_fee).saturating_add(tip) - } -} - -#[cfg(feature = "std")] -impl, I: Instance> rstd::fmt::Debug for TakeFees { - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { - self.0.fmt(f) - } -} - -impl, I: Instance + Clone + Eq> SignedExtension for TakeFees { - type AccountId = T::AccountId; - type Call = T::Call; - type AdditionalSigned = (); - type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } - - fn validate( - &self, - who: &Self::AccountId, - _call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> rstd::result::Result { - // pay any fees. - let fee = Self::compute_fee(len, info, self.0); - let imbalance = >::withdraw( - who, - fee, - WithdrawReason::TransactionPayment, - ExistenceRequirement::KeepAlive, - ).map_err(|_| DispatchError::Payment)?; - T::TransactionPayment::on_unbalanced(imbalance); - - let mut r = ValidTransaction::default(); - // NOTE: we probably want to maximize the _fee (of any type) per weight unit_ here, which - // will be a bit more than setting the priority to tip. For now, this is enough. - r.priority = fee.saturated_into::(); - Ok(r) - } -} - impl, I: Instance> IsDeadAccount for Module where - T::Balance: MaybeSerializeDebug + T::Balance: MaybeSerializeDeserialize + Debug { fn is_dead_account(who: &T::AccountId) -> bool { Self::total_balance(who).is_zero() diff --git a/srml/balances/src/mock.rs b/srml/balances/src/mock.rs index a90c5d56b28d6245a888b3c3a47db5e4b7eb071f..600d0e6fb78799dd796ab9a66d4dd67bbe133225 100644 --- a/srml/balances/src/mock.rs +++ b/srml/balances/src/mock.rs @@ -18,12 +18,12 @@ #![cfg(test)] -use sr_primitives::{Perbill, traits::{Convert, IdentityLookup}, testing::Header, +use sr_primitives::{Perbill, traits::{ConvertInto, IdentityLookup}, testing::Header, weights::{DispatchInfo, Weight}}; -use primitives::{H256, Blake2Hasher}; +use primitives::H256; 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}; @@ -35,10 +35,6 @@ thread_local! { static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); static TRANSFER_FEE: RefCell = RefCell::new(0); static CREATION_FEE: RefCell = RefCell::new(0); - static TRANSACTION_BASE_FEE: RefCell = RefCell::new(0); - static TRANSACTION_BYTE_FEE: RefCell = RefCell::new(1); - static TRANSACTION_WEIGHT_FEE: RefCell = RefCell::new(1); - static WEIGHT_TO_FEE: RefCell = RefCell::new(1); } pub struct ExistentialDeposit; @@ -56,23 +52,6 @@ impl Get for CreationFee { fn get() -> u64 { CREATION_FEE.with(|v| *v.borrow()) } } -pub struct TransactionBaseFee; -impl Get for TransactionBaseFee { - fn get() -> u64 { TRANSACTION_BASE_FEE.with(|v| *v.borrow()) } -} - -pub struct TransactionByteFee; -impl Get for TransactionByteFee { - fn get() -> u64 { TRANSACTION_BYTE_FEE.with(|v| *v.borrow()) } -} - -pub struct WeightToFee(u64); -impl Convert for WeightToFee { - fn convert(t: Weight) -> u64 { - WEIGHT_TO_FEE.with(|v| *v.borrow() * (t as u64)) - } -} - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Runtime; @@ -92,7 +71,6 @@ impl system::Trait for Runtime { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -100,26 +78,31 @@ impl system::Trait for Runtime { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); } +parameter_types! { + pub const TransactionBaseFee: u64 = 0; + pub const TransactionByteFee: u64 = 1; +} +impl transaction_payment::Trait for Runtime { + type Currency = Module; + type OnTransactionPayment = (); + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = ConvertInto; + type FeeMultiplierUpdate = (); +} impl Trait for Runtime { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); type Event = (); - type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = WeightToFee; } pub struct ExtBuilder { - transaction_base_fee: u64, - transaction_byte_fee: u64, - weight_to_fee: u64, existential_deposit: u64, transfer_fee: u64, creation_fee: u64, @@ -129,9 +112,6 @@ pub struct ExtBuilder { impl Default for ExtBuilder { fn default() -> Self { Self { - transaction_base_fee: 0, - transaction_byte_fee: 0, - weight_to_fee: 0, existential_deposit: 0, transfer_fee: 0, creation_fee: 0, @@ -141,12 +121,6 @@ impl Default for ExtBuilder { } } impl ExtBuilder { - pub fn transaction_fees(mut self, base_fee: u64, byte_fee: u64, weight_fee: u64) -> Self { - self.transaction_base_fee = base_fee; - self.transaction_byte_fee = byte_fee; - self.weight_to_fee = weight_fee; - self - } pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { self.existential_deposit = existential_deposit; self @@ -175,11 +149,8 @@ impl ExtBuilder { 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); - TRANSACTION_BASE_FEE.with(|v| *v.borrow_mut() = self.transaction_base_fee); - TRANSACTION_BYTE_FEE.with(|v| *v.borrow_mut() = self.transaction_byte_fee); - WEIGHT_TO_FEE.with(|v| *v.borrow_mut() = self.weight_to_fee); } - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> runtime_io::TestExternalities { self.set_associated_consts(); let mut t = system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig:: { @@ -211,7 +182,6 @@ impl ExtBuilder { pub type System = system::Module; pub type Balances = Module; - pub const CALL: &::Call = &(); /// create a transaction info struct from weight. Handy to avoid building the whole struct. diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index 338513d40d267d453caaf464356e9b60dd07275c..839ac67991c83f92142965c49b6fa979599c939c 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -20,12 +20,14 @@ use super::*; use mock::{Balances, ExtBuilder, Runtime, System, info_from_weight, CALL}; -use runtime_io::with_externalities; -use srml_support::{ +use sr_primitives::traits::SignedExtension; +use support::{ assert_noop, assert_ok, assert_err, traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, Currency, ReservableCurrency} }; +use transaction_payment::ChargeTransactionPayment; +use system::RawOrigin; const ID_1: LockIdentifier = *b"1 "; const ID_2: LockIdentifier = *b"2 "; @@ -33,7 +35,7 @@ const ID_3: LockIdentifier = *b"3 "; #[test] fn basic_locking_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { assert_eq!(Balances::free_balance(&1), 10); Balances::set_lock(ID_1, &1, 9, u64::max_value(), WithdrawReasons::all()); assert_noop!( @@ -45,7 +47,7 @@ fn basic_locking_should_work() { #[test] fn partial_locking_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); assert_ok!(>::transfer(&1, &2, 1)); }); @@ -53,7 +55,7 @@ fn partial_locking_should_work() { #[test] fn lock_removal_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, u64::max_value(), u64::max_value(), WithdrawReasons::all()); Balances::remove_lock(ID_1, &1); assert_ok!(>::transfer(&1, &2, 1)); @@ -62,7 +64,7 @@ fn lock_removal_should_work() { #[test] fn lock_replacement_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, u64::max_value(), u64::max_value(), WithdrawReasons::all()); Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); assert_ok!(>::transfer(&1, &2, 1)); @@ -71,7 +73,7 @@ fn lock_replacement_should_work() { #[test] fn double_locking_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); Balances::set_lock(ID_2, &1, 5, u64::max_value(), WithdrawReasons::all()); assert_ok!(>::transfer(&1, &2, 1)); @@ -80,7 +82,7 @@ fn double_locking_should_work() { #[test] fn combination_locking_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, u64::max_value(), 0, WithdrawReasons::none()); Balances::set_lock(ID_2, &1, 0, u64::max_value(), WithdrawReasons::none()); Balances::set_lock(ID_3, &1, 0, 0, WithdrawReasons::all()); @@ -90,7 +92,7 @@ fn combination_locking_should_work() { #[test] fn lock_value_extension_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 6), @@ -111,12 +113,11 @@ fn lock_value_extension_should_work() { #[test] fn lock_reasons_should_work() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(1) - .monied(true).transaction_fees(0, 1, 0) - .build(), - || { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build() + .execute_with(|| { Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::Transfer.into()); assert_noop!( >::transfer(&1, &2, 1), @@ -124,8 +125,8 @@ fn lock_reasons_should_work() { ); assert_ok!(>::reserve(&1, 1)); // NOTE: this causes a fee payment. - assert!( as SignedExtension>::pre_dispatch( - TakeFees::from(1), + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(1), &1, CALL, info_from_weight(1), @@ -138,8 +139,8 @@ fn lock_reasons_should_work() { >::reserve(&1, 1), "account liquidity restrictions prevent withdrawal" ); - assert!( as SignedExtension>::pre_dispatch( - TakeFees::from(1), + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(1), &1, CALL, info_from_weight(1), @@ -149,20 +150,19 @@ fn lock_reasons_should_work() { Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::TransactionPayment.into()); assert_ok!(>::transfer(&1, &2, 1)); assert_ok!(>::reserve(&1, 1)); - assert!( as SignedExtension>::pre_dispatch( - TakeFees::from(1), + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(1), &1, CALL, info_from_weight(1), 0, ).is_err()); - } - ); + }); } #[test] fn lock_block_number_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, 10, 2, WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 1), @@ -176,7 +176,7 @@ fn lock_block_number_should_work() { #[test] fn lock_block_number_extension_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, 10, 2, WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 6), @@ -198,7 +198,7 @@ fn lock_block_number_extension_should_work() { #[test] fn lock_reasons_extension_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, 10, 10, WithdrawReason::Transfer.into()); assert_noop!( >::transfer(&1, &2, 6), @@ -219,34 +219,30 @@ fn lock_reasons_extension_should_work() { #[test] fn default_indexing_on_new_accounts_should_not_work2() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(10) - .creation_fee(50) - .monied(true) - .build(), - || { - + ExtBuilder::default() + .existential_deposit(10) + .creation_fee(50) + .monied(true) + .build() + .execute_with(|| { assert_eq!(Balances::is_dead_account(&5), true); // account 5 should not exist // 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); - }, - ); + }); } #[test] fn reserved_balance_should_prevent_reclaim_count() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(256 * 1) - .monied(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(256 * 1) + .monied(true) + .build() + .execute_with(|| { System::inc_account_nonce(&2); assert_eq!(Balances::is_dead_account(&2), false); assert_eq!(Balances::is_dead_account(&5), true); @@ -273,14 +269,13 @@ fn reserved_balance_should_prevent_reclaim_count() { assert_ok!(Balances::transfer(Some(4).into(), 6, 256 * 1 + 0x69)); assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); assert_eq!(Balances::is_dead_account(&6), false); - }, - ); + }); } #[test] fn reward_should_work() { - with_externalities(&mut ExtBuilder::default().monied(true).build(), || { + ExtBuilder::default().monied(true).build().execute_with(|| { assert_eq!(Balances::total_balance(&1), 10); assert_ok!(Balances::deposit_into_existing(&1, 10).map(drop)); assert_eq!(Balances::total_balance(&1), 20); @@ -290,12 +285,11 @@ fn reward_should_work() { #[test] fn dust_account_removal_should_work() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(100) - .monied(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(100) + .monied(true) + .build() + .execute_with(|| { System::inc_account_nonce(&2); assert_eq!(System::account_nonce(&2), 1); assert_eq!(Balances::total_balance(&2), 2000); @@ -304,19 +298,17 @@ fn dust_account_removal_should_work() { assert_eq!(Balances::total_balance(&2), 0); assert_eq!(Balances::total_balance(&5), 1901); assert_eq!(System::account_nonce(&2), 0); - }, - ); + }); } #[test] fn dust_account_removal_should_work2() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(100) - .creation_fee(50) - .monied(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(100) + .creation_fee(50) + .monied(true) + .build() + .execute_with(|| { System::inc_account_nonce(&2); assert_eq!(System::account_nonce(&2), 1); assert_eq!(Balances::total_balance(&2), 2000); @@ -325,13 +317,12 @@ fn dust_account_removal_should_work2() { assert_eq!(Balances::total_balance(&2), 0); assert_eq!(Balances::total_balance(&5), 1851); assert_eq!(System::account_nonce(&2), 0); - }, - ); + }); } #[test] fn balance_works() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 42); assert_eq!(Balances::free_balance(&1), 42); assert_eq!(Balances::reserved_balance(&1), 0); @@ -344,7 +335,7 @@ fn balance_works() { #[test] fn balance_transfer_works() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::transfer(Some(1).into(), 2, 69)); assert_eq!(Balances::total_balance(&1), 42); @@ -352,9 +343,23 @@ fn balance_transfer_works() { }); } +#[test] +fn force_transfer_works() { + ExtBuilder::default().build().execute_with(|| { + 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(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_eq!(Balances::total_balance(&1), 111); @@ -371,16 +376,19 @@ fn reserving_balance_should_work() { #[test] fn balance_transfer_when_reserved_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { 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", + ); }); } #[test] fn deducting_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 69)); assert_eq!(Balances::free_balance(&1), 42); @@ -389,7 +397,7 @@ fn deducting_balance_should_work() { #[test] fn refunding_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 42); Balances::set_reserved_balance(&1, 69); Balances::unreserve(&1, 69); @@ -400,7 +408,7 @@ fn refunding_balance_should_work() { #[test] fn slashing_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 69)); assert!(Balances::slash(&1, 69).1.is_zero()); @@ -412,7 +420,7 @@ fn slashing_balance_should_work() { #[test] fn slashing_incomplete_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 42); assert_ok!(Balances::reserve(&1, 21)); assert_eq!(Balances::slash(&1, 69).1, 27); @@ -424,7 +432,7 @@ fn slashing_incomplete_balance_should_work() { #[test] fn unreserving_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 111)); Balances::unreserve(&1, 42); @@ -435,7 +443,7 @@ fn unreserving_balance_should_work() { #[test] fn slashing_reserved_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 111)); assert_eq!(Balances::slash_reserved(&1, 42).1, 0); @@ -447,7 +455,7 @@ fn slashing_reserved_balance_should_work() { #[test] fn slashing_incomplete_reserved_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 42)); assert_eq!(Balances::slash_reserved(&1, 69).1, 27); @@ -459,7 +467,7 @@ fn slashing_incomplete_reserved_balance_should_work() { #[test] fn transferring_reserved_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 110); let _ = Balances::deposit_creating(&2, 1); assert_ok!(Balances::reserve(&1, 110)); @@ -473,7 +481,7 @@ fn transferring_reserved_balance_should_work() { #[test] fn transferring_reserved_balance_to_nonexistent_should_fail() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 111)); assert_noop!(Balances::repatriate_reserved(&1, &2, 42), "beneficiary account must pre-exist"); @@ -482,7 +490,7 @@ fn transferring_reserved_balance_to_nonexistent_should_fail() { #[test] fn transferring_incomplete_reserved_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 110); let _ = Balances::deposit_creating(&2, 1); assert_ok!(Balances::reserve(&1, 41)); @@ -496,13 +504,13 @@ fn transferring_incomplete_reserved_balance_should_work() { #[test] fn transferring_too_high_value_should_not_panic() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { >::insert(1, u64::max_value()); >::insert(2, 1); 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()); @@ -512,89 +520,76 @@ fn transferring_too_high_value_should_not_panic() { #[test] fn account_create_on_free_too_low_with_other() { - with_externalities( - &mut ExtBuilder::default().existential_deposit(100).build(), - || { - let _ = Balances::deposit_creating(&1, 100); - assert_eq!(>::get(), 100); + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 100); + assert_eq!(>::get(), 100); - // No-op. - let _ = Balances::deposit_creating(&2, 50); - assert_eq!(Balances::free_balance(&2), 0); - assert_eq!(>::get(), 100); - } - ) + // No-op. + let _ = Balances::deposit_creating(&2, 50); + assert_eq!(Balances::free_balance(&2), 0); + assert_eq!(>::get(), 100); + }) } #[test] fn account_create_on_free_too_low() { - with_externalities( - &mut ExtBuilder::default().existential_deposit(100).build(), - || { - // No-op. - let _ = Balances::deposit_creating(&2, 50); - assert_eq!(Balances::free_balance(&2), 0); - assert_eq!(>::get(), 0); - } - ) + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + // No-op. + let _ = Balances::deposit_creating(&2, 50); + assert_eq!(Balances::free_balance(&2), 0); + assert_eq!(>::get(), 0); + }) } #[test] fn account_removal_on_free_too_low() { - with_externalities( - &mut ExtBuilder::default().existential_deposit(100).build(), - || { - assert_eq!(>::get(), 0); + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + assert_eq!(>::get(), 0); - // Setup two accounts with free balance above the existential threshold. - let _ = Balances::deposit_creating(&1, 110); - let _ = Balances::deposit_creating(&2, 110); + // Setup two accounts with free balance above the existential threshold. + let _ = Balances::deposit_creating(&1, 110); + let _ = Balances::deposit_creating(&2, 110); - assert_eq!(Balances::free_balance(&1), 110); - assert_eq!(Balances::free_balance(&2), 110); - assert_eq!(>::get(), 220); + assert_eq!(Balances::free_balance(&1), 110); + assert_eq!(Balances::free_balance(&2), 110); + assert_eq!(>::get(), 220); - // Transfer funds from account 1 of such amount that after this transfer - // the balance of account 1 will be below the existential threshold. - // This should lead to the removal of all balance of this account. - assert_ok!(Balances::transfer(Some(1).into(), 2, 20)); + // Transfer funds from account 1 of such amount that after this transfer + // the balance of account 1 will be below the existential threshold. + // This should lead to the removal of all balance of this account. + assert_ok!(Balances::transfer(Some(1).into(), 2, 20)); - // Verify free balance removal of account 1. - assert_eq!(Balances::free_balance(&1), 0); - assert_eq!(Balances::free_balance(&2), 130); + // Verify free balance removal of account 1. + assert_eq!(Balances::free_balance(&1), 0); + assert_eq!(Balances::free_balance(&2), 130); - // Verify that TotalIssuance tracks balance removal when free balance is too low. - assert_eq!(>::get(), 130); - }, - ); + // Verify that TotalIssuance tracks balance removal when free balance is too low. + assert_eq!(>::get(), 130); + }); } #[test] fn transfer_overflow_isnt_exploitable() { - with_externalities( - &mut ExtBuilder::default().creation_fee(50).build(), - || { - // Craft a value that will overflow if summed with `creation_fee`. - let evil_value = u64::max_value() - 49; - - assert_err!( - Balances::transfer(Some(1).into(), 5, evil_value), - "got overflow after adding a fee to value" - ); - } - ); + ExtBuilder::default().creation_fee(50).build().execute_with(|| { + // Craft a value that will overflow if summed with `creation_fee`. + let evil_value = u64::max_value() - 49; + + assert_err!( + Balances::transfer(Some(1).into(), 5, evil_value), + "got overflow after adding a fee to value", + ); + }); } #[test] fn check_vesting_status() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(256) - .monied(true) - .vesting(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(256) + .monied(true) + .vesting(true) + .build() + .execute_with(|| { assert_eq!(System::block_number(), 1); let user1_free_balance = Balances::free_balance(&1); let user2_free_balance = Balances::free_balance(&2); @@ -645,19 +640,17 @@ fn check_vesting_status() { assert_eq!(Balances::vesting_balance(&2), 0); // Account 2 has fully vested by block 30 assert_eq!(Balances::vesting_balance(&12), 0); // Account 2 has fully vested by block 30 - } - ); + }); } #[test] fn unvested_balance_should_not_transfer() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(10) - .monied(true) - .vesting(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(10) + .monied(true) + .vesting(true) + .build() + .execute_with(|| { assert_eq!(System::block_number(), 1); let user1_free_balance = Balances::free_balance(&1); assert_eq!(user1_free_balance, 100); // Account 1 has free balance @@ -665,40 +658,36 @@ 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 - } - ); + }); } #[test] fn vested_balance_should_transfer() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(10) - .monied(true) - .vesting(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(10) + .monied(true) + .vesting(true) + .build() + .execute_with(|| { assert_eq!(System::block_number(), 1); let user1_free_balance = Balances::free_balance(&1); assert_eq!(user1_free_balance, 100); // Account 1 has free balance // Account 1 has only 5 units vested at block 1 (plus 50 unvested) assert_eq!(Balances::vesting_balance(&1), 45); assert_ok!(Balances::transfer(Some(1).into(), 2, 55)); - } - ); + }); } #[test] fn extra_balance_should_transfer() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(10) - .monied(true) - .vesting(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(10) + .monied(true) + .vesting(true) + .build() + .execute_with(|| { assert_eq!(System::block_number(), 1); assert_ok!(Balances::transfer(Some(3).into(), 1, 100)); assert_ok!(Balances::transfer(Some(3).into(), 2, 100)); @@ -716,19 +705,17 @@ fn extra_balance_should_transfer() { // Account 2 has no units vested at block 1, but gained 100 assert_eq!(Balances::vesting_balance(&2), 200); assert_ok!(Balances::transfer(Some(2).into(), 3, 100)); // Account 2 can send extra units gained - } - ); + }); } #[test] fn liquid_funds_should_transfer_with_delayed_vesting() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(256) - .monied(true) - .vesting(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(256) + .monied(true) + .vesting(true) + .build() + .execute_with(|| { assert_eq!(System::block_number(), 1); let user12_free_balance = Balances::free_balance(&12); @@ -746,62 +733,16 @@ fn liquid_funds_should_transfer_with_delayed_vesting() { // Account 12 can still send liquid funds assert_ok!(Balances::transfer(Some(12).into(), 3, 256 * 5)); - } - ); -} - -#[test] -fn signed_extension_take_fees_work() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(10) - .transaction_fees(10, 1, 5) - .monied(true) - .build(), - || { - let len = 10; - assert!(TakeFees::::from(0).pre_dispatch(&1, CALL, info_from_weight(5), len).is_ok()); - assert_eq!(Balances::free_balance(&1), 100 - 20 - 25); - assert!(TakeFees::::from(5 /* tipped */).pre_dispatch(&1, CALL, info_from_weight(3), len).is_ok()); - assert_eq!(Balances::free_balance(&1), 100 - 20 - 25 - 20 - 5 - 15); - } - ); -} - -#[test] -fn signed_extension_take_fees_is_bounded() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(1000) - .transaction_fees(0, 0, 1) - .monied(true) - .build(), - || { - use sr_primitives::weights::Weight; - - // maximum weight possible - assert!(TakeFees::::from(0).pre_dispatch(&1, CALL, info_from_weight(Weight::max_value()), 10).is_ok()); - // fee will be proportional to what is the actual maximum weight in the runtime. - assert_eq!( - Balances::free_balance(&1), - (10000 - ::MaximumBlockWeight::get()) as u64 - ); - } - ); + }); } #[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); - } - ); + ExtBuilder::default().monied(true).build().execute_with(|| { + 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 3828988015a5acaa18c716cad90e481467f35c9a..37c1482f9ba15e785a1e784bb7f7aed53142a208 100644 --- a/srml/collective/src/lib.rs +++ b/srml/collective/src/lib.rs @@ -25,11 +25,12 @@ use rstd::{prelude::*, result}; use primitives::u32_trait::Value as U32; +use sr_primitives::RuntimeDebug; 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}; @@ -55,8 +56,7 @@ pub trait Trait: system::Trait { } /// Origin for the collective module. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, RuntimeDebug)] pub enum RawOrigin { /// It has been condoned by a given number of members of the collective from a given total. Members(MemberCount, MemberCount), @@ -69,8 +69,7 @@ pub enum RawOrigin { /// Origin for the collective module. pub type Origin = RawOrigin<::AccountId, I>; -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] /// Info for keeping track of a motion being voted on. pub struct Votes { /// The proposal's unique index. @@ -86,28 +85,20 @@ pub struct Votes { decl_storage! { trait Store for Module, I: Instance=DefaultInstance> as Collective { /// The hashes of the active proposals. - pub Proposals get(proposals): Vec; + pub Proposals get(fn proposals): Vec; /// Actual proposal for a given hash, if it's current. - pub ProposalOf get(proposal_of): map T::Hash => Option<>::Proposal>; + pub ProposalOf get(fn proposal_of): map T::Hash => Option<>::Proposal>; /// Votes on a given proposal, if it is ongoing. - pub Voting get(voting): map T::Hash => Option>; + pub Voting get(fn voting): map T::Hash => Option>; /// Proposals so far. - pub ProposalCount get(proposal_count): u32; + pub ProposalCount get(fn proposal_count): u32; /// The current members of the collective. This is stored sorted (just by value). - pub Members get(members): Vec; + pub Members get(fn members): Vec; } 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 +129,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 +280,7 @@ impl, I: Instance> ChangeMembers for Module { } ); } - >::put_ref(new); + >::put(new); } } @@ -297,7 +288,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,13 +378,13 @@ 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; - use primitives::{H256, Blake2Hasher}; + use primitives::H256; use sr_primitives::{ - Perbill, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, testing::Header, BuildStorage + Perbill, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, testing::Header, + BuildStorage, }; use crate as collective; @@ -414,7 +405,6 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = Event; - type WeightMultiplierUpdate = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; @@ -435,7 +425,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, @@ -447,7 +437,7 @@ mod tests { } ); - fn make_ext() -> runtime_io::TestExternalities { + fn make_ext() -> runtime_io::TestExternalities { GenesisConfig { collective_Instance1: Some(collective::GenesisConfig { members: vec![1, 2, 3], @@ -459,7 +449,7 @@ mod tests { #[test] fn motions_basic_environment_works() { - with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); assert_eq!(Collective::members(), vec![1, 2, 3]); assert_eq!(Collective::proposals(), Vec::::new()); @@ -472,7 +462,7 @@ mod tests { #[test] fn removal_of_old_voters_votes_works() { - with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); @@ -506,7 +496,7 @@ mod tests { #[test] fn removal_of_old_voters_votes_works_with_set_members() { - with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); @@ -540,7 +530,7 @@ mod tests { #[test] fn propose_works() { - with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); let hash = proposal.blake2_256().into(); @@ -569,7 +559,7 @@ mod tests { #[test] fn motions_ignoring_non_collective_proposals_works() { - with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); assert_noop!( @@ -581,29 +571,35 @@ mod tests { #[test] fn motions_ignoring_non_collective_votes_works() { - with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); - assert_noop!(Collective::vote(Origin::signed(42), hash.clone(), 0, true), "voter not a member"); + assert_noop!( + Collective::vote(Origin::signed(42), hash.clone(), 0, true), + "voter not a member", + ); }); } #[test] fn motions_ignoring_bad_index_collective_vote_works() { - with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(3); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); - assert_noop!(Collective::vote(Origin::signed(2), hash.clone(), 1, true), "mismatched index"); + assert_noop!( + Collective::vote(Origin::signed(2), hash.clone(), 1, true), + "mismatched index", + ); }); } #[test] fn motions_revoting_works() { - with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); @@ -612,13 +608,19 @@ mod tests { Collective::voting(&hash), Some(Votes { index: 0, threshold: 2, ayes: vec![1], nays: vec![] }) ); - assert_noop!(Collective::vote(Origin::signed(1), hash.clone(), 0, true), "duplicate vote ignored"); + assert_noop!( + Collective::vote(Origin::signed(1), hash.clone(), 0, true), + "duplicate vote ignored", + ); assert_ok!(Collective::vote(Origin::signed(1), hash.clone(), 0, false)); assert_eq!( Collective::voting(&hash), Some(Votes { index: 0, threshold: 2, ayes: vec![], nays: vec![1] }) ); - assert_noop!(Collective::vote(Origin::signed(1), hash.clone(), 0, false), "duplicate vote ignored"); + assert_noop!( + Collective::vote(Origin::signed(1), hash.clone(), 0, false), + "duplicate vote ignored", + ); assert_eq!(System::events(), vec![ EventRecord { @@ -648,7 +650,7 @@ mod tests { #[test] fn motions_disapproval_works() { - with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); @@ -691,7 +693,7 @@ mod tests { #[test] fn motions_approval_works() { - with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); 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..365566cfb547e23324891402cfb106116d526d22 100644 --- a/srml/contracts/Cargo.toml +++ b/srml/contracts/Cargo.toml @@ -5,32 +5,30 @@ 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" } +randomness-collective-flip = { package = "srml-randomness-collective-flip", path = "../randomness-collective-flip" } [features] default = ["std"] -core = [ - "wasmi-validation/core", -] std = [ "serde", "codec/std", @@ -39,9 +37,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/rpc/Cargo.toml b/srml/contracts/rpc/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..90bf34bec1fd9fefe3768cd849af835d1e5b45d4 --- /dev/null +++ b/srml/contracts/rpc/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "srml-contracts-rpc" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +client = { package = "substrate-client", path = "../../../core/client" } +codec = { package = "parity-scale-codec", version = "1.0.0" } +jsonrpc-core = "13.2.0" +jsonrpc-core-client = "13.2.0" +jsonrpc-derive = "13.2.0" +primitives = { package = "substrate-primitives", path = "../../../core/primitives" } +rpc-primitives = { package = "substrate-rpc-primitives", path = "../../../core/rpc/primitives" } +serde = { version = "1.0.101", features = ["derive"] } +sr-primitives = { path = "../../../core/sr-primitives" } +srml-contracts-rpc-runtime-api = { path = "./runtime-api" } diff --git a/srml/contracts/rpc/runtime-api/Cargo.toml b/srml/contracts/rpc/runtime-api/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..2a36ed2c96cc451e622b4c58418f0bb28bf48287 --- /dev/null +++ b/srml/contracts/rpc/runtime-api/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "srml-contracts-rpc-runtime-api" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +client = { package = "substrate-client", path = "../../../../core/client", 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, features = ["derive"] } +sr-primitives = { path = "../../../../core/sr-primitives", default-features = false } + +[features] +default = ["std"] +std = [ + "client/std", + "codec/std", + "rstd/std", + "serde", + "sr-primitives/std", +] diff --git a/srml/contracts/rpc/runtime-api/src/lib.rs b/srml/contracts/rpc/runtime-api/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..7f01b8bdfa6c0dd90fae04afc2f04d17298c8f2b --- /dev/null +++ b/srml/contracts/rpc/runtime-api/src/lib.rs @@ -0,0 +1,65 @@ +// 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 definition required by Contracts RPC extensions. +//! +//! This API should be imported and implemented by the runtime, +//! of a node that wants to use the custom RPC extension +//! adding Contracts access methods. + +#![cfg_attr(not(feature = "std"), no_std)] + +use rstd::vec::Vec; +use codec::{Encode, Decode, Codec}; +use sr_primitives::RuntimeDebug; + +/// A result of execution of a contract. +#[derive(Eq, PartialEq, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::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 interact with contracts without using executive. + pub trait ContractsApi where + AccountId: Codec, + Balance: Codec, + { + /// 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/srml/contracts/rpc/src/lib.rs b/srml/contracts/rpc/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..ba50bd12f030034bf5370c66de28e26b40f06f2b --- /dev/null +++ b/srml/contracts/rpc/src/lib.rs @@ -0,0 +1,124 @@ +// 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 codec::Codec; +use jsonrpc_core::{Error, ErrorCode, Result}; +use jsonrpc_derive::rpc; +use primitives::Bytes; +use sr_primitives::{ + generic::BlockId, + traits::{Block as BlockT, ProvideRuntimeApi}, +}; +use rpc_primitives::number; + +pub use srml_contracts_rpc_runtime_api::{ContractExecResult, ContractsApi as ContractsRuntimeApi}; +pub use self::gen_client::Client as ContractsClient; + +/// 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: Bytes, +} + +/// 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, + _marker: std::marker::PhantomData, +} + +impl Contracts { + /// Create new `Contracts` with the given reference to the client. + pub fn new(client: Arc) -> Self { + Contracts { client, _marker: Default::default() } + } +} + +const RUNTIME_ERROR: i64 = 1; + +impl ContractsApi<::Hash, AccountId, Balance> for Contracts +where + Block: BlockT, + C: Send + Sync + 'static, + C: ProvideRuntimeApi, + C: HeaderBackend, + C::Api: ContractsRuntimeApi, + AccountId: Codec, + Balance: Codec, +{ + 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.to_vec()) + .map_err(|e| Error { + code: ErrorCode::ServerError(RUNTIME_ERROR), + message: "Runtime trapped while executing a contract.".into(), + data: Some(format!("{:?}", e).into()), + })?; + + Ok(exec_result) + } +} diff --git a/srml/contracts/src/account_db.rs b/srml/contracts/src/account_db.rs index 9f8b29e0bd897594007b004878da5cdc36ba7007..50bd1fd40e97d34a319dc9b590c2f5ffd977d7c4 100644 --- a/srml/contracts/src/account_db.rs +++ b/srml/contracts/src/account_db.rs @@ -26,8 +26,8 @@ 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 @@ -37,7 +37,7 @@ 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 Some(_), then a contract is created with the code hash. If None and `reset` is false, + /// 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 @@ -189,7 +189,7 @@ impl AccountDb for DirectAccountDb { last_write: None, } } - // New contract is being created. + // New contract is being instantiated. (_, None, Some(code_hash)) => { AliveContractInfo:: { code_hash, @@ -200,7 +200,7 @@ impl AccountDb for DirectAccountDb { last_write: None, } } - // There is no existing at the address nor a new one to be created. + // There is no existing at the address nor a new one to be instantiated. (_, None, None) => continue, }; @@ -278,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, diff --git a/srml/contracts/src/exec.rs b/srml/contracts/src/exec.rs index 818a689f99d9080ced3fc298c8e975bb98dfd049..af79c6c81813185d132d6392b3d0727e501323bf 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, Randomness}; 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; @@ -61,7 +60,7 @@ impl ExecReturnValue { /// VM-specific errors during execution (eg. division by 0, OOB access, failure to satisfy some /// precondition of a system call, etc.) or errors with the orchestration (eg. out-of-gas errors, a /// non-existent destination contract, etc.). -#[cfg_attr(test, derive(Debug))] +#[cfg_attr(test, derive(sr_primitives::RuntimeDebug))] pub struct ExecError { pub reason: &'static str, /// This is an allocated buffer that may be reused. The buffer must be cleared explicitly @@ -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, @@ -237,7 +231,8 @@ impl Token for ExecFeeToken { } } -#[cfg_attr(any(feature = "std", test), derive(Debug, PartialEq, Eq, Clone))] +#[cfg_attr(any(feature = "std", test), derive(PartialEq, Eq, Clone))] +#[derive(sr_primitives::RuntimeDebug)] pub enum DeferredAction { DepositEvent { /// A list of topics this event will be deposited with. @@ -276,7 +271,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, } @@ -301,7 +296,7 @@ where config: &cfg, vm: &vm, loader: &loader, - timestamp: >::now(), + timestamp: T::Time::now(), block_number: >::block_number(), } } @@ -426,7 +421,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, }); } @@ -453,7 +448,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 ); @@ -670,7 +665,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, } @@ -759,13 +754,17 @@ where } fn random(&self, subject: &[u8]) -> SeedOf { - system::Module::::random(subject) + T::Randomness::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, @@ -805,16 +804,11 @@ mod tests { BalanceOf, ExecFeeToken, ExecutionContext, Ext, Loader, TransferFeeKind, TransferFeeToken, Vm, ExecResult, RawEvent, DeferredAction, }; - use crate::account_db::AccountDb; - use crate::exec::{ExecReturnValue, ExecError, STATUS_SUCCESS}; - use crate::gas::GasMeter; - use crate::tests::{ExtBuilder, Test}; - use crate::{CodeHash, Config}; - use runtime_io::with_externalities; - use std::cell::RefCell; - use std::rc::Rc; - use std::collections::HashMap; - use std::marker::PhantomData; + use crate::{ + account_db::AccountDb, gas::GasMeter, tests::{ExtBuilder, Test}, + exec::{ExecReturnValue, ExecError, STATUS_SUCCESS}, CodeHash, Config, + }; + use std::{cell::RefCell, rc::Rc, collections::HashMap, marker::PhantomData}; use assert_matches::assert_matches; const ALICE: u64 = 1; @@ -939,10 +933,10 @@ mod tests { exec_success() }); - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { 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), @@ -959,7 +953,7 @@ mod tests { let dest = BOB; // This test verifies that base fee for call is taken. - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let vm = MockVm::new(); let loader = MockLoader::empty(); let cfg = Config::preload(); @@ -977,7 +971,7 @@ mod tests { }); // This test verifies that base fee for instantiation is taken. - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let mut loader = MockLoader::empty(); let code = loader.insert(|_| exec_success()); @@ -1007,7 +1001,7 @@ mod tests { let vm = MockVm::new(); let loader = MockLoader::empty(); - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); ctx.overlay.set_balance(&origin, 100); @@ -1039,10 +1033,10 @@ mod tests { |_| Ok(ExecReturnValue { status: 1, data: Vec::new() }) ); - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { 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); @@ -1065,95 +1059,86 @@ 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(), - || { - let vm = MockVm::new(); - let loader = MockLoader::empty(); - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 0); - - let mut gas_meter = GasMeter::::with_limit(1000, 1); - - let result = ctx.call(dest, 50, &mut gas_meter, vec![]); - assert_matches!(result, Ok(_)); - - let mut toks = gas_meter.tokens().iter(); - match_tokens!( - toks, - ExecFeeToken::Call, - TransferFeeToken { - kind: TransferFeeKind::AccountCreate, - gas_price: 1u64 - }, - ); - }, - ); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let vm = MockVm::new(); + let loader = MockLoader::empty(); + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + ctx.overlay.set_balance(&origin, 100); + ctx.overlay.set_balance(&dest, 0); + + let mut gas_meter = GasMeter::::with_limit(1000, 1); + + let result = ctx.call(dest, 50, &mut gas_meter, vec![]); + assert_matches!(result, Ok(_)); + + let mut toks = gas_meter.tokens().iter(); + match_tokens!( + toks, + ExecFeeToken::Call, + TransferFeeToken { + kind: TransferFeeKind::AccountCreate, + gas_price: 1u64 + }, + ); + }); // This one is similar to the previous one but transfer to an existing account. // In this test we expect that a regular transfer fee is charged. - with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - let vm = MockVm::new(); - let loader = MockLoader::empty(); - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 15); - - let mut gas_meter = GasMeter::::with_limit(1000, 1); - - let result = ctx.call(dest, 50, &mut gas_meter, vec![]); - assert_matches!(result, Ok(_)); - - let mut toks = gas_meter.tokens().iter(); - match_tokens!( - toks, - ExecFeeToken::Call, - TransferFeeToken { - kind: TransferFeeKind::Transfer, - gas_price: 1u64 - }, - ); - }, - ); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let vm = MockVm::new(); + let loader = MockLoader::empty(); + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + ctx.overlay.set_balance(&origin, 100); + ctx.overlay.set_balance(&dest, 15); + + let mut gas_meter = GasMeter::::with_limit(1000, 1); + + let result = ctx.call(dest, 50, &mut gas_meter, vec![]); + assert_matches!(result, Ok(_)); + + let mut toks = gas_meter.tokens().iter(); + match_tokens!( + toks, + ExecFeeToken::Call, + TransferFeeToken { + kind: TransferFeeKind::Transfer, + gas_price: 1u64 + }, + ); + }); // This test sends 50 units of currency as an endownment to a newly - // created contract. - with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - let mut loader = MockLoader::empty(); - let code = loader.insert(|_| exec_success()); - - let vm = MockVm::new(); - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 15); - - let mut gas_meter = GasMeter::::with_limit(1000, 1); - - let result = ctx.instantiate(50, &mut gas_meter, &code, vec![]); - assert_matches!(result, Ok(_)); - - let mut toks = gas_meter.tokens().iter(); - match_tokens!( - toks, - ExecFeeToken::Instantiate, - TransferFeeToken { - kind: TransferFeeKind::ContractInstantiate, - gas_price: 1u64 - }, - ); - }, - ); + // instantiated contract. + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let mut loader = MockLoader::empty(); + let code = loader.insert(|_| exec_success()); + + let vm = MockVm::new(); + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + + ctx.overlay.set_balance(&origin, 100); + ctx.overlay.set_balance(&dest, 15); + + let mut gas_meter = GasMeter::::with_limit(1000, 1); + + let result = ctx.instantiate(50, &mut gas_meter, &code, vec![]); + assert_matches!(result, Ok(_)); + + let mut toks = gas_meter.tokens().iter(); + match_tokens!( + toks, + ExecFeeToken::Instantiate, + TransferFeeToken { + kind: TransferFeeKind::ContractInstantiate, + gas_price: 1u64 + }, + ); + }); } #[test] @@ -1166,7 +1151,7 @@ mod tests { let vm = MockVm::new(); let loader = MockLoader::empty(); - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); ctx.overlay.set_balance(&origin, 0); @@ -1200,10 +1185,10 @@ mod tests { |_| Ok(ExecReturnValue { status: STATUS_SUCCESS, data: vec![1, 2, 3, 4] }) ); - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { 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, @@ -1231,10 +1216,10 @@ mod tests { |_| Ok(ExecReturnValue { status: 1, data: vec![1, 2, 3, 4] }) ); - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { 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, @@ -1259,10 +1244,10 @@ mod tests { }); // This one tests passing the input data into a contract via call. - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { 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, @@ -1284,7 +1269,7 @@ mod tests { }); // This one tests passing the input data into a contract via instantiate. - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); @@ -1328,10 +1313,10 @@ mod tests { exec_success() }); - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { 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, @@ -1372,12 +1357,12 @@ mod tests { exec_success() }); - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { 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, @@ -1414,11 +1399,11 @@ mod tests { exec_success() }); - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { 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, @@ -1438,23 +1423,20 @@ mod tests { let mut loader = MockLoader::empty(); let dummy_ch = loader.insert(|_| exec_success()); - with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - assert_matches!( - ctx.instantiate( - 0, // <- zero endowment - &mut GasMeter::::with_limit(10000, 1), - &dummy_ch, - vec![], - ), - Err(_) - ); - } - ); + assert_matches!( + ctx.instantiate( + 0, // <- zero endowment + &mut GasMeter::::with_limit(10000, 1), + &dummy_ch, + vec![], + ), + Err(_) + ); + }); } #[test] @@ -1466,38 +1448,35 @@ mod tests { |_| Ok(ExecReturnValue { status: STATUS_SUCCESS, data: vec![80, 65, 83, 83] }) ); - with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); - - let created_contract_address = assert_matches!( - ctx.instantiate( - 100, - &mut GasMeter::::with_limit(10000, 1), - &dummy_ch, - vec![], - ), - Ok((address, ref output)) if output.data == vec![80, 65, 83, 83] => address - ); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_balance(&ALICE, 1000); - // 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.events(), &[ - DeferredAction::DepositEvent { - event: RawEvent::Transfer(ALICE, created_contract_address, 100), - topics: Vec::new(), - }, - DeferredAction::DepositEvent { - event: RawEvent::Instantiated(ALICE, created_contract_address), - topics: Vec::new(), - } - ]); - } - ); + let instantiated_contract_address = assert_matches!( + ctx.instantiate( + 100, + &mut GasMeter::::with_limit(10000, 1), + &dummy_ch, + vec![], + ), + Ok((address, ref output)) if output.data == vec![80, 65, 83, 83] => address + ); + + // Check that the newly created account has the expected code hash and + // there are instantiation event. + assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch); + assert_eq!(&ctx.events(), &[ + DeferredAction::DepositEvent { + event: RawEvent::Transfer(ALICE, instantiated_contract_address, 100), + topics: Vec::new(), + }, + DeferredAction::DepositEvent { + event: RawEvent::Instantiated(ALICE, instantiated_contract_address), + topics: Vec::new(), + } + ]); + }); } #[test] @@ -1509,28 +1488,25 @@ mod tests { |_| Ok(ExecReturnValue { status: 1, data: vec![70, 65, 73, 76] }) ); - with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); - - let created_contract_address = assert_matches!( - ctx.instantiate( - 100, - &mut GasMeter::::with_limit(10000, 1), - &dummy_ch, - vec![], - ), - Ok((address, ref output)) if output.data == vec![70, 65, 73, 76] => address - ); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_balance(&ALICE, 1000); - // Check that the account has not been created. - assert!(ctx.overlay.get_code_hash(&created_contract_address).is_none()); - assert!(ctx.events().is_empty()); - } - ); + let instantiated_contract_address = assert_matches!( + ctx.instantiate( + 100, + &mut GasMeter::::with_limit(10000, 1), + &dummy_ch, + vec![], + ), + Ok((address, ref output)) if output.data == vec![70, 65, 73, 76] => address + ); + + // Check that the account has not been created. + assert!(ctx.overlay.get_code_hash(&instantiated_contract_address).is_none()); + assert!(ctx.events().is_empty()); + }); } #[test] @@ -1539,12 +1515,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, @@ -1552,45 +1528,42 @@ mod tests { vec![] ).unwrap(); - *created_contract_address.borrow_mut() = address.into(); + *instantiated_contract_address.borrow_mut() = address.into(); Ok(output) } }); - with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - 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(); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_balance(&ALICE, 1000); + ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap(); - assert_matches!( - ctx.call(BOB, 20, &mut GasMeter::::with_limit(1000, 1), vec![]), - Ok(_) - ); + 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(); - - // 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.events(), &[ - DeferredAction::DepositEvent { - event: RawEvent::Transfer(ALICE, BOB, 20), - topics: Vec::new(), - }, - DeferredAction::DepositEvent { - event: RawEvent::Transfer(BOB, created_contract_address, 15), - topics: Vec::new(), - }, - DeferredAction::DepositEvent { - event: RawEvent::Instantiated(BOB, created_contract_address), - topics: Vec::new(), - }, - ]); - } - ); + 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(&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, instantiated_contract_address, 15), + topics: Vec::new(), + }, + DeferredAction::DepositEvent { + event: RawEvent::Instantiated(BOB, instantiated_contract_address), + topics: Vec::new(), + }, + ]); + }); } #[test] @@ -1601,10 +1574,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, @@ -1619,29 +1592,26 @@ mod tests { } }); - with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - 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(); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_balance(&ALICE, 1000); + ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap(); - assert_matches!( - ctx.call(BOB, 20, &mut GasMeter::::with_limit(1000, 1), vec![]), - Ok(_) - ); + 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 - // event here. - assert_eq!(&ctx.events(), &[ - DeferredAction::DepositEvent { - event: RawEvent::Transfer(ALICE, BOB, 20), - topics: Vec::new(), - }, - ]); - } - ); + // The contract wasn't instantiated so we don't expect to see an instantiation + // event here. + assert_eq!(&ctx.events(), &[ + DeferredAction::DepositEvent { + event: RawEvent::Transfer(ALICE, BOB, 20), + topics: Vec::new(), + }, + ]); + }); } #[test] @@ -1655,7 +1625,7 @@ mod tests { exec_success() }); - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); 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 f8485f848ad1580bdecc7f445e22e946cafe9179..8eaef951bae466bf9b00a2a8bd45a4d854bb8f78 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,35 @@ 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 rstd::{prelude::*, marker::PhantomData, fmt::Debug}; 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, MaybeSerializeDeserialize, Member, SignedExtension}, + weights::DispatchInfo, + transaction_validity::{ + ValidTransaction, InvalidTransaction, TransactionValidity, TransactionValidityError, + }, + RuntimeDebug, }; -use srml_support::dispatch::{Result, Dispatchable}; -use srml_support::{ - Parameter, StorageMap, StorageValue, decl_module, decl_event, decl_storage, storage::child, - parameter_types, +use support::dispatch::{Result, Dispatchable}; +use support::{ + Parameter, decl_module, decl_event, decl_storage, storage::child, + parameter_types, IsSubType }; -use srml_support::traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get}; +use support::traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get, Time, Randomness}; 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; @@ -128,8 +144,7 @@ pub trait ComputeDispatchFee { /// Information for managing an acocunt and its sub trie abstraction. /// This is the required info to cache for an account -#[derive(Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, RuntimeDebug)] pub enum ContractInfo { Alive(AliveContractInfo), Tombstone(TombstoneContractInfo), @@ -192,9 +207,7 @@ pub type AliveContractInfo = /// Information for managing an account and its sub trie abstraction. /// This is the required info to cache for an account. -// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. -#[derive(Encode, Decode, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] pub struct RawAliveContractInfo { /// Unique ID for the subtree encoded as a bytes vector. pub trie_id: TrieId, @@ -213,15 +226,14 @@ pub struct RawAliveContractInfo { pub type TombstoneContractInfo = RawTombstoneContractInfo<::Hash, ::Hashing>; -// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. -#[derive(Encode, Decode, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub struct RawTombstoneContractInfo(H, PhantomData); impl RawTombstoneContractInfo where - H: Member + MaybeSerializeDebug + AsRef<[u8]> + AsMut<[u8]> + Copy + Default + rstd::hash::Hash - + Codec, + H: Member + MaybeSerializeDeserialize+ Debug + + AsRef<[u8]> + AsMut<[u8]> + Copy + Default + + rstd::hash::Hash + Codec, Hasher: Hash, { fn new(storage_root: &[u8], code_hash: H) -> Self { @@ -283,56 +295,58 @@ 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`]. - pub const DefaultMaxDepth: u32 = 1024; - /// A resonable default value for [`Trait::MaxValueSize`]. + /// A reasonable default value for [`Trait::InstantiateBaseFee`]. + pub const DefaultInstantiateBaseFee: u32 = 1000; + /// A reasonable default value for [`Trait::MaxDepth`]. + pub const DefaultMaxDepth: u32 = 32; + /// 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; + type Randomness: Randomness; /// 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 @@ -341,6 +355,9 @@ pub trait Trait: timestamp::Trait { /// Handler for the unbalanced reduction when making a gas payment. type GasPayment: OnUnbalanced>; + /// Handler for rent payments. + type RentPayment: OnUnbalanced>; + /// Number of block delay an extrinsic claim surcharge has. /// /// When claim surcharge is called by an extrinsic the rent is checked @@ -350,7 +367,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 +399,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 +442,7 @@ where } /// The default dispatch fee computor computes the fee in the same way that -/// the implementation of `TakeFees` for the Balances module does. Note that this only takes a fixed +/// the implementation of `ChargeTransactionPayment` 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 { @@ -449,8 +466,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. @@ -481,7 +498,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(); @@ -489,11 +506,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(); @@ -504,7 +521,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. /// @@ -560,14 +577,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. @@ -575,7 +592,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, @@ -588,6 +605,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 @@ -597,15 +616,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 @@ -619,7 +640,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())?; } } @@ -630,16 +651,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); @@ -690,8 +732,6 @@ impl Module { }); result - .map(|_| ()) - .map_err(|e| e.reason) } fn restore_to( @@ -774,7 +814,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. @@ -798,9 +838,9 @@ decl_event! { decl_storage! { trait Store for Module as Contract { /// Gas spent so far in this block. - GasSpent get(gas_spent): Gas; + GasSpent get(fn gas_spent): Gas; /// Current cost schedule for contracts. - CurrentSchedule get(current_schedule) config(): Schedule = Schedule::default(); + CurrentSchedule get(fn current_schedule) config(): Schedule = Schedule::default(); /// A mapping from an original code hash to the original code, untouched by instrumentation. pub PristineCode: map CodeHash => Option>; /// A mapping between an original code hash and instrumented wasm code, ready for execution. @@ -810,7 +850,7 @@ decl_storage! { /// The code associated with a given account. pub ContractInfoOf: map T::AccountId => Option>; /// The price of one unit of gas. - GasPrice get(gas_price) config(): BalanceOf = 1.into(); + GasPrice get(fn gas_price) config(): BalanceOf = 1.into(); } } @@ -851,8 +891,8 @@ impl Config { } /// Definition of the cost schedule and other parameterizations for wasm vm. -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -#[derive(Clone, Encode, Decode, PartialEq, Eq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub struct Schedule { /// Version of the schedule. pub version: u32, @@ -937,3 +977,67 @@ 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) + } +} + +impl rstd::fmt::Debug for CheckBlockGasLimit { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + write!(f, "CheckBlockGasLimit") + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::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..ecc5f610313c08a778e884c66d96996f007d6ae3 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, OnUnbalanced}; +use support::StorageMap; #[derive(PartialEq, Eq, Copy, Clone)] #[must_use] @@ -126,7 +126,7 @@ fn try_evict_or_and_pay_rent( if can_withdraw_rent && (insufficient_rent || pay_rent) { // Collect dues. - let _ = T::Currency::withdraw( + let imbalance = T::Currency::withdraw( account, dues_limited, WithdrawReason::Fee, @@ -137,6 +137,8 @@ fn try_evict_or_and_pay_rent( dues_limited < rent_budget < balance - subsistence < balance - existential_deposit; qed", ); + + T::RentPayment::on_unbalanced(imbalance); } if insufficient_rent || !can_withdraw_rent { diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index 6ac1a50764f3f44a0f3181f2ece031deb0e0c85a..7a13a66de26c7a7c41523bc85f725c885852f887 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -19,37 +19,34 @@ #![allow(unused)] -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, account_db::{AccountDb, DirectAccountDb, OverlayAccountDb}, }; 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 std::{cell::RefCell, sync::atomic::{AtomicUsize, Ordering}}; use primitives::storage::well_known_keys; -use primitives::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 +66,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 +82,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; @@ -99,8 +96,6 @@ parameter_types! { pub const BlockHashCount: u64 = 250; pub const MaximumBlockWeight: u32 = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; - pub const BalancesTransactionBaseFee: u64 = 0; - pub const BalancesTransactionByteFee: u64 = 0; pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl system::Trait for Test { @@ -113,7 +108,6 @@ impl system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = MetaEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -126,15 +120,11 @@ impl balances::Trait for Test { type OnFreeBalanceZero = Contract; type OnNewAccount = (); type Event = MetaEvent; - type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = BalancesTransactionBaseFee; - type TransactionByteFee = BalancesTransactionByteFee; - type WeightToFee = (); } parameter_types! { pub const MinimumPeriod: u64 = 1; @@ -155,18 +145,21 @@ 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 Randomness = Randomness; type Call = Call; type DetermineContractAddress = DummyContractAddressFor; type Event = MetaEvent; type ComputeDispatchFee = DummyComputeDispatchFee; type TrieIdGenerator = DummyTrieIdGenerator; type GasPayment = (); + type RentPayment = (); type SignedClaimHandicap = SignedClaimHandicap; type TombstoneDeposit = TombstoneDeposit; type StorageSizeOffset = StorageSizeOffset; @@ -179,15 +172,17 @@ 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; +type Randomness = randomness_collective_flip::Module; pub struct DummyContractAddressFor; impl ContractAddressFor for DummyContractAddressFor { @@ -233,7 +228,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 { @@ -242,7 +237,7 @@ impl Default for ExtBuilder { gas_price: 2, block_gas_limit: 100_000_000, transfer_fee: 0, - creation_fee: 0, + instantiation_fee: 0, } } } @@ -263,17 +258,17 @@ 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 { + pub fn build(self) -> runtime_io::TestExternalities { self.set_associated_consts(); let mut t = system::GenesisConfig::default().build_storage::().unwrap(); balances::GenesisConfig:: { @@ -305,7 +300,7 @@ fn compile_module(wabt_module: &str) // Then we check that the all unused gas is refunded. #[test] fn refunds_unused_gas() { - with_externalities(&mut ExtBuilder::default().gas_price(2).build(), || { + ExtBuilder::default().gas_price(2).build().execute_with(|| { Balances::deposit_creating(&ALICE, 100_000_000); assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, Vec::new())); @@ -317,70 +312,67 @@ fn refunds_unused_gas() { #[test] fn account_removal_removes_storage() { - with_externalities( - &mut ExtBuilder::default().existential_deposit(100).build(), - || { - let trie_id1 = ::TrieIdGenerator::trie_id(&1); - let trie_id2 = ::TrieIdGenerator::trie_id(&2); - let key1 = &[1; 32]; - let key2 = &[2; 32]; - - // Set up two accounts with free balance above the existential threshold. - { - Balances::deposit_creating(&1, 110); - ContractInfoOf::::insert(1, &ContractInfo::Alive(RawAliveContractInfo { - trie_id: trie_id1.clone(), - storage_size: ::StorageSizeOffset::get(), - deduct_block: System::block_number(), - code_hash: H256::repeat_byte(1), - rent_allowance: 40, - last_write: None, - })); - - let mut overlay = OverlayAccountDb::::new(&DirectAccountDb); - overlay.set_storage(&1, key1.clone(), Some(b"1".to_vec())); - overlay.set_storage(&1, key2.clone(), Some(b"2".to_vec())); - DirectAccountDb.commit(overlay.into_change_set()); - - Balances::deposit_creating(&2, 110); - ContractInfoOf::::insert(2, &ContractInfo::Alive(RawAliveContractInfo { - trie_id: trie_id2.clone(), - storage_size: ::StorageSizeOffset::get(), - deduct_block: System::block_number(), - code_hash: H256::repeat_byte(2), - rent_allowance: 40, - last_write: None, - })); - - let mut overlay = OverlayAccountDb::::new(&DirectAccountDb); - overlay.set_storage(&2, key1.clone(), Some(b"3".to_vec())); - overlay.set_storage(&2, key2.clone(), Some(b"4".to_vec())); - DirectAccountDb.commit(overlay.into_change_set()); - } + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + let trie_id1 = ::TrieIdGenerator::trie_id(&1); + let trie_id2 = ::TrieIdGenerator::trie_id(&2); + let key1 = &[1; 32]; + let key2 = &[2; 32]; + + // Set up two accounts with free balance above the existential threshold. + { + Balances::deposit_creating(&1, 110); + ContractInfoOf::::insert(1, &ContractInfo::Alive(RawAliveContractInfo { + trie_id: trie_id1.clone(), + storage_size: ::StorageSizeOffset::get(), + deduct_block: System::block_number(), + code_hash: H256::repeat_byte(1), + rent_allowance: 40, + last_write: None, + })); + + let mut overlay = OverlayAccountDb::::new(&DirectAccountDb); + overlay.set_storage(&1, key1.clone(), Some(b"1".to_vec())); + overlay.set_storage(&1, key2.clone(), Some(b"2".to_vec())); + DirectAccountDb.commit(overlay.into_change_set()); + + Balances::deposit_creating(&2, 110); + ContractInfoOf::::insert(2, &ContractInfo::Alive(RawAliveContractInfo { + trie_id: trie_id2.clone(), + storage_size: ::StorageSizeOffset::get(), + deduct_block: System::block_number(), + code_hash: H256::repeat_byte(2), + rent_allowance: 40, + last_write: None, + })); + + let mut overlay = OverlayAccountDb::::new(&DirectAccountDb); + overlay.set_storage(&2, key1.clone(), Some(b"3".to_vec())); + overlay.set_storage(&2, key2.clone(), Some(b"4".to_vec())); + DirectAccountDb.commit(overlay.into_change_set()); + } - // Transfer funds from account 1 of such amount that after this transfer - // the balance of account 1 will be below the existential threshold. - // - // This should lead to the removal of all storage associated with this account. - assert_ok!(Balances::transfer(Origin::signed(1), 2, 20)); - - // Verify that all entries from account 1 is removed, while - // entries from account 2 is in place. - { - assert!(>::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key1).is_none()); - assert!(>::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key2).is_none()); - - assert_eq!( - >::get_storage(&DirectAccountDb, &2, Some(&trie_id2), key1), - Some(b"3".to_vec()) - ); - assert_eq!( - >::get_storage(&DirectAccountDb, &2, Some(&trie_id2), key2), - Some(b"4".to_vec()) - ); - } - }, - ); + // Transfer funds from account 1 of such amount that after this transfer + // the balance of account 1 will be below the existential threshold. + // + // This should lead to the removal of all storage associated with this account. + assert_ok!(Balances::transfer(Origin::signed(1), 2, 20)); + + // Verify that all entries from account 1 is removed, while + // entries from account 2 is in place. + { + assert!(>::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key1).is_none()); + assert!(>::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key2).is_none()); + + assert_eq!( + >::get_storage(&DirectAccountDb, &2, Some(&trie_id2), key1), + Some(b"3".to_vec()) + ); + assert_eq!( + >::get_storage(&DirectAccountDb, &2, Some(&trie_id2), key2), + Some(b"4".to_vec()) + ); + } + }); } const CODE_RETURN_FROM_START_FN: &str = r#" @@ -417,61 +409,58 @@ const CODE_RETURN_FROM_START_FN: &str = r#" fn instantiate_and_call_and_deposit_event() { let (wasm, code_hash) = compile_module::(CODE_RETURN_FROM_START_FN).unwrap(); - with_externalities( - &mut ExtBuilder::default().existential_deposit(100).build(), - || { - Balances::deposit_creating(&ALICE, 1_000_000); - - 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( - Origin::signed(ALICE), - 100, - 100_000, - code_hash.into(), - vec![], - ); + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); + + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // Check at the end to get hash on error easily + let creation = Contract::instantiate( + Origin::signed(ALICE), + 100, + 100_000, + code_hash.into(), + vec![], + ); + + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances( + balances::RawEvent::NewAccount(BOB, 100) + ), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Contract(BOB, vec![1, 2, 3, 4])), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), + topics: vec![], + } + ]); - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances( - balances::RawEvent::NewAccount(BOB, 100) - ), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Contract(BOB, vec![1, 2, 3, 4])), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), - topics: vec![], - } - ]); - - assert_ok!(creation); - assert!(ContractInfoOf::::exists(BOB)); - }, - ); + assert_ok!(creation); + assert!(ContractInfoOf::::exists(BOB)); + }); } const CODE_DISPATCH_CALL: &str = r#" @@ -500,98 +489,95 @@ fn dispatch_call() { let (wasm, code_hash) = compile_module::(CODE_DISPATCH_CALL).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)); - - // Let's keep this assert even though it's redundant. If you ever need to update the - // wasm source this test will fail and will show you the actual hash. - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - ]); - - assert_ok!(Contract::create( - Origin::signed(ALICE), - 100, - 100_000, - code_hash.into(), - vec![], - )); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::call( - Origin::signed(ALICE), - BOB, // newly created account - 0, - 100_000, - vec![], - )); - - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances( - balances::RawEvent::NewAccount(BOB, 100) - ), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), - topics: vec![], - }, - - // Dispatching the call. - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances( - balances::RawEvent::NewAccount(CHARLIE, 50) - ), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances( - balances::RawEvent::Transfer(BOB, CHARLIE, 50, 0) - ), - topics: vec![], - }, - - // Event emited as a result of dispatch. - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Dispatched(BOB, true)), - topics: vec![], - } - ]); - }, - ); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // Let's keep this assert even though it's redundant. If you ever need to update the + // wasm source this test will fail and will show you the actual hash. + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + ]); + + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100, + 100_000, + code_hash.into(), + vec![], + )); + + assert_ok!(Contract::call( + Origin::signed(ALICE), + BOB, // newly created account + 0, + 100_000, + vec![], + )); + + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances( + balances::RawEvent::NewAccount(BOB, 100) + ), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), + topics: vec![], + }, + + // Dispatching the call. + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances( + balances::RawEvent::NewAccount(CHARLIE, 50) + ), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances( + balances::RawEvent::Transfer(BOB, CHARLIE, 50, 0) + ), + topics: vec![], + }, + + // Event emited as a result of dispatch. + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Dispatched(BOB, true)), + topics: vec![], + } + ]); + }); } const CODE_DISPATCH_CALL_THEN_TRAP: &str = r#" @@ -621,80 +607,77 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { let (wasm, code_hash) = compile_module::(CODE_DISPATCH_CALL_THEN_TRAP).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)); - - // Let's keep this assert even though it's redundant. If you ever need to update the - // wasm source this test will fail and will show you the actual hash. - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - ]); - - assert_ok!(Contract::create( + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); + + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // Let's keep this assert even though it's redundant. If you ever need to update the + // wasm source this test will fail and will show you the actual hash. + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + ]); + + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100, + 100_000, + code_hash.into(), + vec![], + )); + + // Call the newly instantiated contract. The contract is expected to dispatch a call + // and then trap. + assert_err!( + Contract::call( Origin::signed(ALICE), - 100, + BOB, // newly created account + 0, 100_000, - code_hash.into(), vec![], - )); - - // Call the newly created contract. The contract is expected to dispatch a call - // and then trap. - assert_err!( - Contract::call( - Origin::signed(ALICE), - BOB, // newly created account - 0, - 100_000, - vec![], + ), + "during execution" + ); + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances( + balances::RawEvent::NewAccount(BOB, 100) ), - "during execution" - ); - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances( - balances::RawEvent::NewAccount(BOB, 100) - ), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), - topics: vec![], - }, - // ABSENCE of events which would be caused by dispatched Balances::transfer call - ]); - }, - ); + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), + topics: vec![], + }, + // ABSENCE of events which would be caused by dispatched Balances::transfer call + ]); + }); } const CODE_SET_RENT: &str = r#" @@ -824,28 +807,25 @@ fn test_set_rent_code_and_hash() { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).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)); - - // If you ever need to update the wasm source this test will fail - // and will show you the actual hash. - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - ]); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // If you ever need to update the wasm source this test will fail + // and will show you the actual hash. + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + ]); + }); } #[test] @@ -853,92 +833,86 @@ fn storage_size() { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); // Storage size - 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, wasm)); - assert_ok!(Contract::create( - Origin::signed(ALICE), - 30_000, - 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4); - - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::set_storage_4_byte())); - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4 + 4); - - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::remove_storage_4_byte())); - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 30_000, + 100_000, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4); + + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::set_storage_4_byte())); + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4 + 4); + + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::remove_storage_4_byte())); + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4); + }); } #[test] fn deduct_blocks() { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).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, wasm)); - assert_ok!(Contract::create( - Origin::signed(ALICE), - 30_000, - 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - // Check creation - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000); - - // Advance 4 blocks - System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent through call - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); - - // Check result - let rent = (8 + 4 - 3) // storage size = size_offset + deploy_set_storage - deposit_offset - * 4 // rent byte price - * 4; // blocks to rent - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000 - rent); - assert_eq!(bob_contract.deduct_block, 5); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent); - - // Advance 7 blocks more - System::initialize(&12, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent through call - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); - - // Check result - let rent_2 = (8 + 4 - 2) // storage size = size_offset + deploy_set_storage - deposit_offset - * 4 // rent byte price - * 7; // blocks to rent - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); - assert_eq!(bob_contract.deduct_block, 12); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); - - // Second call on same block should have no effect on rent - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); - - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); - assert_eq!(bob_contract.deduct_block, 12); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 30_000, + 100_000, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); + + // Check creation + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 1_000); + + // Advance 4 blocks + System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent through call + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + + // Check result + let rent = (8 + 4 - 3) // storage size = size_offset + deploy_set_storage - deposit_offset + * 4 // rent byte price + * 4; // blocks to rent + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 1_000 - rent); + assert_eq!(bob_contract.deduct_block, 5); + assert_eq!(Balances::free_balance(BOB), 30_000 - rent); + + // Advance 7 blocks more + System::initialize(&12, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent through call + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + + // Check result + let rent_2 = (8 + 4 - 2) // storage size = size_offset + deploy_set_storage - deposit_offset + * 4 // rent byte price + * 7; // blocks to rent + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); + assert_eq!(bob_contract.deduct_block, 12); + assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); + + // Second call on same block should have no effect on rent + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); + assert_eq!(bob_contract.deduct_block, 12); + assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); + }); } #[test] @@ -980,32 +954,29 @@ fn claim_surcharge_malus() { fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).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, wasm)); - assert_ok!(Contract::create( - Origin::signed(ALICE), - 100, - 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100, + 100_000, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); - // Advance blocks - System::initialize(&blocks, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + // Advance blocks + System::initialize(&blocks, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - // Trigger rent through call - assert!(trigger_call()); + // Trigger rent through call + assert!(trigger_call()); - if removes { - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - } else { - assert!(ContractInfoOf::::get(BOB).unwrap().get_alive().is_some()); - } + if removes { + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + } else { + assert!(ContractInfoOf::::get(BOB).unwrap().get_alive().is_some()); } - ); + }); } /// Test for all kind of removals for the given trigger: @@ -1016,123 +987,114 @@ fn removals(trigger_call: impl Fn() -> bool) { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); // Balance reached and superior to subsistence threshold - 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, wasm.clone())); - assert_ok!(Contract::create( - Origin::signed(ALICE), - 100, - 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - let subsistence_threshold = 50 /*existential_deposit*/ + 16 /*tombstone_deposit*/; - - // Trigger rent must have no effect - assert!(trigger_call()); - assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); - assert_eq!(Balances::free_balance(&BOB), 100); - - // Advance blocks - System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent through call - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(&BOB), subsistence_threshold); - - // Advance blocks - System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(&BOB), subsistence_threshold); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100, + 100_000, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); + + let subsistence_threshold = 50 /*existential_deposit*/ + 16 /*tombstone_deposit*/; + + // Trigger rent must have no effect + assert!(trigger_call()); + assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); + assert_eq!(Balances::free_balance(&BOB), 100); + + // Advance blocks + System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent through call + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + assert_eq!(Balances::free_balance(&BOB), subsistence_threshold); + + // Advance blocks + System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + assert_eq!(Balances::free_balance(&BOB), subsistence_threshold); + }); // Allowance exceeded - 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, wasm.clone())); - assert_ok!(Contract::create( - Origin::signed(ALICE), - 1_000, - 100_000, code_hash.into(), - ::Balance::from(100u32).encode() // rent allowance - )); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 100); - assert_eq!(Balances::free_balance(&BOB), 1_000); - - // Advance blocks - System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent through call - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - // Balance should be initial balance - initial rent_allowance - assert_eq!(Balances::free_balance(&BOB), 900); - - // Advance blocks - System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(&BOB), 900); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 1_000, + 100_000, code_hash.into(), + ::Balance::from(100u32).encode() // rent allowance + )); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 100); + assert_eq!(Balances::free_balance(&BOB), 1_000); + + // Advance blocks + System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent through call + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + // Balance should be initial balance - initial rent_allowance + assert_eq!(Balances::free_balance(&BOB), 900); + + // Advance blocks + System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + assert_eq!(Balances::free_balance(&BOB), 900); + }); // Balance reached and inferior to subsistence threshold - 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, wasm.clone())); - assert_ok!(Contract::create( - Origin::signed(ALICE), - 50+Balances::minimum_balance(), - 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); - assert_eq!(Balances::free_balance(&BOB), 50 + Balances::minimum_balance()); - - // Transfer funds - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::transfer())); - assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); - assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); - - // Advance blocks - System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent through call - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).is_none()); - assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); - - // Advance blocks - System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).is_none()); - assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 50+Balances::minimum_balance(), + 100_000, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); + assert_eq!(Balances::free_balance(&BOB), 50 + Balances::minimum_balance()); + + // Transfer funds + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::transfer())); + assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); + assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); + + // Advance blocks + System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent through call + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB).is_none()); + assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); + + // Advance blocks + System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB).is_none()); + assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); + }); } #[test] @@ -1140,38 +1102,35 @@ fn call_removed_contract() { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); // Balance reached and superior to subsistence threshold - 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, wasm.clone())); - assert_ok!(Contract::create( - Origin::signed(ALICE), - 100, - 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - // Calling contract should succeed. - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); - - // Advance blocks - System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Calling contract should remove contract and fail. - assert_err!( - Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), - "contract has been evicted" - ); - - // Subsequent contract calls should also fail. - assert_err!( - Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), - "contract has been evicted" - ); - } - ) + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100, + 100_000, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); + + // Calling contract should succeed. + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + + // Advance blocks + System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Calling contract should remove contract and fail. + assert_err!( + Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), + "contract has been evicted" + ); + + // Subsequent contract calls should also fail. + assert_err!( + Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), + "contract has been evicted" + ); + }) } const CODE_CHECK_DEFAULT_RENT_ALLOWANCE: &str = r#" @@ -1225,38 +1184,35 @@ 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( - &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, wasm)); - assert_ok!(Contract::create( - Origin::signed(ALICE), - 30_000, - 100_000, - code_hash.into(), - vec![], - )); - - // Check creation - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, >::max_value()); - - // Advance blocks - System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent through call - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); - - // Check contract is still alive - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive(); - assert!(bob_contract.is_some()) - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 30_000, + 100_000, + code_hash.into(), + vec![], + )); + + // Check creation + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, >::max_value()); + + // Advance blocks + System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent through call + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + + // Check contract is still alive + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive(); + assert!(bob_contract.is_some()) + }); } const CODE_RESTORATION: &str = r#" @@ -1345,122 +1301,119 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: let (restoration_wasm, restoration_code_hash) = compile_module::(CODE_RESTORATION).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, restoration_wasm)); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, set_rent_wasm)); - - // If you ever need to update the wasm source this test will fail - // and will show you the actual hash. - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(restoration_code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(set_rent_code_hash.into())), - topics: vec![], - }, - ]); - - // Create an account with address `BOB` with code `CODE_SET_RENT`. - // The input parameter sets the rent allowance to 0. - assert_ok!(Contract::create( + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, restoration_wasm)); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, set_rent_wasm)); + + // If you ever need to update the wasm source this test will fail + // and will show you the actual hash. + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(restoration_code_hash.into())), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(set_rent_code_hash.into())), + topics: vec![], + }, + ]); + + // Create an account with address `BOB` with code `CODE_SET_RENT`. + // The input parameter sets the rent allowance to 0. + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 30_000, + 100_000, + set_rent_code_hash.into(), + ::Balance::from(0u32).encode() + )); + + // Check if `BOB` was created successfully and that the rent allowance is + // set to 0. + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 0); + + if test_different_storage { + assert_ok!(Contract::call( Origin::signed(ALICE), - 30_000, - 100_000, - set_rent_code_hash.into(), - ::Balance::from(0u32).encode() - )); - - // Check if `BOB` was created successfully and that the rent allowance is - // set to 0. - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 0); - - if test_different_storage { - assert_ok!(Contract::call( - Origin::signed(ALICE), - BOB, 0, 100_000, - call::set_storage_4_byte()) - ); - } - - // Advance 4 blocks, to the 5th. - System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Call `BOB`, which makes it pay rent. Since the rent allowance is set to 0 - // we expect that it will get removed leaving tombstone. - assert_err!( - Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), - "contract has been evicted" + BOB, 0, 100_000, + call::set_storage_4_byte()) ); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - - /// Create another account with the address `DJANGO` with `CODE_RESTORATION`. - /// - /// 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( - Origin::signed(CHARLIE), - 30_000, - 100_000, - restoration_code_hash.into(), - ::Balance::from(0u32).encode() - )); - - // Before performing a call to `DJANGO` save its original trie id. - let django_trie_id = ContractInfoOf::::get(DJANGO).unwrap() - .get_alive().unwrap().trie_id; + } - if !test_restore_to_with_dirty_storage { - // Advance 1 block, to the 6th. - System::initialize(&6, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - } + // Advance 4 blocks, to the 5th. + System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Call `BOB`, which makes it pay rent. Since the rent allowance is set to 0 + // we expect that it will get removed leaving tombstone. + assert_err!( + Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), + "contract has been evicted" + ); + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + + /// Create another account with the address `DJANGO` with `CODE_RESTORATION`. + /// + /// 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::instantiate( + Origin::signed(CHARLIE), + 30_000, + 100_000, + restoration_code_hash.into(), + ::Balance::from(0u32).encode() + )); + + // Before performing a call to `DJANGO` save its original trie id. + let django_trie_id = ContractInfoOf::::get(DJANGO).unwrap() + .get_alive().unwrap().trie_id; + + if !test_restore_to_with_dirty_storage { + // Advance 1 block, to the 6th. + System::initialize(&6, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + } - // Perform a call to `DJANGO`. This should either perform restoration successfully or - // fail depending on the test parameters. - assert_ok!(Contract::call( - Origin::signed(ALICE), - DJANGO, - 0, - 100_000, - vec![], - )); - - if test_different_storage || test_restore_to_with_dirty_storage { - // Parametrization of the test imply restoration failure. Check that `DJANGO` aka - // restoration contract is still in place and also that `BOB` doesn't exist. - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - let django_contract = ContractInfoOf::::get(DJANGO).unwrap() - .get_alive().unwrap(); - assert_eq!(django_contract.storage_size, 16); - assert_eq!(django_contract.trie_id, django_trie_id); - assert_eq!(django_contract.deduct_block, System::block_number()); - } else { - // Here we expect that the restoration is succeeded. Check that the restoration - // contract `DJANGO` ceased to exist and that `BOB` returned back. - println!("{:?}", ContractInfoOf::::get(BOB)); - let bob_contract = ContractInfoOf::::get(BOB).unwrap() - .get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 50); - assert_eq!(bob_contract.storage_size, 12); - assert_eq!(bob_contract.trie_id, django_trie_id); - assert_eq!(bob_contract.deduct_block, System::block_number()); - assert!(ContractInfoOf::::get(DJANGO).is_none()); - } + // Perform a call to `DJANGO`. This should either perform restoration successfully or + // fail depending on the test parameters. + assert_ok!(Contract::call( + Origin::signed(ALICE), + DJANGO, + 0, + 100_000, + vec![], + )); + + if test_different_storage || test_restore_to_with_dirty_storage { + // Parametrization of the test imply restoration failure. Check that `DJANGO` aka + // restoration contract is still in place and also that `BOB` doesn't exist. + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + let django_contract = ContractInfoOf::::get(DJANGO).unwrap() + .get_alive().unwrap(); + assert_eq!(django_contract.storage_size, 16); + assert_eq!(django_contract.trie_id, django_trie_id); + assert_eq!(django_contract.deduct_block, System::block_number()); + } else { + // Here we expect that the restoration is succeeded. Check that the restoration + // contract `DJANGO` ceased to exist and that `BOB` returned back. + println!("{:?}", ContractInfoOf::::get(BOB)); + let bob_contract = ContractInfoOf::::get(BOB).unwrap() + .get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 50); + assert_eq!(bob_contract.storage_size, 12); + assert_eq!(bob_contract.trie_id, django_trie_id); + assert_eq!(bob_contract.deduct_block, System::block_number()); + assert!(ContractInfoOf::::get(DJANGO).is_none()); } - ); + }); } const CODE_STORAGE_SIZE: &str = r#" @@ -1531,46 +1484,43 @@ const CODE_STORAGE_SIZE: &str = r#" fn storage_max_value_limit() { let (wasm, code_hash) = compile_module::(CODE_STORAGE_SIZE).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, wasm)); - assert_ok!(Contract::create( - Origin::signed(ALICE), - 30_000, - 100_000, - code_hash.into(), - vec![], - )); - - // Check creation - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, >::max_value()); - - // Call contract with allowed storage value. - assert_ok!(Contract::call( + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 30_000, + 100_000, + code_hash.into(), + vec![], + )); + + // Check creation + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, >::max_value()); + + // Call contract with allowed storage value. + assert_ok!(Contract::call( + Origin::signed(ALICE), + BOB, + 0, + 100_000, + Encode::encode(&self::MaxValueSize::get()), + )); + + // Call contract with too large a storage value. + assert_err!( + Contract::call( Origin::signed(ALICE), BOB, 0, 100_000, - Encode::encode(&self::MaxValueSize::get()), - )); - - // Call contract with too large a storage value. - assert_err!( - Contract::call( - Origin::signed(ALICE), - BOB, - 0, - 100_000, - Encode::encode(&(self::MaxValueSize::get() + 1)), - ), - "during execution" - ); - } - ); + Encode::encode(&(self::MaxValueSize::get() + 1)), + ), + "during execution" + ); + }); } const CODE_RETURN_WITH_DATA: &str = r#" @@ -1621,7 +1571,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)) @@ -1677,7 +1627,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. @@ -1705,7 +1655,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. @@ -1733,7 +1683,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. @@ -1898,33 +1848,30 @@ fn deploy_and_call_other_contract() { let (callee_wasm, callee_code_hash) = compile_module::(CODE_RETURN_WITH_DATA).unwrap(); let (caller_wasm, caller_code_hash) = compile_module::(CODE_CALLER_CONTRACT).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)); - - assert_ok!(Contract::create( - Origin::signed(ALICE), - 100_000, - 100_000, - caller_code_hash.into(), - vec![], - )); - - // Call BOB contract, which attempts to instantiate and call the callee contract and - // makes various assertions on the results from those calls. - assert_ok!(Contract::call( - Origin::signed(ALICE), - BOB, - 0, - 200_000, - callee_code_hash.as_ref().to_vec(), - )); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // 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)); + + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100_000, + 100_000, + caller_code_hash.into(), + vec![], + )); + + // Call BOB contract, which attempts to instantiate and call the callee contract and + // makes various assertions on the results from those calls. + assert_ok!(Contract::call( + Origin::signed(ALICE), + BOB, + 0, + 200_000, + callee_code_hash.as_ref().to_vec(), + )); + }); } const CODE_SELF_DESTRUCT: &str = r#" @@ -2029,86 +1976,80 @@ const CODE_SELF_DESTRUCT: &str = r#" #[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::create( - 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()); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + 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::create( + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + 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, - 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(_)) - ); - } - ); + 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#" @@ -2118,7 +2059,7 @@ const CODE_DESTROY_AND_TRANSFER: &str = r#" (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_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 $assert (param i32) @@ -2149,7 +2090,7 @@ const CODE_DESTROY_AND_TRANSFER: &str = r#" ;; Deploy the contract with the provided code hash. (call $assert (i32.eq - (call $ext_create + (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. @@ -2270,43 +2211,40 @@ 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::create( - 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()); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // 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#" @@ -2369,24 +2307,37 @@ const CODE_SELF_DESTRUCTING_CONSTRUCTOR: &str = r#" #[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::create( - Origin::signed(ALICE), - 100_000, - 100_000, - code_hash.into(), - vec![], - ), - "insufficient remaining balance" - ); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + 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() { + ExtBuilder::default().block_gas_limit(50).build().execute_with(|| { + 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 c6ef1bb3f561aea37d5527da9021b485a4ee4ed5..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; @@ -432,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 @@ -445,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. @@ -456,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, @@ -535,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); @@ -611,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. // @@ -707,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 @@ -812,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 deleted file mode 100644 index 635d62fd2c12603f1da55fd253938b949e07f6ac..0000000000000000000000000000000000000000 --- a/srml/council/src/lib.rs +++ /dev/null @@ -1,283 +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 . - -//! Council system: Handles the voting in and maintenance of council members. - -#![cfg_attr(not(feature = "std"), no_std)] -#![recursion_limit="128"] - -pub mod motions; -pub mod seats; - -pub use crate::seats::{Trait, Module, RawEvent, Event, VoteIndex}; - -/// Trait for type that can handle incremental changes to a set of account IDs. -pub trait OnMembersChanged { - /// A number of members `new` just joined the set and replaced some `old` ones. - fn on_members_changed(new: &[AccountId], old: &[AccountId]); -} - -impl OnMembersChanged for () { - fn on_members_changed(_new: &[T], _old: &[T]) {} -} - -#[cfg(test)] -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; - 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}; - pub use sr_primitives::Perbill; - pub use {seats, motions}; - use std::cell::RefCell; - - impl_outer_origin! { - pub enum Origin for Test { - motions - } - } - - impl_outer_event! { - pub enum Event for Test { - balances, democracy, seats, motions, - } - } - - impl_outer_dispatch! { - pub enum Call for Test where origin: Origin { - balances::Balances, - democracy::Democracy, - } - } - - 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); - } - - 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()) } - } - - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, Eq, PartialEq, 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(); - } - 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 WeightMultiplierUpdate = (); - type Event = 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 = 1; - 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 LaunchPeriod: u64 = 1; - pub const VotingPeriod: u64 = 3; - pub const MinimumDeposit: u64 = 1; - pub const EnactmentPeriod: u64 = 0; - pub const CooloffPeriod: u64 = 2; - } - impl democracy::Trait for Test { - type Proposal = Call; - type Event = Event; - type Currency = balances::Module; - type EnactmentPeriod = EnactmentPeriod; - type LaunchPeriod = LaunchPeriod; - type EmergencyVotingPeriod = VotingPeriod; - type VotingPeriod = VotingPeriod; - type MinimumDeposit = MinimumDeposit; - type ExternalOrigin = motions::EnsureProportionAtLeast<_1, _2, u64>; - type ExternalMajorityOrigin = motions::EnsureProportionAtLeast<_2, _3, u64>; - type EmergencyOrigin = motions::EnsureProportionAtLeast<_1, _1, u64>; - type CancellationOrigin = motions::EnsureProportionAtLeast<_2, _3, u64>; - type VetoOrigin = motions::EnsureMember; - type CooloffPeriod = CooloffPeriod; - } - parameter_types! { - pub const CandidacyBond: u64 = 3; - pub const CarryCount: u32 = 2; - pub const InactiveGracePeriod: u32 = 1; - pub const CouncilVotingPeriod: u64 = 4; - } - impl seats::Trait for Test { - type Event = Event; - type BadPresentation = (); - type BadReaper = (); - type BadVoterIndex = (); - type LoserCandidate = (); - type OnMembersChanged = CouncilMotions; - type CandidacyBond = CandidacyBond; - type VotingBond = VotingBond; - type VotingFee = VotingFee; - type PresentSlashPerVoter = PresentSlashPerVoter; - type CarryCount = CarryCount; - type InactiveGracePeriod = InactiveGracePeriod; - type CouncilVotingPeriod = CouncilVotingPeriod; - type DecayRatio = DecayRatio; - } - impl motions::Trait for Test { - type Origin = Origin; - type Proposal = Call; - type Event = Event; - } - - pub struct ExtBuilder { - balance_factor: u64, - decay_ratio: u32, - voting_fee: u64, - voter_bond: u64, - bad_presentation_punishment: u64, - with_council: bool, - } - - impl Default for ExtBuilder { - fn default() -> Self { - Self { - balance_factor: 1, - decay_ratio: 24, - voting_fee: 0, - voter_bond: 0, - bad_presentation_punishment: 1, - with_council: false, - } - } - } - - impl ExtBuilder { - pub fn with_council(mut self, council: bool) -> Self { - self.with_council = council; - self - } - 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 set_associated_consts(&self) { - 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); - } - pub fn build(self) -> runtime_io::TestExternalities { - self.set_associated_consts(); - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); - 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![], - }.assimilate_storage(&mut t).unwrap(); - seats::GenesisConfig:: { - active_council: if self.with_council { vec![ - (1, 10), - (2, 10), - (3, 10) - ] } else { vec![] }, - desired_seats: 2, - presentation_duration: 2, - term_duration: 5, - }.assimilate_storage(&mut t).unwrap(); - runtime_io::TestExternalities::new(t) - } - } - - pub type System = system::Module; - pub type Balances = balances::Module; - pub type Democracy = democracy::Module; - pub type Council = seats::Module; - pub type CouncilMotions = motions::Module; -} 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 cfac7fdfbcfe19e16842e55a11d33f39561f0c91..f1f10a7319ea7036680cb3788d199818f0725234 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -20,18 +20,21 @@ 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::{ + RuntimeDebug, + 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; @@ -46,8 +49,7 @@ pub type PropIndex = u32; pub type ReferendumIndex = u32; /// A value denoting the strength of conviction of a vote. -#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)] pub enum Conviction { /// 0.1x votes, unlocked. None, @@ -146,8 +148,7 @@ impl Bounded for Conviction { const MAX_RECURSION_LIMIT: u32 = 16; /// A number of lock periods, plus a vote, one way or the other. -#[derive(Copy, Clone, Eq, PartialEq, Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Copy, Clone, Eq, PartialEq, Default, RuntimeDebug)] pub struct Vote { pub aye: bool, pub conviction: Conviction, @@ -174,13 +175,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>; @@ -236,8 +230,7 @@ pub trait Trait: system::Trait + Sized { } /// Info regarding an ongoing referendum. -#[derive(Encode, Decode, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] pub struct ReferendumInfo { /// When voting on this referendum will end. end: BlockNumber, @@ -264,38 +257,38 @@ impl ReferendumInfo as Democracy { /// The number of (public) proposals that have been made so far. - pub PublicPropCount get(public_prop_count) build(|_| 0 as PropIndex) : PropIndex; + pub PublicPropCount get(fn public_prop_count) build(|_| 0 as PropIndex) : PropIndex; /// The public proposals. Unsorted. - pub PublicProps get(public_props): Vec<(PropIndex, T::Proposal, T::AccountId)>; + pub PublicProps get(fn public_props): Vec<(PropIndex, T::Proposal, T::AccountId)>; /// Those who have locked a deposit. - pub DepositOf get(deposit_of): map PropIndex => Option<(BalanceOf, Vec)>; + pub DepositOf get(fn deposit_of): map PropIndex => Option<(BalanceOf, Vec)>; /// The next free referendum index, aka the number of referenda started so far. - pub ReferendumCount get(referendum_count) build(|_| 0 as ReferendumIndex): ReferendumIndex; + pub ReferendumCount get(fn referendum_count) build(|_| 0 as ReferendumIndex): ReferendumIndex; /// The next referendum index that should be tallied. - pub NextTally get(next_tally) build(|_| 0 as ReferendumIndex): ReferendumIndex; + pub NextTally get(fn next_tally) build(|_| 0 as ReferendumIndex): ReferendumIndex; /// Information concerning any given referendum. - pub ReferendumInfoOf get(referendum_info): + pub ReferendumInfoOf get(fn referendum_info): map ReferendumIndex => Option<(ReferendumInfo)>; /// Queue of successful referenda to be dispatched. - pub DispatchQueue get(dispatch_queue): + pub DispatchQueue get(fn dispatch_queue): map T::BlockNumber => Vec>; /// Get the voters for the current proposal. - pub VotersFor get(voters_for): map ReferendumIndex => Vec; + pub VotersFor get(fn voters_for): map ReferendumIndex => Vec; /// Get the vote in a given referendum of a particular voter. The result is meaningful only /// if `voters_for` includes the voter when called with the referendum (you'll get the /// default `Vote` value otherwise). If you don't want to check `voters_for`, then you can /// also check for simple existence with `VoteOf::exists` first. - pub VoteOf get(vote_of): map (ReferendumIndex, T::AccountId) => Vote; + pub VoteOf get(fn vote_of): map (ReferendumIndex, T::AccountId) => Vote; /// Who is able to vote for whom. Value is the fund-holding account, key is the /// vote-transaction-sending account. - pub Proxy get(proxy): map T::AccountId => Option; + pub Proxy get(fn proxy): map T::AccountId => Option; /// Get the account (and lock periods) to which another account is delegating vote. - pub Delegations get(delegations): linked_map T::AccountId => (T::AccountId, Conviction); + pub Delegations get(fn delegations): linked_map T::AccountId => (T::AccountId, Conviction); /// True if the last referendum tabled was submitted externally. False if it was a public /// proposal. @@ -309,7 +302,7 @@ decl_storage! { /// A record of who vetoed what. Maps proposal hash to a possible existent block number /// (until when it may not be resubmitted) and who vetoed it. - pub Blacklist get(blacklist): map T::Hash => Option<(T::BlockNumber, Vec)>; + pub Blacklist get(fn blacklist): map T::Hash => Option<(T::BlockNumber, Vec)>; /// Record of all proposals that have been subject to emergency cancellation. pub Cancellations: map T::Hash => bool; @@ -361,7 +354,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 +375,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 +560,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 +607,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 +786,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 +925,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 +945,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) { @@ -977,14 +969,12 @@ impl OnFreeBalanceZero for Module { #[cfg(test)] 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 }; - use primitives::{H256, Blake2Hasher}; - use sr_primitives::{traits::{BlakeTwo256, IdentityLookup, Bounded}, testing::Header}; - use sr_primitives::Perbill; + use primitives::H256; + use sr_primitives::{traits::{BlakeTwo256, IdentityLookup, Bounded}, testing::Header, Perbill}; use balances::BalanceLock; use system::EnsureSignedBy; @@ -1023,7 +1013,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -1035,23 +1024,17 @@ mod tests { 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 = (); } parameter_types! { pub const LaunchPeriod: u64 = 2; @@ -1090,7 +1073,7 @@ mod tests { type CooloffPeriod = CooloffPeriod; } - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); balances::GenesisConfig::{ balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], @@ -1106,7 +1089,7 @@ mod tests { #[test] fn params_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Democracy::referendum_count(), 0); assert_eq!(Balances::free_balance(&42), 0); assert_eq!(Balances::total_issuance(), 210); @@ -1138,7 +1121,7 @@ mod tests { #[test] fn external_and_public_interleaving_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(Democracy::external_propose( Origin::signed(2), @@ -1251,7 +1234,7 @@ mod tests { #[test] fn emergency_cancel_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); let r = Democracy::inject_referendum( 2, @@ -1280,7 +1263,7 @@ mod tests { #[test] fn veto_external_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(Democracy::external_propose( Origin::signed(2), @@ -1340,7 +1323,7 @@ mod tests { #[test] fn external_referendum_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_noop!(Democracy::external_propose( Origin::signed(1), @@ -1369,7 +1352,7 @@ mod tests { #[test] fn external_majority_referendum_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_noop!(Democracy::external_propose_majority( Origin::signed(1), @@ -1394,7 +1377,7 @@ mod tests { #[test] fn external_default_referendum_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_noop!(Democracy::external_propose_default( Origin::signed(3), @@ -1419,7 +1402,7 @@ mod tests { #[test] fn fast_track_referendum_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); let h = BlakeTwo256::hash_of(&set_balance_proposal(2)); assert_noop!(Democracy::fast_track(Origin::signed(5), h, 3, 2), "no proposal made"); @@ -1443,7 +1426,7 @@ mod tests { #[test] fn fast_track_referendum_fails_when_no_simple_majority() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); let h = BlakeTwo256::hash_of(&set_balance_proposal(2)); assert_ok!(Democracy::external_propose( @@ -1459,7 +1442,7 @@ mod tests { #[test] fn locked_for_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); assert_ok!(propose_set_balance(1, 2, 2)); assert_ok!(propose_set_balance(1, 4, 4)); @@ -1472,7 +1455,7 @@ mod tests { #[test] fn single_proposal_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); assert!(Democracy::referendum_info(0).is_none()); @@ -1519,7 +1502,7 @@ mod tests { #[test] fn cancel_queued_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1543,7 +1526,7 @@ mod tests { #[test] fn proxy_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Democracy::proxy(10), None); assert_ok!(Democracy::set_proxy(Origin::signed(1), 10)); assert_eq!(Democracy::proxy(10), Some(1)); @@ -1573,7 +1556,7 @@ mod tests { #[test] fn single_proposal_should_work_with_proxy() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1593,7 +1576,7 @@ mod tests { #[test] fn single_proposal_should_work_with_delegation() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1618,7 +1601,7 @@ mod tests { #[test] fn single_proposal_should_work_with_cyclic_delegation() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1645,7 +1628,7 @@ mod tests { #[test] /// If transactor already voted, delegated vote is overwriten. fn single_proposal_should_work_with_vote_and_delegation() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1671,7 +1654,7 @@ mod tests { #[test] fn single_proposal_should_work_with_undelegation() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1700,7 +1683,7 @@ mod tests { #[test] /// If transactor voted, delegated vote is overwriten. fn single_proposal_should_work_with_delegation_and_vote() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1731,7 +1714,7 @@ mod tests { #[test] fn deposit_for_proposals_should_be_taken() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); assert_ok!(propose_set_balance(1, 2, 5)); assert_ok!(Democracy::second(Origin::signed(2), 0)); @@ -1746,7 +1729,7 @@ mod tests { #[test] fn deposit_for_proposals_should_be_returned() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); assert_ok!(propose_set_balance(1, 2, 5)); assert_ok!(Democracy::second(Origin::signed(2), 0)); @@ -1762,7 +1745,7 @@ mod tests { #[test] fn proposal_with_deposit_below_minimum_should_not_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); assert_noop!(propose_set_balance(1, 2, 0), "value too low"); }); @@ -1770,7 +1753,7 @@ mod tests { #[test] fn poor_proposer_should_not_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); assert_noop!(propose_set_balance(1, 2, 11), "proposer\'s balance too low"); }); @@ -1778,7 +1761,7 @@ mod tests { #[test] fn poor_seconder_should_not_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); assert_ok!(propose_set_balance(2, 2, 11)); assert_noop!(Democracy::second(Origin::signed(1), 0), "seconder\'s balance too low"); @@ -1787,7 +1770,7 @@ mod tests { #[test] fn runners_up_should_come_after() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 2)); assert_ok!(propose_set_balance(1, 4, 4)); @@ -1803,7 +1786,7 @@ mod tests { #[test] fn simple_passing_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1826,7 +1809,7 @@ mod tests { #[test] fn cancel_referendum_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1846,7 +1829,7 @@ mod tests { #[test] fn simple_failing_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1869,7 +1852,7 @@ mod tests { #[test] fn controversial_voting_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1895,7 +1878,7 @@ mod tests { #[test] fn delayed_enactment_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1923,7 +1906,7 @@ mod tests { #[test] fn controversial_low_turnout_voting_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1945,7 +1928,7 @@ mod tests { #[test] fn passing_low_turnout_voting_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Balances::free_balance(&42), 0); assert_eq!(Balances::total_issuance(), 210); @@ -1971,7 +1954,7 @@ mod tests { #[test] fn lock_voting_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); let r = Democracy::inject_referendum( 1, @@ -2031,7 +2014,7 @@ mod tests { #[test] fn lock_voting_should_work_with_delegation() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( 1, diff --git a/srml/democracy/src/vote_threshold.rs b/srml/democracy/src/vote_threshold.rs index d304c36f32c95d7ba7523c0576f0bad4deed9d09..61e7e6535941ab6d797c6f9bbdcc14eefc63e0f4 100644 --- a/srml/democracy/src/vote_threshold.rs +++ b/srml/democracy/src/vote_threshold.rs @@ -23,8 +23,8 @@ use sr_primitives::traits::{Zero, IntegerSquareRoot}; use rstd::ops::{Add, Mul, Div, Rem}; /// A means of determining if a vote is past pass threshold. -#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] +#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, sr_primitives::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum VoteThreshold { /// A supermajority of approvals is needed to pass this vote. SuperMajorityApprove, 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..f56c5a4ec3cb51dcfe8f6908a51989a0d4ca7f1e --- /dev/null +++ b/srml/elections-phragmen/src/lib.rs @@ -0,0 +1,1639 @@ +// 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 rstd::prelude::*; +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(fn desired_members) config(): u32; + /// Number of runners_up to keep. + pub DesiredRunnersUp get(fn desired_runners_up) config(): u32; + /// How long each seat is kept. This defines the next block number at which an election + /// round will happen. If set to zero, no elections are ever triggered and the module will + /// be in passive mode. In that case only a member set defined in at genesis can exist. + pub TermDuration get(fn term_duration) config(): T::BlockNumber; + + // ---- State + /// The current elected membership. Sorted based on account id. + pub Members get(fn members) config(): Vec; + /// The current runners_up. Sorted based on low to high merit (worse to best runner). + pub RunnersUp get(fn runners_up): Vec; + /// The total number of vote rounds that have happened, excluding the upcoming one. + pub ElectionRounds get(fn election_rounds): u32 = Zero::zero(); + + /// Votes of a particular voter, with the round index of the votes. + pub VotesOf get(fn votes_of): linked_map T::AccountId => Vec; + /// Locked stake of a voter. + pub StakeOf get(fn 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(fn 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 !Self::term_duration().is_zero() { + 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 primitives::H256; + 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 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; + } + + impl balances::Trait for Test { + type Balance = u64; + type OnNewAccount = (); + type OnFreeBalanceZero = (); + type Event = Event; + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + } + + 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, + term_duration: u64, + desired_runners_up: u32, + members: Vec, + } + + impl Default for ExtBuilder { + fn default() -> Self { + Self { + balance_factor: 1, + voter_bond: 2, + desired_runners_up: 0, + term_duration: 5, + members: vec![], + } + } + } + + 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 term_duration(mut self, duration: u64) -> Self { + self.term_duration = duration; + self + } + pub fn members(mut self, members: Vec) -> Self { + self.members = members; + 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: self.members, + desired_members: 2, + desired_runners_up: self.desired_runners_up, + term_duration: self.term_duration, + }), + }.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() { + ExtBuilder::default().build().execute_with(|| { + 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 passive_module_should_work() { + ExtBuilder::default() + .term_duration(0) + .members(vec![1, 2, 3]) + .build() + .execute_with(|| + { + System::set_block_number(1); + assert_eq!(Elections::term_duration(), 0); + assert_eq!(Elections::desired_members(), 2); + assert_eq!(Elections::election_rounds(), 0); + + assert_eq!(Elections::members(), vec![1, 2, 3]); + assert_eq!(Elections::runners_up(), vec![]); + + assert_eq!(Elections::candidates(), vec![]); + assert_eq!(all_voters(), vec![]); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![1, 2, 3]); + assert_eq!(Elections::runners_up(), vec![]); + }); + } + + #[test] + fn simple_candidate_submission_should_work() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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. + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().voter_bond(8).build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().voter_bond(8).build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + assert_noop!(Elections::remove_voter(Origin::signed(3)), "must be a voter"); + }); + } + + #[test] + fn dupe_remove_should_fail() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + Elections::report_defunct_voter(Origin::signed(1), 2), + "reporter must be a voter", + ); + }); + } + + #[test] + fn can_detect_defunct_voter() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + 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() { + ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + 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() { + ExtBuilder::default().desired_runners_up(1).build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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. + ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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 a82b3fab7ef1d96810b0d44c022d5011aa539ab4..87e29f3b1449895ed94bfc4570c914531af38103 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -24,11 +24,13 @@ #![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::{ + RuntimeDebug, + 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 +40,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. @@ -96,8 +101,7 @@ use system::{self, ensure_signed, ensure_root}; // entries before they increase the capacity. /// The activity status of a voter. -#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Default, RuntimeDebug)] pub struct VoterInfo { /// Last VoteIndex in which this voter assigned (or initialized) approvals. last_active: VoteIndex, @@ -112,8 +116,7 @@ pub struct VoterInfo { } /// Used to demonstrate the status of a particular index in the global voter list. -#[derive(PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, RuntimeDebug)] pub enum CellStatus { /// Any out of bound index. Means a push a must happen to the chunk pointed by `NextVoterSet`. /// Voting fee is applied in case a new chunk is created. @@ -126,29 +129,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 +181,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,55 +212,59 @@ 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; + pub PresentationDuration get(fn presentation_duration) config(): T::BlockNumber; /// How long each position is active for. - pub TermDuration get(term_duration) config(): T::BlockNumber; + pub TermDuration get(fn term_duration) config(): T::BlockNumber; /// Number of accounts that should constitute the collective. - pub DesiredSeats get(desired_seats) config(): u32; + pub DesiredSeats get(fn 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). - pub Members get(members) config(): Vec<(T::AccountId, T::BlockNumber)>; + + /// 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(fn 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; + pub VoteCount get(fn 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`. - 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. - pub RegisterInfoOf get(candidate_reg_info): map T::AccountId => Option<(VoteIndex, u32)>; + + // 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(fn 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. + pub RegisterInfoOf get(fn candidate_reg_info): map T::AccountId => Option<(VoteIndex, u32)>; /// Basic information about a voter. - pub VoterInfoOf get(voter_info): map T::AccountId => Option>>; + pub VoterInfoOf get(fn voter_info): map T::AccountId => Option>>; /// The present voter list (chunked and capped at [`VOTER_SET_SIZE`]). - pub Voters get(voters): map SetIndex => Vec>; + pub Voters get(fn voters): map SetIndex => Vec>; /// the next free set to store a voter in. This will keep growing. - pub NextVoterSet get(next_nonfull_voter_set): SetIndex = 0; + pub NextVoterSet get(fn next_nonfull_voter_set): SetIndex = 0; /// Current number of Voters. - pub VoterCount get(voter_count): SetIndex = 0; + pub VoterCount get(fn voter_count): SetIndex = 0; /// The present candidate list. - pub Candidates get(candidates): Vec; // has holes + pub Candidates get(fn candidates): Vec; // has holes /// Current number of active candidates - pub CandidateCount get(candidate_count): u32; + pub CandidateCount get(fn 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 + pub NextFinalize get(fn 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. + /// Sorted from low to high. + pub Leaderboard get(fn leaderboard): Option, T::AccountId)> >; /// Who is able to vote for whom. Value is the fund-holding account, key is the /// vote-transaction-sending account. - pub Proxy get(proxy): map T::AccountId => Option; + pub Proxy get(fn proxy): map T::AccountId => Option; } } @@ -294,6 +298,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 +313,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 +340,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 +361,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 +394,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 +434,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 +511,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 +530,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 +545,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 +702,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 +744,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 +800,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 +814,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 +830,7 @@ impl Module { &who, locked_balance, T::BlockNumber::max_value(), - WithdrawReasons::except(WithdrawReason::TransactionPayment), + WithdrawReasons::all(), ); >::insert( @@ -815,28 +852,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. @@ -906,9 +948,11 @@ impl Module { } } // 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)); @@ -918,18 +962,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. @@ -974,8 +1006,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() { @@ -995,13 +1027,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 { @@ -1020,7 +1054,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 @@ -1055,7 +1088,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, @@ -1117,1814 +1152,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; - 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; - } - - 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, - 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() - } - } - - 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() - } - - fn balances(who: &u64) -> (u64, u64) { - (Balances::free_balance(who), Balances::reserved_balance(who)) - } - - #[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); - }); - } - - #[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))); - }); - } - - #[test] - fn 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)); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![false, true, true, 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), 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)); - }); - } -} diff --git a/srml/elections/src/mock.rs b/srml/elections/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..77b13d74a139f42d7aab7ad6a76741cdd70c8342 --- /dev/null +++ b/srml/elections/src/mock.rs @@ -0,0 +1,284 @@ +// 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 primitives::H256; +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 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; +} +impl balances::Trait for Test { + type Balance = u64; + type OnNewAccount = (); + type OnFreeBalanceZero = (); + type Event = Event; + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; +} + +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(); + t.execute_with(|| { + >::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..c9bb054ab23538edf62dfbcfb67b648f278c7a96 --- /dev/null +++ b/srml/elections/src/tests.rs @@ -0,0 +1,1681 @@ +// 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}; + +#[test] +fn params_should_work() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + // 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().voting_fee(5).voter_bond(2).build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().voter_bond(2).build().execute_with(|| { + 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() { + ExtBuilder::default().voter_bond(2).build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().voter_bond(2).build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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(); + + t.execute_with(|| { + 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(); + + t.execute_with(|| { + 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(); + + t.execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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| { + ExtBuilder::default() + .voting_fee(5) + .voter_bond(2) + .bad_presentation_punishment(p) + .build() + .execute_with(|| { + System::set_block_number(4); + let _ = Balances::make_free_balance_be(&1, 15); + assert!(!Elections::presentation_active()); + + // -3 + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_eq!(Balances::free_balance(&1), 12); + // -2 -5 + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 15)); + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().desired_seats(1).build().execute_with(|| { + 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() { + ExtBuilder::default().balance_factor(10).build().execute_with(|| { + 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() { + ExtBuilder::default().balance_factor(10).build().execute_with(|| { + 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() { + ExtBuilder::default() + .voter_bond(0) + .voting_fee(0) + .balance_factor(10) + .build() + .execute_with(|| { + 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() { + ExtBuilder::default().build().execute_with(|| { + 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() { + ExtBuilder::default().decay_ratio(0).build().execute_with(|| { + 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 73e280605a1c79fe212b8541c29a547cebc57f25..695e0602fb32757b203213c7ad7a18d89c5dcdfd 100644 --- a/srml/example/Cargo.toml +++ b/srml/example/Cargo.toml @@ -5,14 +5,14 @@ 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 } -rio = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives" } @@ -23,9 +23,9 @@ std = [ "serde", "codec/std", "sr-primitives/std", - "srml-support/std", + "support/std", "system/std", "balances/std", - "rio/std", + "runtime-io/std", "rstd/std" ] diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index 3de961f5cdcf5f4c027ab0346d8022a6ec48605c..c9d9d93cc7334f2f055731150dee33692a6dcd8e 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -254,16 +254,55 @@ #![cfg_attr(not(feature = "std"), no_std)] use rstd::marker::PhantomData; -use srml_support::{StorageValue, dispatch::Result, decl_module, decl_storage, decl_event}; +use support::{dispatch::Result, decl_module, decl_storage, decl_event}; use system::{ensure_signed, ensure_root}; use codec::{Encode, Decode}; use sr_primitives::{ - traits::{SignedExtension, DispatchError, Bounded}, - transaction_validity::ValidTransaction, - weights::{SimpleDispatchInfo, DispatchInfo}, + traits::{SignedExtension, Bounded, SaturatedConversion}, + weights::{SimpleDispatchInfo, DispatchInfo, DispatchClass, ClassifyDispatch, WeighData, Weight}, + transaction_validity::{ + ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity, + }, }; -/// Our module's configuration trait. All our types and consts go in here. If the +// A custom weight calculator tailored for the dispatch call `set_dummy()`. This actually examines +// the arguments and makes a decision based upon them. +// +// The `WeightData` trait has access to the arguments of the dispatch that it wants to assign a +// weight to. Nonetheless, the trait itself can not make any assumptions about what that type +// generic type of the arguments, `T`, is. Based on our needs, we could replace `T` with a more +// concrete type while implementing the trait. The `decl_module!` expects whatever implements +// `WeighData` to replace `T` with a tuple of the dispatch arguments. This is exactly how we will +// craft the implementation below. +// +// The rules of `WeightForSetDummy` is as follows: +// - The final weight of each dispatch is calculated as the argument of the call multiplied by the +// parameter given to the `WeightForSetDummy`'s constructor. +// - assigns a dispatch class `operational` if the argument of the call is more than 1000. +struct WeightForSetDummy(BalanceOf); + +impl WeighData<(&BalanceOf,)> for WeightForSetDummy +{ + fn weigh_data(&self, target: (&BalanceOf,)) -> Weight { + let multiplier = self.0; + (*target.0 * multiplier).saturated_into::() + } +} + +impl ClassifyDispatch<(&BalanceOf,)> for WeightForSetDummy { + fn classify_dispatch(&self, target: (&BalanceOf,)) -> DispatchClass { + if *target.0 > >::from(1000u32) { + DispatchClass::Operational + } else { + DispatchClass::Normal + } + } +} + +/// A type alias for the balance type from this module's point of view. +type BalanceOf = ::Balance; + +/// Our module's configuration trait. All our types and constants go in here. If the /// module is dependent on specific other modules, then their configuration traits /// should be added to our implied traits list. /// @@ -279,7 +318,7 @@ decl_storage! { // keep things around between blocks. trait Store for Module as Example { // Any storage declarations of the form: - // `pub? Name get(getter_name)? [config()|config(myname)] [build(|_| {...})] : (= )?;` + // `pub? Name get(fn getter_name)? [config()|config(myname)] [build(|_| {...})] : (= )?;` // where `` is either: // - `Type` (a basic value item); or // - `map KeyType => ValueType` (a map item). @@ -292,7 +331,7 @@ decl_storage! { // - `Foo::put(1); Foo::get()` returns `1`; // - `Foo::kill(); Foo::get()` returns `0` (u32::default()). // e.g. Foo: u32; - // e.g. pub Bar get(bar): map T::AccountId => Vec<(T::Balance, u64)>; + // e.g. pub Bar get(fn bar): map T::AccountId => Vec<(T::Balance, u64)>; // // For basic value items, you'll get a type which implements // `support::StorageValue`. For map items, you'll get a type which @@ -301,13 +340,13 @@ decl_storage! { // If they have a getter (`get(getter_name)`), then your module will come // equipped with `fn getter_name() -> Type` for basic value items or // `fn getter_name(key: KeyType) -> ValueType` for map items. - Dummy get(dummy) config(): Option; + Dummy get(fn dummy) config(): Option; // A map that has enumerable entries. - Bar get(bar) config(): linked_map T::AccountId => T::Balance; + Bar get(fn bar) config(): linked_map T::AccountId => T::Balance; // this one uses the default, we'll demonstrate the usage of 'mutate' API. - Foo get(foo) config(): T::Balance; + Foo get(fn foo) config(): T::Balance; } } @@ -363,7 +402,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. @@ -453,6 +492,7 @@ decl_module! { // without worrying about gameability or attack scenarios. // If you not specify `Result` explicitly as return value, it will be added automatically // for you and `Ok(())` will be returned. + #[weight = WeightForSetDummy::(>::from(100u32))] fn set_dummy(origin, #[compact] new_value: T::Balance) { ensure_root(origin)?; // Put the new value into storage. @@ -544,10 +584,9 @@ impl Module { #[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") + write!(f, "WatchDummy") } } @@ -561,7 +600,7 @@ impl SignedExtension for WatchDummy { 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, @@ -569,20 +608,22 @@ impl SignedExtension for WatchDummy { call: &Self::Call, _info: DispatchInfo, len: usize, - ) -> rstd::result::Result { + ) -> TransactionValidity { // if the transaction is too big, just drop it. - if len > 200 { return Err(DispatchError::Exhausted) } + if len > 200 { + return InvalidTransaction::ExhaustsResources.into() + } // check for `set_dummy` match call { Call::set_dummy(..) => { - rio::print("set_dummy was received."); + 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()) + _ => Ok(Default::default()), } } } @@ -591,13 +632,13 @@ impl SignedExtension for WatchDummy { mod tests { use super::*; - use srml_support::{assert_ok, impl_outer_origin, parameter_types}; - use rio::with_externalities; - use primitives::{H256, Blake2Hasher}; + use support::{assert_ok, impl_outer_origin, parameter_types}; + use primitives::H256; // 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. use sr_primitives::{ - Perbill, traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup}, testing::Header + Perbill, weights::GetDispatchInfo, testing::Header, + traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup}, }; impl_outer_origin! { @@ -625,7 +666,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -637,23 +677,17 @@ mod tests { 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 = (); @@ -662,7 +696,7 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> rio::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(); @@ -677,7 +711,7 @@ mod tests { #[test] fn it_works_for_optional_value() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // Check that GenesisBuilder works properly. assert_eq!(Example::dummy(), Some(42)); @@ -698,7 +732,7 @@ mod tests { #[test] fn it_works_for_default_value() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Example::foo(), 24); assert_ok!(Example::accumulate_foo(Origin::signed(1), 1)); assert_eq!(Example::foo(), 25); @@ -707,18 +741,34 @@ mod tests { #[test] fn signed_ext_watch_dummy_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let call = >::set_dummy(10); let info = DispatchInfo::default(); assert_eq!( - WatchDummy::(PhantomData).validate(&1, &call, info, 150).unwrap().priority, - Bounded::max_value() + WatchDummy::(PhantomData).validate(&1, &call, info, 150) + .unwrap() + .priority, + Bounded::max_value(), ); assert_eq!( WatchDummy::(PhantomData).validate(&1, &call, info, 250), - Err(DispatchError::Exhausted) + InvalidTransaction::ExhaustsResources.into(), ); }) } + + #[test] + fn weights_work() { + // must have a default weight. + let default_call = >::accumulate_dummy(10); + let info = default_call.get_dispatch_info(); + // aka. `let info = as GetDispatchInfo>::get_dispatch_info(&default_call);` + assert_eq!(info.weight, 10_000); + + // must have a custom weight of `100 * arg = 2000` + let custom_call = >::set_dummy(20); + let info = custom_call.get_dispatch_info(); + assert_eq!(info.weight, 2000); + } } diff --git a/srml/executive/Cargo.toml b/srml/executive/Cargo.toml index e398a951896ea6e59767981a72d2316040ae1c65..92191a7aac4db28dc3577a1379a0642afb8c2b00 100644 --- a/srml/executive/Cargo.toml +++ b/srml/executive/Cargo.toml @@ -5,28 +5,29 @@ 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" } +transaction-payment = { package = "srml-transaction-payment", path = "../transaction-payment" } [features] 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 d25cacf4467fd29d8835a7ca01bb619e142e6b09..401f07d2069e9dcca34c0725da7904aef7bba928 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,23 @@ 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 primitives::H256; + 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 +319,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 +338,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; @@ -398,7 +347,6 @@ mod tests { type Header = Header; type Event = MetaEvent; type BlockHashCount = BlockHashCount; - type WeightMultiplierUpdate = (); type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; @@ -408,32 +356,39 @@ mod tests { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 10; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Runtime { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); type Event = MetaEvent; - type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; + } + + parameter_types! { + pub const TransactionBaseFee: u64 = 10; + pub const TransactionByteFee: u64 = 0; + } + impl transaction_payment::Trait for Runtime { + type Currency = Balances; + type OnTransactionPayment = (); type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; type WeightToFee = ConvertInto; + type FeeMultiplierUpdate = (); } 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(), } } } @@ -442,9 +397,9 @@ mod tests { system::CheckEra, system::CheckNonce, system::CheckWeight, - balances::TakeFees + transaction_payment::ChargeTransactionPayment ); - 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 { @@ -452,7 +407,7 @@ mod tests { system::CheckEra::from(Era::Immortal), system::CheckNonce::from(nonce), system::CheckWeight::new(), - balances::TakeFees::from(fee) + transaction_payment::ChargeTransactionPayment::from(fee) ) } @@ -467,10 +422,10 @@ 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, || { + let mut t = runtime_io::TestExternalities::new(t); + t.execute_with(|| { Executive::initialize_block(&Header::new( 1, H256::default(), @@ -479,13 +434,13 @@ 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); }); } - fn new_test_ext(balance_factor: u64) -> runtime_io::TestExternalities { + fn new_test_ext(balance_factor: u64) -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); balances::GenesisConfig:: { balances: vec![(1, 111 * balance_factor)], @@ -496,12 +451,12 @@ mod tests { #[test] fn block_import_works() { - with_externalities(&mut new_test_ext(1), || { + new_test_ext(1).execute_with(|| { Executive::execute_block(Block { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("3e51b47b6cc8449eece93eee4b01f03b00a0ca7981c0b6c0447b6e0d50ca886d").into(), + state_root: hex!("f0d1d66255c2e5b40580eb8b93ddbe732491478487f85e358e1d167d369e398e").into(), extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), digest: Digest { logs: vec![], }, }, @@ -513,7 +468,7 @@ mod tests { #[test] #[should_panic] fn block_import_of_bad_state_root_fails() { - with_externalities(&mut new_test_ext(1), || { + new_test_ext(1).execute_with(|| { Executive::execute_block(Block { header: Header { parent_hash: [69u8; 32].into(), @@ -530,7 +485,7 @@ mod tests { #[test] #[should_panic] fn block_import_of_bad_extrinsic_root_fails() { - with_externalities(&mut new_test_ext(1), || { + new_test_ext(1).execute_with(|| { Executive::execute_block(Block { header: Header { parent_hash: [69u8; 32].into(), @@ -548,8 +503,8 @@ 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)); - with_externalities(&mut t, || { + let xt = sr_primitives::testing::TestXt(sign_extra(1, 30, 0), Call::Balances(BalancesCall::transfer(33, 69))); + t.execute_with(|| { Executive::initialize_block(&Header::new( 1, H256::default(), @@ -566,12 +521,12 @@ 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(); let num_to_exhaust_block = limit / encoded_len; - with_externalities(&mut t, || { + t.execute_with(|| { Executive::initialize_block(&Header::new( 1, H256::default(), @@ -582,14 +537,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())); } } }); @@ -597,18 +557,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, || { + t.execute_with(|| { 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()); @@ -623,13 +583,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)); + t.execute_with(|| { + 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") } + ) + ) + ); }); } @@ -638,15 +604,18 @@ mod tests { let id: LockIdentifier = *b"0 "; let execute_with_lock = |lock: WithdrawReasons| { let mut t = new_test_ext(1); - with_externalities(&mut t, || { + t.execute_with(|| { as LockableCurrency>::set_lock( 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, @@ -657,11 +626,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 1ed9d07dbbf38787218853e562360e0fdb90a8d0..5e973cd43235d3002e89b8badfe1c7cee38e5bd3 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")] @@ -97,17 +96,17 @@ pub trait Trait: SystemTrait { decl_storage! { trait Store for Module as Timestamp { /// Recent hints. - RecentHints get(recent_hints) build(|_| vec![T::BlockNumber::zero()]): Vec; + RecentHints get(fn recent_hints) build(|_| vec![T::BlockNumber::zero()]): Vec; /// Ordered recent hints. - OrderedHints get(ordered_hints) build(|_| vec![T::BlockNumber::zero()]): Vec; + OrderedHints get(fn ordered_hints) build(|_| vec![T::BlockNumber::zero()]): Vec; /// The median. - Median get(median) build(|_| T::BlockNumber::zero()): T::BlockNumber; + Median get(fn median) build(|_| T::BlockNumber::zero()): T::BlockNumber; /// Final hint to apply in the block. `None` means "same as parent". Update: Option; // when initialized through config this is set in the beginning. - Initialized get(initialized) build(|_| false): bool; + Initialized get(fn initialized) build(|_| false): bool; } } @@ -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,13 @@ impl ProvideInherent for Module { mod tests { use super::*; - use sr_io::{with_externalities, TestExternalities}; + use runtime_io::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 sr_primitives::{ + testing::Header, Perbill, + traits::{BlakeTwo256, IdentityLookup, OnFinalize, Header as HeaderT}, + }; + use support::{assert_ok, impl_outer_origin, parameter_types}; use srml_system as system; use std::cell::RefCell; @@ -315,7 +298,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -339,7 +321,7 @@ mod tests { #[test] fn median_works() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + TestExternalities::new(t).execute_with(|| { FinalityTracker::update_hint(Some(500)); assert_eq!(FinalityTracker::median(), 250); assert!(NOTIFICATIONS.with(|n| n.borrow().is_empty())); @@ -349,7 +331,7 @@ mod tests { #[test] fn notifies_when_stalled() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + TestExternalities::new(t).execute_with(|| { let mut parent_hash = System::parent_hash(); for i in 2..106 { System::initialize(&i, &parent_hash, &Default::default(), &Default::default()); @@ -368,7 +350,7 @@ mod tests { #[test] fn recent_notifications_prevent_stalling() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + TestExternalities::new(t).execute_with(|| { let mut parent_hash = System::parent_hash(); for i in 2..106 { System::initialize(&i, &parent_hash, &Default::default(), &Default::default()); 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 016e39127fec76f89889f268ab459af68960fefa..fdbb57f56fc990d68f02309333e09a79d32556e6 100644 --- a/srml/generic-asset/src/lib.rs +++ b/srml/generic-asset/src/lib.rs @@ -153,12 +153,13 @@ use codec::{Decode, Encode, HasCompact, Input, Output, Error}; +use sr_primitives::RuntimeDebug; use sr_primitives::traits::{ - CheckedAdd, CheckedSub, MaybeSerializeDebug, Member, One, Saturating, SimpleArithmetic, Zero, Bounded + CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Member, One, Saturating, SimpleArithmetic, Zero, Bounded }; use rstd::prelude::*; -use rstd::{cmp, result}; +use rstd::{cmp, result, fmt::Debug}; use support::dispatch::Result; use support::{ decl_event, decl_module, decl_storage, ensure, @@ -166,7 +167,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}; @@ -181,7 +182,8 @@ pub trait Trait: system::Trait { + SimpleArithmetic + Default + Copy - + MaybeSerializeDebug; + + MaybeSerializeDeserialize + + Debug; type AssetId: Parameter + Member + SimpleArithmetic + Default + Copy; type Event: From> + Into<::Event>; } @@ -192,7 +194,8 @@ pub trait Subtrait: system::Trait { + SimpleArithmetic + Default + Copy - + MaybeSerializeDebug; + + MaybeSerializeDeserialize + + Debug; type AssetId: Parameter + Member + SimpleArithmetic + Default + Copy; } @@ -202,8 +205,7 @@ impl Subtrait for T { } /// Asset creation options. -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Clone, Encode, Decode, PartialEq, Eq)] +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub struct AssetOptions { /// Initial issuance of this asset. All deposit to the creater of the asset. #[codec(compact)] @@ -213,8 +215,7 @@ pub struct AssetOptions { } /// Owner of an asset. -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Clone, Encode, Decode, PartialEq, Eq)] +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub enum Owner { /// No owner. None, @@ -229,8 +230,7 @@ impl Default for Owner { } /// Asset permissions -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Clone, Encode, Decode, PartialEq, Eq)] +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub struct PermissionsV1 { /// Who have permission to update asset permission pub update: Owner, @@ -240,16 +240,14 @@ pub struct PermissionsV1 { pub burn: Owner, } -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Clone, Encode, Decode, PartialEq, Eq)] +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)] #[repr(u8)] enum PermissionVersionNumber { V1 = 0, } /// Versioned asset permission -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq, RuntimeDebug)] pub enum PermissionVersions { V1(PermissionsV1), } @@ -324,7 +322,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 { @@ -435,8 +433,7 @@ decl_module! { } } -#[derive(Encode, Decode, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] pub struct BalanceLock { pub id: LockIdentifier, pub amount: Balance, @@ -447,7 +444,7 @@ pub struct BalanceLock { decl_storage! { trait Store for Module as GenericAsset { /// Total issuance of a given asset. - pub TotalIssuance get(total_issuance) build(|config: &GenesisConfig| { + pub TotalIssuance get(fn total_issuance) build(|config: &GenesisConfig| { let issuance = config.initial_balance * (config.endowed_accounts.len() as u32).into(); config.assets.iter().map(|id| (id.clone(), issuance)).collect::>() }): map T::AssetId => T::Balance; @@ -459,34 +456,29 @@ decl_storage! { pub ReservedBalance: double_map T::AssetId, twox_128(T::AccountId) => T::Balance; /// Next available ID for user-created asset. - pub NextAssetId get(next_asset_id) config(): T::AssetId; + pub NextAssetId get(fn next_asset_id) config(): T::AssetId; /// Permission options for a given asset. - pub Permissions get(get_permission): map T::AssetId => PermissionVersions; + pub Permissions get(fn get_permission): map T::AssetId => PermissionVersions; /// Any liquidity locks on some account balances. - pub Locks get(locks): map T::AccountId => Vec>; + pub Locks get(fn locks): map T::AccountId => Vec>; /// The identity of the asset which is the one that is designated for the chain's staking system. - pub StakingAssetId get(staking_asset_id) config(): T::AssetId; + pub StakingAssetId get(fn staking_asset_id) config(): T::AssetId; /// The identity of the asset which is the one that is designated for paying the chain's transaction fee. - pub SpendingAssetId get(spending_asset_id) config(): T::AssetId; + pub SpendingAssetId get(fn spending_asset_id) config(): T::AssetId; } add_extra_genesis { config(assets): Vec; 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); }); }); }); @@ -1061,7 +1053,6 @@ impl system::Trait for ElevatedTrait { type MaximumBlockWeight = T::MaximumBlockWeight; type MaximumBlockLength = T::MaximumBlockLength; type AvailableBlockRatio = T::AvailableBlockRatio; - type WeightMultiplierUpdate = (); type BlockHashCount = T::BlockHashCount; type Version = T::Version; } @@ -1071,8 +1062,7 @@ impl Trait for ElevatedTrait { type Event = (); } -#[derive(Encode, Decode, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] pub struct AssetCurrency(rstd::marker::PhantomData, rstd::marker::PhantomData); impl Currency for AssetCurrency @@ -1206,7 +1196,9 @@ where Self::free_balance(who) .checked_sub(&value) .map_or(false, |new_balance| - >::ensure_can_withdraw(&U::asset_id(), who, value, WithdrawReason::Reserve, new_balance).is_ok() + >::ensure_can_withdraw( + &U::asset_id(), who, value, WithdrawReason::Reserve, new_balance + ).is_ok() ) } @@ -1260,7 +1252,7 @@ impl AssetIdProvider for SpendingAssetIdProvider { impl LockableCurrency for AssetCurrency> where T: Trait, - T::Balance: MaybeSerializeDebug, + T::Balance: MaybeSerializeDeserialize + Debug, { type Moment = T::BlockNumber; diff --git a/srml/generic-asset/src/mock.rs b/srml/generic-asset/src/mock.rs index 7e47de0b36537d18076d86461432afe5db8e52a6..57b13760fa03d2ed90d59dd8a33dfb9abbc62b77 100644 --- a/srml/generic-asset/src/mock.rs +++ b/srml/generic-asset/src/mock.rs @@ -25,7 +25,7 @@ use sr_primitives::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; -use primitives::{Blake2Hasher, H256}; +use primitives::H256; use support::{parameter_types, impl_outer_event, impl_outer_origin}; use super::*; @@ -56,7 +56,6 @@ impl system::Trait for Test { type Lookup = IdentityLookup; type Header = Header; type Event = TestEvent; - type WeightMultiplierUpdate = (); type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; @@ -118,7 +117,7 @@ impl ExtBuilder { } // builds genesis config - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig:: { @@ -137,7 +136,7 @@ impl ExtBuilder { // This function basically just builds a genesis storage key/value store according to // our desired mockup. -pub fn new_test_ext() -> runtime_io::TestExternalities { +pub fn new_test_ext() -> runtime_io::TestExternalities { system::GenesisConfig::default() .build_storage::() .unwrap() diff --git a/srml/generic-asset/src/tests.rs b/srml/generic-asset/src/tests.rs index 685e553c1c14d03687a3595ece8032746f273fea..165936d0215a6e86133f59b2ce652fb830b55f33 100644 --- a/srml/generic-asset/src/tests.rs +++ b/srml/generic-asset/src/tests.rs @@ -22,14 +22,13 @@ use super::*; use crate::mock::{new_test_ext, ExtBuilder, GenericAsset, Origin, System, Test, TestEvent}; -use runtime_io::with_externalities; use support::{assert_noop, assert_ok}; #[test] fn issuing_asset_units_to_issuer_should_work() { let balance = 100; - with_externalities(&mut ExtBuilder::default().free_balance((16000, 1, 100)).build(), || { + ExtBuilder::default().free_balance((16000, 1, 100)).build().execute_with(|| { let default_permission = PermissionLatest { update: Owner::Address(1), mint: Owner::Address(1), @@ -51,61 +50,55 @@ fn issuing_asset_units_to_issuer_should_work() { #[test] fn issuing_with_next_asset_id_overflow_should_not_work() { - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - NextAssetId::::put(u32::max_value()); - let default_permission = PermissionLatest { - update: Owner::Address(1), - mint: Owner::Address(1), - burn: Owner::Address(1), - }; - assert_noop!( - GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: 1, - permissions: default_permission - } - ), - "No new assets id available." - ); - assert_eq!(GenericAsset::next_asset_id(), u32::max_value()); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + NextAssetId::::put(u32::max_value()); + let default_permission = PermissionLatest { + update: Owner::Address(1), + mint: Owner::Address(1), + burn: Owner::Address(1), + }; + assert_noop!( + GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: 1, + permissions: default_permission + } + ), + "No new assets id available." + ); + assert_eq!(GenericAsset::next_asset_id(), u32::max_value()); + }); } #[test] fn querying_total_supply_should_work() { let asset_id = 1000; - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let default_permission = PermissionLatest { - update: Owner::Address(1), - mint: Owner::Address(1), - burn: Owner::Address(1), - }; - assert_ok!(GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: 100, - permissions: default_permission - } - )); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), 100); - assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 2, 50)); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), 50); - assert_eq!(GenericAsset::free_balance(&asset_id, &2), 50); - assert_ok!(GenericAsset::transfer(Origin::signed(2), asset_id, 3, 31)); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), 50); - assert_eq!(GenericAsset::free_balance(&asset_id, &2), 19); - assert_eq!(GenericAsset::free_balance(&asset_id, &3), 31); - assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 1, 1)); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), 50); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let default_permission = PermissionLatest { + update: Owner::Address(1), + mint: Owner::Address(1), + burn: Owner::Address(1), + }; + assert_ok!(GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: 100, + permissions: default_permission + } + )); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), 100); + assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 2, 50)); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), 50); + assert_eq!(GenericAsset::free_balance(&asset_id, &2), 50); + assert_ok!(GenericAsset::transfer(Origin::signed(2), asset_id, 3, 31)); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), 50); + assert_eq!(GenericAsset::free_balance(&asset_id, &2), 19); + assert_eq!(GenericAsset::free_balance(&asset_id, &3), 31); + assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 1, 1)); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), 50); + }); } // Given @@ -127,27 +120,24 @@ fn querying_total_supply_should_work() { fn transferring_amount_should_work() { let asset_id = 1000; let free_balance = 100; - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let default_permission = PermissionLatest { - update: Owner::Address(1), - mint: Owner::Address(1), - burn: Owner::Address(1), - }; - assert_ok!(GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: free_balance, - permissions: default_permission - } - )); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), free_balance); - assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 2, 40)); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), 60); - assert_eq!(GenericAsset::free_balance(&asset_id, &2), 40); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let default_permission = PermissionLatest { + update: Owner::Address(1), + mint: Owner::Address(1), + burn: Owner::Address(1), + }; + assert_ok!(GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: free_balance, + permissions: default_permission + } + )); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), free_balance); + assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 2, 40)); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), 60); + assert_eq!(GenericAsset::free_balance(&asset_id, &2), 40); + }); } // Given @@ -168,55 +158,49 @@ fn transferring_amount_should_work() { #[test] fn transferring_amount_should_fail_when_transferring_more_than_free_balance() { let asset_id = 1000; - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let default_permission = PermissionLatest { - update: Owner::Address(1), - mint: Owner::Address(1), - burn: Owner::Address(1), - }; - assert_ok!(GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: 100, - permissions: default_permission - } - )); - assert_noop!( - GenericAsset::transfer(Origin::signed(1), asset_id, 2, 2000), - "balance too low to send amount" - ); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let default_permission = PermissionLatest { + update: Owner::Address(1), + mint: Owner::Address(1), + burn: Owner::Address(1), + }; + assert_ok!(GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: 100, + permissions: default_permission + } + )); + assert_noop!( + GenericAsset::transfer(Origin::signed(1), asset_id, 2, 2000), + "balance too low to send amount" + ); + }); } #[test] fn transferring_less_than_one_unit_should_not_work() { let asset_id = 1000; - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let default_permission = PermissionLatest { - update: Owner::Address(1), - mint: Owner::Address(1), - burn: Owner::Address(1), - }; - assert_ok!(GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: 100, - permissions: default_permission - } - )); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), 100); - assert_noop!( - GenericAsset::transfer(Origin::signed(1), asset_id, 2, 0), - "cannot transfer zero amount" - ); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let default_permission = PermissionLatest { + update: Owner::Address(1), + mint: Owner::Address(1), + burn: Owner::Address(1), + }; + assert_ok!(GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: 100, + permissions: default_permission + } + )); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), 100); + assert_noop!( + GenericAsset::transfer(Origin::signed(1), asset_id, 2, 0), + "cannot transfer zero amount" + ); + }); } // Given @@ -233,60 +217,54 @@ fn self_transfer_should_fail() { let asset_id = 1000; let balance = 100; - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let default_permission = PermissionLatest { - update: Owner::Address(1), - mint: Owner::Address(1), - burn: Owner::Address(1), - }; - assert_ok!(GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: balance, - permissions: default_permission - } - )); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let default_permission = PermissionLatest { + update: Owner::Address(1), + mint: Owner::Address(1), + burn: Owner::Address(1), + }; + assert_ok!(GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: balance, + permissions: default_permission + } + )); - let initial_free_balance = GenericAsset::free_balance(&asset_id, &1); - assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 1, 10)); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), initial_free_balance); - }, - ); + let initial_free_balance = GenericAsset::free_balance(&asset_id, &1); + assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 1, 10)); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), initial_free_balance); + }); } #[test] fn transferring_more_units_than_total_supply_should_not_work() { let asset_id = 1000; - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let default_permission = PermissionLatest { - update: Owner::Address(1), - mint: Owner::Address(1), - burn: Owner::Address(1), - }; - assert_ok!(GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: 100, - permissions: default_permission - } - )); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), 100); - assert_noop!( - GenericAsset::transfer(Origin::signed(1), asset_id, 2, 101), - "balance too low to send amount" - ); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let default_permission = PermissionLatest { + update: Owner::Address(1), + mint: Owner::Address(1), + burn: Owner::Address(1), + }; + assert_ok!(GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: 100, + permissions: default_permission + } + )); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), 100); + assert_noop!( + GenericAsset::transfer(Origin::signed(1), asset_id, 2, 101), + "balance too low to send amount" + ); + }); } // Ensures it uses fake money for staking asset id. #[test] fn staking_asset_id_should_return_0() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(GenericAsset::staking_asset_id(), 16000); }); } @@ -294,7 +272,7 @@ fn staking_asset_id_should_return_0() { // Ensures it uses fake money for spending asset id. #[test] fn spending_asset_id_should_return_10() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(GenericAsset::spending_asset_id(), 16001); }); } @@ -305,7 +283,7 @@ fn spending_asset_id_should_return_10() { // -Â total_balance should return 0 #[test] fn total_balance_should_be_zero() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(GenericAsset::total_balance(&0, &0), 0); }); } @@ -323,19 +301,16 @@ fn total_balance_should_be_equal_to_account_balance() { mint: Owner::Address(1), burn: Owner::Address(1), }; - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - assert_ok!(GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: 100, - permissions: default_permission - } - )); - assert_eq!(GenericAsset::total_balance(&1000, &1), 100); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + assert_ok!(GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: 100, + permissions: default_permission + } + )); + assert_eq!(GenericAsset::total_balance(&1000, &1), 100); + }); } // Given @@ -348,7 +323,7 @@ fn total_balance_should_be_equal_to_account_balance() { // -Â free_balance should return 50. #[test] fn free_balance_should_only_return_account_free_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 50)).build(), || { + ExtBuilder::default().free_balance((1, 0, 50)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 70); assert_eq!(GenericAsset::free_balance(&1, &0), 50); }); @@ -363,7 +338,7 @@ fn free_balance_should_only_return_account_free_balance() { // -Â total_balance should equals to account balance + free balance. #[test] fn total_balance_should_be_equal_to_sum_of_account_balance_and_free_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 50)).build(), || { + ExtBuilder::default().free_balance((1, 0, 50)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 70); assert_eq!(GenericAsset::total_balance(&1, &0), 120); }); @@ -378,7 +353,7 @@ fn total_balance_should_be_equal_to_sum_of_account_balance_and_free_balance() { // - reserved_balance should return 70. #[test] fn reserved_balance_should_only_return_account_reserved_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 50)).build(), || { + ExtBuilder::default().free_balance((1, 0, 50)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 70); assert_eq!(GenericAsset::reserved_balance(&1, &0), 70); }); @@ -394,7 +369,7 @@ fn reserved_balance_should_only_return_account_reserved_balance() { // - reserved_balance = amount #[test] fn set_reserved_balance_should_add_balance_as_reserved() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 50); assert_eq!(GenericAsset::reserved_balance(&1, &0), 50); }); @@ -410,7 +385,7 @@ fn set_reserved_balance_should_add_balance_as_reserved() { // - New free_balance should replace older free_balance. #[test] fn set_free_balance_should_add_amount_as_free_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { GenericAsset::set_free_balance(&1, &0, 50); assert_eq!(GenericAsset::free_balance(&1, &0), 50); }); @@ -429,7 +404,7 @@ fn set_free_balance_should_add_amount_as_free_balance() { // - new reserved_balance = original free balance + reserved amount #[test] fn reserve_should_moves_amount_from_balance_to_reserved_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { assert_ok!(GenericAsset::reserve(&1, &0, 70)); assert_eq!(GenericAsset::free_balance(&1, &0), 30); assert_eq!(GenericAsset::reserved_balance(&1, &0), 70); @@ -448,7 +423,7 @@ fn reserve_should_moves_amount_from_balance_to_reserved_balance() { // - Should throw an error. #[test] fn reserve_should_not_moves_amount_from_balance_to_reserved_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { assert_noop!(GenericAsset::reserve(&1, &0, 120), "not enough free funds"); assert_eq!(GenericAsset::free_balance(&1, &0), 100); assert_eq!(GenericAsset::reserved_balance(&1, &0), 0); @@ -466,7 +441,7 @@ fn reserve_should_not_moves_amount_from_balance_to_reserved_balance() { // - unreserved should return 20. #[test] fn unreserve_should_return_substratced_value_from_unreserved_amount_by_actual_acount_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::unreserve(&1, &0, 120), 20); }); @@ -483,7 +458,7 @@ fn unreserve_should_return_substratced_value_from_unreserved_amount_by_actual_ac // - unreserved should return None. #[test] fn unreserve_should_return_none() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::unreserve(&1, &0, 50), 0); }); @@ -500,7 +475,7 @@ fn unreserve_should_return_none() { // - free_balance should be 200. #[test] fn unreserve_should_increase_free_balance_by_reserved_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); GenericAsset::unreserve(&1, &0, 120); assert_eq!(GenericAsset::free_balance(&1, &0), 200); @@ -518,7 +493,7 @@ fn unreserve_should_increase_free_balance_by_reserved_balance() { // - reserved_balance should be 0. #[test] fn unreserve_should_deduct_reserved_balance_by_reserved_amount() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { GenericAsset::set_free_balance(&1, &0, 100); GenericAsset::unreserve(&1, &0, 120); assert_eq!(GenericAsset::reserved_balance(&1, &0), 0); @@ -536,7 +511,7 @@ fn unreserve_should_deduct_reserved_balance_by_reserved_amount() { // - slash should return None. #[test] fn slash_should_return_slash_reserved_amount() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::slash(&1, &0, 70), None); }); @@ -550,7 +525,7 @@ fn slash_should_return_slash_reserved_amount() { // - Should return slashed_reserved - reserved_balance. #[test] fn slash_reserved_should_deducts_up_to_amount_from_reserved_balance() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::slash_reserved(&1, &0, 150), Some(50)); }); @@ -564,7 +539,7 @@ fn slash_reserved_should_deducts_up_to_amount_from_reserved_balance() { // - Should return None. #[test] fn slash_reserved_should_return_none() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::slash_reserved(&1, &0, 100), None); }); @@ -579,7 +554,7 @@ fn slash_reserved_should_return_none() { // - Should not return None. #[test] fn repatriate_reserved_return_amount_substracted_by_slash_amount() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::repatriate_reserved(&1, &0, &1, 130), 30); }); @@ -594,7 +569,7 @@ fn repatriate_reserved_return_amount_substracted_by_slash_amount() { // - Should return None. #[test] fn repatriate_reserved_return_none() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::repatriate_reserved(&1, &0, &1, 90), 0); }); @@ -608,7 +583,7 @@ fn repatriate_reserved_return_none() { // - Should create a new reserved asset. #[test] fn create_reserved_should_create_a_default_account_with_the_balance_given() { - with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let default_permission = PermissionLatest { update: Owner::Address(1), mint: Owner::Address(1), @@ -643,7 +618,7 @@ fn create_reserved_should_create_a_default_account_with_the_balance_given() { // - Should throw a permission error #[test] fn mint_should_throw_permission_error() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let origin = 1; let asset_id = 4; let to_account = 2; @@ -666,36 +641,33 @@ fn mint_should_throw_permission_error() { // - Should not change `origins` free_balance. #[test] fn mint_should_increase_asset() { - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let origin = 1; - let asset_id = 1000; - let to_account = 2; - let amount = 500; - let initial_issuance = 100; - - let default_permission = PermissionLatest { - update: Owner::Address(origin), - mint: Owner::Address(origin), - burn: Owner::Address(origin), - }; + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let origin = 1; + let asset_id = 1000; + let to_account = 2; + let amount = 500; + let initial_issuance = 100; - assert_ok!(GenericAsset::create( - Origin::signed(origin), - AssetOptions { - initial_issuance: initial_issuance, - permissions: default_permission - } - )); + let default_permission = PermissionLatest { + update: Owner::Address(origin), + mint: Owner::Address(origin), + burn: Owner::Address(origin), + }; - assert_ok!(GenericAsset::mint(Origin::signed(origin), asset_id, to_account, amount)); - assert_eq!(GenericAsset::free_balance(&asset_id, &to_account), amount); + assert_ok!(GenericAsset::create( + Origin::signed(origin), + AssetOptions { + initial_issuance: initial_issuance, + permissions: default_permission + } + )); - // Origin's free_balance should not change. - assert_eq!(GenericAsset::free_balance(&asset_id, &origin), initial_issuance); - }, - ); + assert_ok!(GenericAsset::mint(Origin::signed(origin), asset_id, to_account, amount)); + assert_eq!(GenericAsset::free_balance(&asset_id, &to_account), amount); + + // Origin's free_balance should not change. + assert_eq!(GenericAsset::free_balance(&asset_id, &origin), initial_issuance); + }); } // Given @@ -707,20 +679,17 @@ fn mint_should_increase_asset() { // - Should throw a permission error. #[test] fn burn_should_throw_permission_error() { - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let origin = 1; - let asset_id = 4; - let to_account = 2; - let amount = 10; - - assert_noop!( - GenericAsset::burn(Origin::signed(origin), asset_id, to_account, amount), - "The origin does not have permission to burn an asset." - ); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let origin = 1; + let asset_id = 4; + let to_account = 2; + let amount = 10; + + assert_noop!( + GenericAsset::burn(Origin::signed(origin), asset_id, to_account, amount), + "The origin does not have permission to burn an asset." + ); + }); } // Given @@ -733,41 +702,38 @@ fn burn_should_throw_permission_error() { // - Should not change `origin`'s free_balance. #[test] fn burn_should_burn_an_asset() { - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let origin = 1; - let asset_id = 1000; - let to_account = 2; - let amount = 1000; - let initial_issuance = 100; - let burn_amount = 400; - let expected_amount = 600; - - let default_permission = PermissionLatest { - update: Owner::Address(origin), - mint: Owner::Address(origin), - burn: Owner::Address(origin), - }; + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let origin = 1; + let asset_id = 1000; + let to_account = 2; + let amount = 1000; + let initial_issuance = 100; + let burn_amount = 400; + let expected_amount = 600; - assert_ok!(GenericAsset::create( - Origin::signed(origin), - AssetOptions { - initial_issuance: initial_issuance, - permissions: default_permission - } - )); - assert_ok!(GenericAsset::mint(Origin::signed(origin), asset_id, to_account, amount)); + let default_permission = PermissionLatest { + update: Owner::Address(origin), + mint: Owner::Address(origin), + burn: Owner::Address(origin), + }; - assert_ok!(GenericAsset::burn( - Origin::signed(origin), - asset_id, - to_account, - burn_amount - )); - assert_eq!(GenericAsset::free_balance(&asset_id, &to_account), expected_amount); - }, - ); + assert_ok!(GenericAsset::create( + Origin::signed(origin), + AssetOptions { + initial_issuance: initial_issuance, + permissions: default_permission + } + )); + assert_ok!(GenericAsset::mint(Origin::signed(origin), asset_id, to_account, amount)); + + assert_ok!(GenericAsset::burn( + Origin::signed(origin), + asset_id, + to_account, + burn_amount + )); + assert_eq!(GenericAsset::free_balance(&asset_id, &to_account), expected_amount); + }); } // Given @@ -779,41 +745,29 @@ fn burn_should_burn_an_asset() { // - The account origin should have burn, mint and update permissions. #[test] fn check_permission_should_return_correct_permission() { - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let origin = 1; - let asset_id = 1000; - let initial_issuance = 100; - - let default_permission = PermissionLatest { - update: Owner::Address(origin), - mint: Owner::Address(origin), - burn: Owner::Address(origin), - }; + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let origin = 1; + let asset_id = 1000; + let initial_issuance = 100; - assert_ok!(GenericAsset::create( - Origin::signed(origin), - AssetOptions { - initial_issuance: initial_issuance, - permissions: default_permission - } - )); + let default_permission = PermissionLatest { + update: Owner::Address(origin), + mint: Owner::Address(origin), + burn: Owner::Address(origin), + }; - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Burn), - true - ); - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Mint), - true - ); - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Update), - true - ); - }, - ); + assert_ok!(GenericAsset::create( + Origin::signed(origin), + AssetOptions { + initial_issuance: initial_issuance, + permissions: default_permission + }, + )); + + assert!(GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Burn)); + assert!(GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Mint)); + assert!(GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Update)); + }); } // Given @@ -825,41 +779,29 @@ fn check_permission_should_return_correct_permission() { // - The account origin should not have burn, mint and update permissions. #[test] fn check_permission_should_return_false_for_no_permission() { - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let origin = 1; - let asset_id = 1000; - let initial_issuance = 100; - - let default_permission = PermissionLatest { - update: Owner::None, - mint: Owner::None, - burn: Owner::None, - }; + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let origin = 1; + let asset_id = 1000; + let initial_issuance = 100; - assert_ok!(GenericAsset::create( - Origin::signed(origin), - AssetOptions { - initial_issuance: initial_issuance, - permissions: default_permission - } - )); + let default_permission = PermissionLatest { + update: Owner::None, + mint: Owner::None, + burn: Owner::None, + }; - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Burn), - false - ); - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Mint), - false - ); - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Update), - false - ); - }, - ); + assert_ok!(GenericAsset::create( + Origin::signed(origin), + AssetOptions { + initial_issuance: initial_issuance, + permissions: default_permission + } + )); + + assert!(!GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Burn)); + assert!(!GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Mint)); + assert!(!GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Update)); + }); } // Given @@ -871,48 +813,39 @@ fn check_permission_should_return_false_for_no_permission() { // - The account origin should have update and mint permissions. #[test] fn update_permission_should_change_permission() { - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let origin = 1; - let asset_id = 1000; - let initial_issuance = 100; - - let default_permission = PermissionLatest { - update: Owner::Address(origin), - mint: Owner::None, - burn: Owner::None, - }; - - let new_permission = PermissionLatest { - update: Owner::Address(origin), - mint: Owner::Address(origin), - burn: Owner::None, - }; + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let origin = 1; + let asset_id = 1000; + let initial_issuance = 100; - assert_ok!(GenericAsset::create( - Origin::signed(origin), - AssetOptions { - initial_issuance: initial_issuance, - permissions: default_permission - } - )); + let default_permission = PermissionLatest { + update: Owner::Address(origin), + mint: Owner::None, + burn: Owner::None, + }; - assert_ok!(GenericAsset::update_permission( - Origin::signed(origin), - asset_id, - new_permission - )); - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Mint), - true - ); - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Burn), - false - ); - }, - ); + let new_permission = PermissionLatest { + update: Owner::Address(origin), + mint: Owner::Address(origin), + burn: Owner::None, + }; + + assert_ok!(GenericAsset::create( + Origin::signed(origin), + AssetOptions { + initial_issuance: initial_issuance, + permissions: default_permission + } + )); + + assert_ok!(GenericAsset::update_permission( + Origin::signed(origin), + asset_id, + new_permission, + )); + assert!(GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Mint)); + assert!(!GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Burn)); + }); } // Given @@ -923,41 +856,38 @@ fn update_permission_should_change_permission() { // - Should throw an error stating "Origin does not have enough permission to update permissions." #[test] fn update_permission_should_throw_error_when_lack_of_permissions() { - with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let origin = 1; - let asset_id = 1000; - let initial_issuance = 100; - - let default_permission = PermissionLatest { - update: Owner::None, - mint: Owner::None, - burn: Owner::None, - }; - - let new_permission = PermissionLatest { - update: Owner::Address(origin), - mint: Owner::Address(origin), - burn: Owner::None, - }; - - let expected_error_message = "Origin does not have enough permission to update permissions."; + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let origin = 1; + let asset_id = 1000; + let initial_issuance = 100; - assert_ok!(GenericAsset::create( - Origin::signed(origin), - AssetOptions { - initial_issuance: initial_issuance, - permissions: default_permission - } - )); + let default_permission = PermissionLatest { + update: Owner::None, + mint: Owner::None, + burn: Owner::None, + }; - assert_noop!( - GenericAsset::update_permission(Origin::signed(origin), asset_id, new_permission), - expected_error_message - ); - }, - ); + let new_permission = PermissionLatest { + update: Owner::Address(origin), + mint: Owner::Address(origin), + burn: Owner::None, + }; + + let expected_error_message = "Origin does not have enough permission to update permissions."; + + assert_ok!(GenericAsset::create( + Origin::signed(origin), + AssetOptions { + initial_issuance: initial_issuance, + permissions: default_permission + }, + )); + + assert_noop!( + GenericAsset::update_permission(Origin::signed(origin), asset_id, new_permission), + expected_error_message, + ); + }); } // Given @@ -974,7 +904,7 @@ fn update_permission_should_throw_error_when_lack_of_permissions() { // - Permissions must have burn, mint and updatePermission for the given asset_id. #[test] fn create_asset_works_with_given_asset_id_and_from_account() { - with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; let from_account: Option<::AccountId> = Some(1); @@ -1011,7 +941,7 @@ fn create_asset_works_with_given_asset_id_and_from_account() { // - `create_asset` should not work. #[test] fn create_asset_with_non_reserved_asset_id_should_not_work() { - with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; let from_account: Option<::AccountId> = Some(1); @@ -1045,7 +975,7 @@ fn create_asset_with_non_reserved_asset_id_should_not_work() { // - `create_asset` should not work. #[test] fn create_asset_with_a_taken_asset_id_should_not_work() { - with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; let from_account: Option<::AccountId> = Some(1); @@ -1090,7 +1020,7 @@ fn create_asset_with_a_taken_asset_id_should_not_work() { // - Should create a reserved token. #[test] fn create_asset_should_create_a_reserved_asset_when_from_account_is_none() { - with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; let from_account: Option<::AccountId> = None; @@ -1133,7 +1063,7 @@ fn create_asset_should_create_a_reserved_asset_when_from_account_is_none() { // - Should not create a `reserved_asset`. #[test] fn create_asset_should_create_a_user_asset() { - with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; let from_account: Option<::AccountId> = None; @@ -1180,12 +1110,11 @@ fn update_permission_should_raise_event() { burn: Owner::Address(origin), }; - with_externalities( - &mut ExtBuilder::default() - .next_asset_id(asset_id) - .free_balance((staking_asset_id, origin, initial_balance)) - .build(), - || { + ExtBuilder::default() + .next_asset_id(asset_id) + .free_balance((staking_asset_id, origin, initial_balance)) + .build() + .execute_with(|| { assert_ok!(GenericAsset::create( Origin::signed(origin), AssetOptions { @@ -1201,9 +1130,11 @@ fn update_permission_should_raise_event() { permissions.clone() )); + let expected_event = TestEvent::generic_asset( + RawEvent::PermissionUpdated(asset_id, permissions.clone()), + ); // Assert - assert!(System::events().iter().any(|record| record.event - == TestEvent::generic_asset(RawEvent::PermissionUpdated(asset_id, permissions.clone())))); + assert!(System::events().iter().any(|record| record.event == expected_event)); }, ); } @@ -1223,27 +1154,26 @@ fn mint_should_raise_event() { let to = 2; let amount = 100; - with_externalities( - &mut ExtBuilder::default() - .next_asset_id(asset_id) - .free_balance((staking_asset_id, origin, initial_balance)) - .build(), - || { + ExtBuilder::default() + .next_asset_id(asset_id) + .free_balance((staking_asset_id, origin, initial_balance)) + .build() + .execute_with(|| { assert_ok!(GenericAsset::create( Origin::signed(origin), AssetOptions { initial_issuance: 0, permissions: permissions.clone(), - } + }, )); // Act assert_ok!(GenericAsset::mint(Origin::signed(origin), asset_id, to, amount)); + let expected_event = TestEvent::generic_asset(RawEvent::Minted(asset_id, to, amount)); + // Assert - assert!(System::events() - .iter() - .any(|record| record.event == TestEvent::generic_asset(RawEvent::Minted(asset_id, to, amount)))); + assert!(System::events().iter().any(|record| record.event == expected_event)); }, ); } @@ -1262,27 +1192,26 @@ fn burn_should_raise_event() { }; let amount = 100; - with_externalities( - &mut ExtBuilder::default() - .next_asset_id(asset_id) - .free_balance((staking_asset_id, origin, initial_balance)) - .build(), - || { + ExtBuilder::default() + .next_asset_id(asset_id) + .free_balance((staking_asset_id, origin, initial_balance)) + .build() + .execute_with(|| { assert_ok!(GenericAsset::create( Origin::signed(origin), AssetOptions { initial_issuance: amount, permissions: permissions.clone(), - } + }, )); // Act assert_ok!(GenericAsset::burn(Origin::signed(origin), asset_id, origin, amount)); + let expected_event = TestEvent::generic_asset(RawEvent::Burned(asset_id, origin, amount)); + // Assert - assert!(System::events() - .iter() - .any(|record| record.event == TestEvent::generic_asset(RawEvent::Burned(asset_id, origin, amount)))); + assert!(System::events().iter().any(|record| record.event == expected_event)); }, ); } diff --git a/srml/grandpa/Cargo.toml b/srml/grandpa/Cargo.toml index 71e43e8692ff159fd503607208c3a88c995e7a9b..4b494cfeff8d11979116deb598d03dc5920f690e 100644 --- a/srml/grandpa/Cargo.toml +++ b/srml/grandpa/Cargo.toml @@ -5,21 +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 } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false, features = [ "wasm-nice-panic-message" ] } sr-primitives = { path = "../../core/sr-primitives", default-features = false } sr-staking-primitives = { path = "../../core/sr-staking-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 } 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"] @@ -29,7 +28,7 @@ std = [ "primitives/std", "substrate-finality-grandpa-primitives/std", "rstd/std", - "srml-support/std", + "support/std", "sr-primitives/std", "sr-staking-primitives/std", "system/std", diff --git a/srml/grandpa/src/lib.rs b/srml/grandpa/src/lib.rs index d64939ae0a7669f916b371680ec0d546a5bbde0c..0fc0df382a0bdb67233a81ae3c2decc3bd5deae0 100644 --- a/srml/grandpa/src/lib.rs +++ b/srml/grandpa/src/lib.rs @@ -32,8 +32,8 @@ 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, @@ -43,7 +43,7 @@ use sr_staking_primitives::{ SessionIndex, offence::{Offence, Kind}, }; -use fg_primitives::{ScheduledChange, ConsensusLog, GRANDPA_ENGINE_ID}; +use fg_primitives::{GRANDPA_ENGINE_ID, ScheduledChange, ConsensusLog, SetId, RoundNumber}; pub use fg_primitives::{AuthorityId, AuthorityWeight}; use system::{ensure_signed, DigestOf}; @@ -65,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. @@ -76,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, @@ -127,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. @@ -138,31 +138,30 @@ decl_event!( decl_storage! { trait Store for Module as GrandpaFinality { /// The current authority set. - Authorities get(authorities): Vec<(AuthorityId, AuthorityWeight)>; + Authorities get(fn authorities): Vec<(AuthorityId, AuthorityWeight)>; /// State of the current authority set. - State get(state): StoredState = StoredState::Live; + State get(fn state): StoredState = StoredState::Live; /// Pending change: (signaled at, scheduled change). PendingChange: Option>; /// next block number where we can force a change. - NextForced get(next_forced): Option; + NextForced get(fn next_forced): Option; /// `true` if we are currently stalled. - Stalled get(stalled): Option<(T::BlockNumber, T::BlockNumber)>; + Stalled get(fn 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(fn 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(fn session_for_set): map SetId => Option; } add_extra_genesis { config(authorities): Vec<(AuthorityId, AuthorityWeight)>; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig - | { - runtime_io::with_storage( - storage, - || Module::::initialize_authorities(&config.authorities), - ); - }) + build(|config| Module::::initialize_authorities(&config.authorities)) } } @@ -243,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(); @@ -262,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(); @@ -292,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 { @@ -331,35 +333,40 @@ impl Module { fn initialize_authorities(authorities: &[(AuthorityId, AuthorityWeight)]) { if !authorities.is_empty() { assert!(Authorities::get().is_empty(), "Authorities are already initialized!"); - Authorities::put_ref(authorities); + 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 { @@ -367,7 +374,9 @@ 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) @@ -380,18 +389,27 @@ impl session::OneSessionHandler for Module { fn on_new_session<'a, I: 'a>(changed: bool, validators: I, _queued_validators: I) where I: Iterator { - // instant changes - if changed { + // 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::>(); - 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); - } + 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) { @@ -412,8 +430,8 @@ impl finality_tracker::OnFinalizationStalled for Modul #[derive(Copy, Clone, PartialOrd, Ord, Eq, PartialEq, Encode, Decode)] struct GrandpaTimeSlot { // The order of these matters for `derive(Ord)`. - set_id: u64, - round: u64, + set_id: SetId, + round: RoundNumber, } // TODO [slashing]: Integrate this. diff --git a/srml/grandpa/src/mock.rs b/srml/grandpa/src/mock.rs index dd6ed766ce07a70eb01a69f6a38f873f63f3d311..fcacbade20490e19c961ddcfa7d94ba1b216322a 100644 --- a/srml/grandpa/src/mock.rs +++ b/srml/grandpa/src/mock.rs @@ -20,8 +20,8 @@ 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 primitives::{H256, Blake2Hasher}; +use support::{impl_outer_origin, impl_outer_event, parameter_types}; +use primitives::H256; use codec::{Encode, Decode}; use crate::{AuthorityId, GenesisConfig, Trait, Module, ConsensusLog}; use substrate_finality_grandpa_primitives::GRANDPA_ENGINE_ID; @@ -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,11 +53,10 @@ 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; - type WeightMultiplierUpdate = (); type Event = TestEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -82,7 +81,7 @@ pub fn to_authorities(vec: Vec<(u64, u64)>) -> Vec<(AuthorityId, u64)> { .collect() } -pub fn new_test_ext(authorities: Vec<(u64, u64)>) -> runtime_io::TestExternalities { +pub fn new_test_ext(authorities: Vec<(u64, u64)>) -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig { authorities: to_authorities(authorities), diff --git a/srml/grandpa/src/tests.rs b/srml/grandpa/src/tests.rs index 41229a5136165d5f4970ce603153ae7c881cd831..2efeb4b5bf3cfc87f69763ef1e07b5a56b3421f2 100644 --- a/srml/grandpa/src/tests.rs +++ b/srml/grandpa/src/tests.rs @@ -18,9 +18,7 @@ #![cfg(test)] -use sr_primitives::testing::Digest; -use sr_primitives::traits::{Header, OnFinalize}; -use runtime_io::with_externalities; +use sr_primitives::{testing::Digest, traits::{Header, OnFinalize}}; use crate::mock::*; use system::{EventRecord, Phase}; use codec::{Decode, Encode}; @@ -29,7 +27,7 @@ use super::*; #[test] fn authorities_change_logged() { - with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_change(to_authorities(vec![(4, 1), (5, 1), (6, 1)]), 0, None).unwrap(); @@ -57,7 +55,7 @@ fn authorities_change_logged() { #[test] fn authorities_change_logged_after_delay() { - with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_change(to_authorities(vec![(4, 1), (5, 1), (6, 1)]), 1, None).unwrap(); Grandpa::on_finalize(1); @@ -90,7 +88,7 @@ fn authorities_change_logged_after_delay() { #[test] fn cannot_schedule_change_when_one_pending() { - with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_change(to_authorities(vec![(4, 1), (5, 1), (6, 1)]), 1, None).unwrap(); assert!(>::exists()); @@ -133,7 +131,7 @@ fn new_decodes_from_old() { #[test] fn dispatch_forced_change() { - with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_change( to_authorities(vec![(4, 1), (5, 1), (6, 1)]), @@ -205,7 +203,7 @@ fn dispatch_forced_change() { #[test] fn schedule_pause_only_when_live() { - with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { // we schedule a pause at block 1 with delay of 1 System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_pause(1).unwrap(); @@ -240,7 +238,7 @@ fn schedule_pause_only_when_live() { #[test] fn schedule_resume_only_when_paused() { - with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); // the set is currently live, resuming it is an error diff --git a/srml/im-online/Cargo.toml b/srml/im-online/Cargo.toml index 5f7514755b72fd194bfbae3edaa15bf1f77a2c5b..b62cc2a8f96158219c9bd2e092e7625e54203a63 100644 --- a/srml/im-online/Cargo.toml +++ b/srml/im-online/Cargo.toml @@ -9,14 +9,17 @@ app-crypto = { package = "substrate-application-crypto", path = "../../core/appl 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 } -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 } -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] +offchain = { package = "substrate-offchain", path = "../../core/offchain" } + [features] default = ["std", "session/historical"] std = [ @@ -26,9 +29,9 @@ std = [ "rstd/std", "serde", "session/std", - "sr-io/std", + "runtime-io/std", "sr-primitives/std", "sr-staking-primitives/std", - "srml-support/std", + "support/std", "system/std", ] diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 760ab79eb9e2d33e914e6ae9c5fb6a716a634339..82b866d32bc86da71d1b4b13c2fc619d9bdcb6e0 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,75 +67,93 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] +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_io::Printable; use sr_primitives::{ - Perbill, ApplyError, - traits::{Extrinsic as ExtrinsicT, Convert}, - transaction_validity::{TransactionValidity, TransactionLongevity, ValidTransaction}, + RuntimeDebug, + traits::{Convert, Member, Printable, Saturating}, Perbill, + transaction_validity::{ + TransactionValidity, TransactionLongevity, ValidTransaction, InvalidTransaction, + }, }; use sr_staking_primitives::{ - SessionIndex, CurrentElectedSet, + SessionIndex, offence::{ReportOffence, Offence, Kind}, }; -use srml_support::{ - StorageValue, decl_module, decl_event, decl_storage, StorageDoubleMap, print, ensure +use support::{ + decl_module, decl_event, decl_storage, print, ensure, Parameter, debug }; use system::ensure_none; +use system::offchain::SubmitUnsignedTransaction; + +pub mod sr25519 { + mod app_sr25519 { + use app_crypto::{app_crypto, key_types::IM_ONLINE, sr25519}; + app_crypto!(sr25519, IM_ONLINE); + } + + /// An i'm online keypair using sr25519 as its crypto. + #[cfg(feature = "std")] + pub type AuthorityPair = app_sr25519::Pair; -mod app { - pub use app_crypto::sr25519 as crypto; - use app_crypto::{app_crypto, key_types::IM_ONLINE, sr25519}; + /// An i'm online signature using sr25519 as its crypto. + pub type AuthoritySignature = app_sr25519::Signature; - app_crypto!(sr25519, IM_ONLINE); + /// 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); + } + + /// 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. -#[derive(Encode, Decode, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +/// 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, RuntimeDebug)] struct WorkerStatus { done: bool, gossipping_at: BlockNumber, } -// Error which may occur while executing the off-chain code. +/// Error which may occur while executing the off-chain code. +#[derive(RuntimeDebug)] 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!"), @@ -146,8 +164,7 @@ impl Printable for OffchainErr { pub type AuthIndex = u32; /// Heartbeat which is sent/received. -#[derive(Encode, Decode, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] pub struct Heartbeat where BlockNumber: PartialEq + Eq + Decode + Encode, { @@ -158,15 +175,17 @@ pub struct Heartbeat } 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: @@ -175,13 +194,12 @@ pub trait Trait: system::Trait + session::historical::Trait { IdentificationTuple, UnresponsivenessOffence>, >; - - /// A type that returns a validator id from the current elected set of the era. - type CurrentElectedSet: CurrentElectedSet<::ValidatorId>; } decl_event!( - pub enum Event { + pub enum Event where + ::AuthorityId, + { /// A new heartbeat was received from `AuthorityId` HeartbeatReceived(AuthorityId), } @@ -190,27 +208,19 @@ decl_event!( decl_storage! { trait Store for Module as ImOnline { /// The block number when we should gossip. - GossipAt get(gossip_at): T::BlockNumber; + GossipAt get(fn gossip_at): T::BlockNumber; /// The current set of keys that may issue a heartbeat. - Keys get(keys): Vec; + Keys get(fn keys): Vec; /// For each session index we keep a mapping of `AuthorityId` /// to `offchain::OpaqueNetworkState`. - ReceivedHeartbeats get(received_heartbeats): double_map SessionIndex, + ReceivedHeartbeats get(fn received_heartbeats): double_map SessionIndex, blake2_256(AuthIndex) => Vec; } add_extra_genesis { - config(keys): Vec; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig - | { - sr_io::with_storage( - storage, - || Module::::initialize_keys(&config.keys), - ); - }) + config(keys): Vec; + build(|config| Module::::initialize_keys(&config.keys)) } } @@ -222,7 +232,7 @@ decl_module! { fn heartbeat( origin, heartbeat: Heartbeat, - signature: AuthoritySignature + signature: ::Signature ) { ensure_none(origin)?; @@ -232,7 +242,7 @@ decl_module! { ¤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) { let signature_valid = heartbeat.using_encoded(|encoded_heartbeat| { @@ -240,7 +250,7 @@ decl_module! { }); ensure!(signature_valid, "Invalid heartbeat signature."); - Self::deposit_event(Event::HeartbeatReceived(public.clone())); + Self::deposit_event(Event::::HeartbeatReceived(public.clone())); let network_state = heartbeat.network_state.encode(); ::insert( @@ -248,13 +258,19 @@ 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) { + debug::RuntimeLogger::init(); + // Only send messages if we are a potential validator. - if sr_io::is_validator() { + if runtime_io::is_validator() { Self::offchain(now); } } @@ -269,7 +285,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 { @@ -292,13 +308,21 @@ impl Module { Ok(_) => {}, Err(err) => print(err), } + } else { + debug::native::trace!( + target: "imonline", + "Skipping gossip at: {:?} >= {:?} || {:?}", + next_gossip, + now, + if not_yet_gossipped { "not gossipped" } else { "gossipped" } + ); } } 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() @@ -309,7 +333,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, @@ -319,9 +343,15 @@ 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)?; + + debug::info!( + target: "imonline", + "[index: {:?}] Reporting im-online at block: {:?}", + authority_index, + block_number + ); + 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 @@ -340,7 +370,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), @@ -356,7 +386,7 @@ impl Module { done, gossipping_at, }; - sr_io::local_storage_set( + runtime_io::local_storage_set( StorageKind::PERSISTENT, DB_KEY, &enc.encode()); } @@ -367,7 +397,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[..]) @@ -389,36 +419,33 @@ impl Module { } } - fn initialize_keys(keys: &[AuthorityId]) { + fn initialize_keys(keys: &[T::AuthorityId]) { if !keys.is_empty() { - assert!(Keys::get().is_empty(), "Keys are already initialized!"); - Keys::put_ref(keys); + assert!(Keys::::get().is_empty(), "Keys are already initialized!"); + Keys::::put(keys); } } } impl session::OneSessionHandler for Module { - type Key = AuthorityId; + type Key = T::AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) - where I: Iterator + 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, _queued_validators: I) - where I: Iterator + where I: Iterator { - // Reset heartbeats - ::remove_prefix(&>::current_index()); - // 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(validators.map(|x| x.1).collect::>()); + Keys::::put(validators.map(|x| x.1).collect::>()); } fn on_before_session_ending() { @@ -426,20 +453,17 @@ impl session::OneSessionHandler for Module { let current_session = >::current_index(); - let keys = Keys::get(); - let current_elected = T::CurrentElectedSet::current_elected_set(); + let keys = Keys::::get(); + let current_validators = >::validators(); - // The invariant is that these two are of the same length. - // TODO: What to do: Uncomment, ignore, a third option? - // assert_eq!(keys.len(), current_elected.len()); - - for (auth_idx, validator_id) in current_elected.into_iter().enumerate() { + for (auth_idx, validator_id) in current_validators.into_iter().enumerate() { let auth_idx = auth_idx as u32; - if !::exists(¤t_session, &auth_idx) { + 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_elected; - current_elected is set of currently elected validators; + "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", @@ -449,6 +473,10 @@ impl session::OneSessionHandler for Module { } } + if unresponsive.is_empty() { + return; + } + let validator_set_count = keys.len() as u32; let offence = UnresponsivenessOffence { session_index: current_session, @@ -457,6 +485,10 @@ impl session::OneSessionHandler for Module { }; 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) { @@ -464,27 +496,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). @@ -493,23 +525,25 @@ 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() } - - TransactionValidity::Invalid(0) } } /// An offence that is filed if a validator didn't send a heartbeat message. +#[derive(RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Clone, PartialEq, Eq))] pub struct UnresponsivenessOffence { /// The current session index in which we report the unresponsive validators. /// @@ -545,37 +579,6 @@ impl Offence for UnresponsivenessOffence { 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); - - // _ * 0.05 - // For now, Perbill doesn't support multiplication other than an integer so we perform - // a manual scaling. - // TODO: #3189 should fix this. - let p = (x.into_parts() as u64 * 50_000_000u64) / 1_000_000_000u64; - Perbill::from_parts(p as u32) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[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% - ); + 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..e50e7779e9fcdf35ed717590c660c97b1052ae11 --- /dev/null +++ b/srml/im-online/src/mock.rs @@ -0,0 +1,166 @@ +// 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; +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 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..652d7512812945e41ab0e24be83ccbabc240b5f5 --- /dev/null +++ b/srml/im-online/src/tests.rs @@ -0,0 +1,245 @@ +// 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, OffchainExt}; +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() { + new_test_ext().execute_with(|| { + // 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() { + new_test_ext().execute_with(|| { + 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() { + new_test_ext().execute_with(|| { + 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.register_extension(OffchainExt::new(offchain)); + + ext.execute_with(|| { + // 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() { + new_test_ext().execute_with(|| { + 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/address.rs b/srml/indices/src/address.rs index caef4728fbf3fdb245fd5e099708604c31889bed..21ee654cf2e3f362182a99f12bb8ca8f4cc60f10 100644 --- a/srml/indices/src/address.rs +++ b/srml/indices/src/address.rs @@ -24,8 +24,8 @@ use codec::{Encode, Decode, Input, Output, Error}; /// An indices-aware address, which can be either a direct `AccountId` or /// an index. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug, Hash))] +#[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] pub enum Address where AccountId: Member, AccountIndex: Member, diff --git a/srml/indices/src/lib.rs b/srml/indices/src/lib.rs index 5bf838f32112dfc56c63fce28ff272218cb23a90..31aa57276bde95444d9320a09639480b560da3ec 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; } } @@ -93,12 +93,12 @@ decl_event!( decl_storage! { trait Store for Module as Indices { /// The next free enumeration set. - pub NextEnumSet get(next_enum_set) build(|config: &GenesisConfig| { + pub NextEnumSet get(fn next_enum_set) build(|config: &GenesisConfig| { (config.ids.len() as u32 / ENUM_SET_SIZE).into() }): T::AccountIndex; /// The enumeration sets. - pub EnumSet get(enum_set) build(|config: &GenesisConfig| { + pub EnumSet get(fn enum_set) build(|config: &GenesisConfig| { (0..((config.ids.len() as u32) + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE) .map(|i| ( i.into(), @@ -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 e28416fd3a9be0e8b730891aa29aee6f9e1a5d5b..427fd87c47e7d14d9383e9708ea96f8869891649 100644 --- a/srml/indices/src/mock.rs +++ b/srml/indices/src/mock.rs @@ -22,8 +22,8 @@ use std::collections::HashSet; 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 primitives::H256; +use support::{impl_outer_origin, parameter_types}; use {runtime_io, system}; use crate::{GenesisConfig, Module, Trait, IsDeadAccount, OnNewAccount, ResolveHint}; @@ -81,7 +81,6 @@ impl system::Trait for Runtime { type AccountId = u64; type Lookup = Indices; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -96,7 +95,7 @@ impl Trait for Runtime { type Event = (); } -pub fn new_test_ext() -> runtime_io::TestExternalities { +pub fn new_test_ext() -> runtime_io::TestExternalities { { let mut h = ALIVE.borrow_mut(); h.clear(); diff --git a/srml/indices/src/tests.rs b/srml/indices/src/tests.rs index 7b60e305278c58be97d156b0bbffc892afe7b750..3bcf0157130ce9ad10a5ed0fd8396359bb658814 100644 --- a/srml/indices/src/tests.rs +++ b/srml/indices/src/tests.rs @@ -20,61 +20,48 @@ use super::*; use crate::mock::{Indices, new_test_ext, make_account, kill_account, TestIsDeadAccount}; -use runtime_io::with_externalities; #[test] fn indexing_lookup_should_work() { - with_externalities( - &mut new_test_ext(), - || { - assert_eq!(Indices::lookup_index(0), Some(1)); - assert_eq!(Indices::lookup_index(1), Some(2)); - assert_eq!(Indices::lookup_index(2), Some(3)); - assert_eq!(Indices::lookup_index(3), Some(4)); - assert_eq!(Indices::lookup_index(4), None); - }, - ); + new_test_ext().execute_with(|| { + assert_eq!(Indices::lookup_index(0), Some(1)); + assert_eq!(Indices::lookup_index(1), Some(2)); + assert_eq!(Indices::lookup_index(2), Some(3)); + assert_eq!(Indices::lookup_index(3), Some(4)); + assert_eq!(Indices::lookup_index(4), None); + }); } #[test] fn default_indexing_on_new_accounts_should_work() { - with_externalities( - &mut new_test_ext(), - || { - assert_eq!(Indices::lookup_index(4), None); - make_account(5); - assert_eq!(Indices::lookup_index(4), Some(5)); - }, - ); + new_test_ext().execute_with(|| { + assert_eq!(Indices::lookup_index(4), None); + make_account(5); + assert_eq!(Indices::lookup_index(4), Some(5)); + }); } #[test] fn reclaim_indexing_on_new_accounts_should_work() { - with_externalities( - &mut new_test_ext(), - || { - assert_eq!(Indices::lookup_index(1), Some(2)); - assert_eq!(Indices::lookup_index(4), None); + new_test_ext().execute_with(|| { + assert_eq!(Indices::lookup_index(1), Some(2)); + assert_eq!(Indices::lookup_index(4), None); - kill_account(2); // index 1 no longer locked to id 2 + kill_account(2); // index 1 no longer locked to id 2 - make_account(1 + 256); // id 257 takes index 1. - assert_eq!(Indices::lookup_index(1), Some(257)); - }, - ); + make_account(1 + 256); // id 257 takes index 1. + assert_eq!(Indices::lookup_index(1), Some(257)); + }); } #[test] fn alive_account_should_prevent_reclaim() { - with_externalities( - &mut new_test_ext(), - || { - assert!(!TestIsDeadAccount::is_dead_account(&2)); - assert_eq!(Indices::lookup_index(1), Some(2)); - assert_eq!(Indices::lookup_index(4), None); + new_test_ext().execute_with(|| { + assert!(!TestIsDeadAccount::is_dead_account(&2)); + assert_eq!(Indices::lookup_index(1), Some(2)); + assert_eq!(Indices::lookup_index(4), None); - make_account(1 + 256); // id 257 takes index 1. - assert_eq!(Indices::lookup_index(4), Some(257)); - }, - ); + make_account(1 + 256); // id 257 takes index 1. + assert_eq!(Indices::lookup_index(4), Some(257)); + }); } 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 e36351ddbe5c7efa54093c36eef32eab99d917d8..6cd2a914e6bffea346b79ad1b3c33b763b0c1e48 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}; @@ -57,21 +57,16 @@ pub trait Trait: system::Trait { decl_storage! { trait Store for Module, I: Instance=DefaultInstance> as Membership { /// The current membership, stored as an ordered Vec. - Members get(members): Vec; + Members get(fn members): Vec; } 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,14 +192,11 @@ 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 primitives::{H256, Blake2Hasher}; + use support::{assert_ok, assert_noop, impl_outer_origin, parameter_types}; + use primitives::H256; // 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 sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; use system::EnsureSignedBy; impl_outer_origin! { @@ -232,7 +224,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -286,7 +277,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::{ @@ -298,7 +289,7 @@ mod tests { #[test] fn query_membership_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Membership::members(), vec![10, 20, 30]); assert_eq!(MEMBERS.with(|m| m.borrow().clone()), vec![10, 20, 30]); }); @@ -306,7 +297,7 @@ mod tests { #[test] fn add_member_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!(Membership::add_member(Origin::signed(5), 15), "bad origin"); assert_noop!(Membership::add_member(Origin::signed(1), 10), "already a member"); assert_ok!(Membership::add_member(Origin::signed(1), 15)); @@ -317,7 +308,7 @@ mod tests { #[test] fn remove_member_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!(Membership::remove_member(Origin::signed(5), 20), "bad origin"); assert_noop!(Membership::remove_member(Origin::signed(2), 15), "not a member"); assert_ok!(Membership::remove_member(Origin::signed(2), 20)); @@ -328,7 +319,7 @@ mod tests { #[test] fn swap_member_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!(Membership::swap_member(Origin::signed(5), 10, 25), "bad origin"); assert_noop!(Membership::swap_member(Origin::signed(3), 15, 25), "not a member"); assert_noop!(Membership::swap_member(Origin::signed(3), 10, 30), "already a member"); @@ -342,7 +333,7 @@ mod tests { #[test] fn reset_members_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!(Membership::reset_members(Origin::signed(1), vec![20, 40, 30]), "bad origin"); assert_ok!(Membership::reset_members(Origin::signed(4), vec![20, 40, 30])); assert_eq!(Membership::members(), vec![20, 30, 40]); 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/metadata/src/lib.rs b/srml/metadata/src/lib.rs index bf7c379000d760cffb39c950c0fc6eace93e2934..d85a6837fc6e015d7d1c2068a685e1eaa9283fea 100644 --- a/srml/metadata/src/lib.rs +++ b/srml/metadata/src/lib.rs @@ -28,6 +28,7 @@ use serde::Serialize; use codec::{Decode, Input, Error}; use codec::{Encode, Output}; use rstd::vec::Vec; +use primitives::RuntimeDebug; #[cfg(feature = "std")] type StringBuf = String; @@ -84,13 +85,12 @@ impl Eq for DecodeDifferent where B: Encode + Eq + PartialEq + 'static, O: Encode + Eq + PartialEq + 'static {} -#[cfg(feature = "std")] -impl std::fmt::Debug for DecodeDifferent +impl rstd::fmt::Debug for DecodeDifferent where - B: std::fmt::Debug + Eq + 'static, - O: std::fmt::Debug + Eq + 'static, + B: rstd::fmt::Debug + Eq + 'static, + O: rstd::fmt::Debug + Eq + 'static, { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { match self { DecodeDifferent::Encode(b) => b.fmt(f), DecodeDifferent::Decoded(o) => o.fmt(f), @@ -114,14 +114,11 @@ impl serde::Serialize for DecodeDifferent pub type DecodeDifferentArray = DecodeDifferent<&'static [B], Vec>; -#[cfg(feature = "std")] -type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; -#[cfg(not(feature = "std"))] type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; /// All the metadata about a function. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct FunctionMetadata { pub name: DecodeDifferentStr, pub arguments: DecodeDifferentArray, @@ -129,8 +126,8 @@ pub struct FunctionMetadata { } /// All the metadata about a function argument. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct FunctionArgumentMetadata { pub name: DecodeDifferentStr, pub ty: DecodeDifferentStr, @@ -154,9 +151,8 @@ impl PartialEq for FnEncode { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for FnEncode { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl rstd::fmt::Debug for FnEncode { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { self.0().fmt(f) } } @@ -169,8 +165,8 @@ impl serde::Serialize for FnEncode { } /// All the metadata about an outer event. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct OuterEventMetadata { pub name: DecodeDifferentStr, pub events: DecodeDifferentArray< @@ -179,9 +175,9 @@ pub struct OuterEventMetadata { >, } -/// All the metadata about a event. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +/// All the metadata about an event. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct EventMetadata { pub name: DecodeDifferentStr, pub arguments: DecodeDifferentArray<&'static str, StringBuf>, @@ -189,8 +185,8 @@ pub struct EventMetadata { } /// All the metadata about one storage entry. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct StorageEntryMetadata { pub name: DecodeDifferentStr, pub modifier: StorageEntryModifier, @@ -200,8 +196,8 @@ pub struct StorageEntryMetadata { } /// All the metadata about one module constant. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ModuleConstantMetadata { pub name: DecodeDifferentStr, pub ty: DecodeDifferentStr, @@ -209,6 +205,25 @@ pub struct ModuleConstantMetadata { pub documentation: DecodeDifferentArray<&'static str, StringBuf>, } +/// All the metadata about a module error. +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct ErrorMetadata { + pub name: DecodeDifferentStr, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about errors in a module. +pub trait ModuleErrorMetadata { + fn metadata() -> &'static [ErrorMetadata]; +} + +impl ModuleErrorMetadata for &'static str { + fn metadata() -> &'static [ErrorMetadata] { + &[] + } +} + /// A technical trait to store lazy initiated vec value as static dyn pointer. pub trait DefaultByte: Send + Sync { fn default_byte(&self) -> Vec; @@ -246,16 +261,15 @@ impl serde::Serialize for DefaultByteGetter { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for DefaultByteGetter { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl rstd::fmt::Debug for DefaultByteGetter { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { self.0.default_byte().fmt(f) } } /// Hasher used by storage maps -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageHasher { Blake2_128, Blake2_256, @@ -265,8 +279,8 @@ pub enum StorageHasher { } /// A storage entry type. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageEntryType { Plain(DecodeDifferentStr), Map { @@ -285,32 +299,32 @@ pub enum StorageEntryType { } /// A storage entry modifier. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageEntryModifier { Optional, Default, } /// All metadata of the storage. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct StorageMetadata { /// The common prefix used by all storage entries. pub prefix: DecodeDifferent<&'static str, StringBuf>, pub entries: DecodeDifferent<&'static [StorageEntryMetadata], Vec>, } -#[derive(Eq, Encode, PartialEq)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] /// Metadata prefixed by a u32 for reserved usage pub struct RuntimeMetadataPrefixed(pub u32, pub RuntimeMetadata); /// The metadata of a runtime. /// The version ID encoded/decoded through /// the enum nature of `RuntimeMetadata`. -#[derive(Eq, Encode, PartialEq)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum RuntimeMetadata { /// Unused; enum filler. V0(RuntimeMetadataDeprecated), @@ -326,13 +340,15 @@ pub enum RuntimeMetadata { V5(RuntimeMetadataDeprecated), /// Version 6 for runtime metadata. No longer used. V6(RuntimeMetadataDeprecated), - /// Version 7 for runtime metadata. - V7(RuntimeMetadataV7), + /// Version 7 for runtime metadata. No longer used. + V7(RuntimeMetadataDeprecated), + /// Version 8 for runtime metadata. + V8(RuntimeMetadataV8), } /// Enum that should fail. -#[derive(Eq, PartialEq)] -#[cfg_attr(feature = "std", derive(Debug, Serialize))] +#[derive(Eq, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize))] pub enum RuntimeMetadataDeprecated { } impl Encode for RuntimeMetadataDeprecated { @@ -349,24 +365,25 @@ impl Decode for RuntimeMetadataDeprecated { } /// The metadata of a runtime. -#[derive(Eq, Encode, PartialEq)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] -pub struct RuntimeMetadataV7 { +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct RuntimeMetadataV8 { pub modules: DecodeDifferentArray, } /// The latest version of the metadata. -pub type RuntimeMetadataLastVersion = RuntimeMetadataV7; +pub type RuntimeMetadataLastVersion = RuntimeMetadataV8; /// All metadata about an runtime module. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ModuleMetadata { pub name: DecodeDifferentStr, pub storage: Option, StorageMetadata>>, pub calls: ODFnA, pub event: ODFnA, pub constants: DFnA, + pub errors: DFnA, } type ODFnA = Option>; @@ -380,6 +397,6 @@ impl Into for RuntimeMetadataPrefixed { impl Into for RuntimeMetadataLastVersion { fn into(self) -> RuntimeMetadataPrefixed { - RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V7(self)) + RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V8(self)) } } diff --git a/srml/offences/Cargo.toml b/srml/offences/Cargo.toml index 4dd12413f67291407ad0c8df7364da88f9e6e85d..90a3396d112280285dfa1b55fcdcf1071e613cc9 100644 --- a/srml/offences/Cargo.toml +++ b/srml/offences/Cargo.toml @@ -8,14 +8,14 @@ edition = "2018" 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", optional = true } +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", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io" } substrate-primitives = { path = "../../core/primitives" } [features] diff --git a/srml/offences/src/lib.rs b/srml/offences/src/lib.rs index a89efa2f830c4725626c5cdd9b9ee6338d75414f..a6cf4d795646771e2dc424d2f5cd2190be6eef70 100644 --- a/srml/offences/src/lib.rs +++ b/srml/offences/src/lib.rs @@ -29,11 +29,11 @@ use rstd::{ collections::btree_set::BTreeSet, }; use support::{ - StorageMap, StorageDoubleMap, decl_module, decl_event, decl_storage, Parameter, + decl_module, decl_event, decl_storage, Parameter, }; use sr_primitives::{ Perbill, - traits::Hash, + traits::{Hash, Saturating}, }; use sr_staking_primitives::{ offence::{Offence, ReportOffence, Kind, OnOffenceHandler, OffenceDetails}, @@ -59,7 +59,7 @@ pub trait Trait: system::Trait { 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>; + Reports get(fn 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>; @@ -131,12 +131,9 @@ where offenders_count.saturating_sub(previous_offenders_count), validator_set_count, ); - let numerator = new_fraction - .into_parts() - .saturating_sub(previous_fraction.into_parts()); - let denominator = - Perbill::from_parts(Perbill::one().into_parts() - previous_fraction.into_parts()); - Perbill::from_parts(denominator * numerator) + let numerator = new_fraction.saturating_sub(previous_fraction); + let denominator = Perbill::one().saturating_sub(previous_fraction); + denominator.saturating_mul(numerator) } else { new_fraction.clone() }; diff --git a/srml/offences/src/mock.rs b/srml/offences/src/mock.rs index e7280c34e92431265b60bedda712de52e254679e..f9c79390819e0e83e4cfb48618c271a6150467ea 100644 --- a/srml/offences/src/mock.rs +++ b/srml/offences/src/mock.rs @@ -28,7 +28,7 @@ use sr_staking_primitives::{ }; use sr_primitives::testing::Header; use sr_primitives::traits::{IdentityLookup, BlakeTwo256}; -use substrate_primitives::{H256, Blake2Hasher}; +use substrate_primitives::H256; use support::{impl_outer_origin, impl_outer_event, parameter_types, StorageMap, StorageDoubleMap}; use {runtime_io, system}; @@ -78,7 +78,6 @@ impl system::Trait for Runtime { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = TestEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -103,7 +102,7 @@ impl_outer_event! { } } -pub fn new_test_ext() -> runtime_io::TestExternalities { +pub fn new_test_ext() -> runtime_io::TestExternalities { let t = system::GenesisConfig::default().build_storage::().unwrap(); t.into() } diff --git a/srml/offences/src/tests.rs b/srml/offences/src/tests.rs index 17f933b8e8d12bcd6dc9d8f26613e0cca753fccf..28e655d16bfdd2e93fa69ce211adca389f65bccb 100644 --- a/srml/offences/src/tests.rs +++ b/srml/offences/src/tests.rs @@ -24,11 +24,10 @@ use crate::mock::{ 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(), || { + new_test_ext().execute_with(|| { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -51,7 +50,7 @@ fn should_report_an_authority_and_trigger_on_offence() { #[test] fn should_calculate_the_fraction_correctly() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -83,7 +82,7 @@ fn should_calculate_the_fraction_correctly() { #[test] fn should_not_report_the_same_authority_twice_in_the_same_slot() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -113,7 +112,7 @@ fn should_not_report_the_same_authority_twice_in_the_same_slot() { #[test] fn should_report_in_different_time_slot() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -143,7 +142,7 @@ fn should_report_in_different_time_slot() { #[test] fn should_deposit_event() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -171,7 +170,7 @@ fn should_deposit_event() { #[test] fn doesnt_deposit_event_for_dups() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -208,7 +207,7 @@ fn doesnt_deposit_event_for_dups() { 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(), || { + new_test_ext().execute_with(|| { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); diff --git a/srml/randomness-collective-flip/Cargo.toml b/srml/randomness-collective-flip/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..5be9aad50f0b3003f82265d725e97fdb5cba8a2c --- /dev/null +++ b/srml/randomness-collective-flip/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "srml-randomness-collective-flip" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +safe-mix = { version = "1.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +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 } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } + +[dev-dependencies] +primitives = { package = "substrate-primitives", path = "../../core/primitives" } +runtime-io = { package = "sr-io", path = "../../core/sr-io" } + +[features] +default = ["std"] +std = [ + "safe-mix/std", + "system/std", + "codec/std", + "support/std", + "sr-primitives/std", + "rstd/std", +] diff --git a/srml/randomness-collective-flip/src/lib.rs b/srml/randomness-collective-flip/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..3644b8898c2ab3ebd8646078f39001c75737ec0c --- /dev/null +++ b/srml/randomness-collective-flip/src/lib.rs @@ -0,0 +1,280 @@ +// 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 . + +//! # Randomness Module +//! +//! The Randomness Collective Flip module provides a [`random`](./struct.Module.html#method.random) +//! function that generates low-influence random values based on the block hashes from the previous +//! `81` blocks. Low-influence randomness can be useful when defending against relatively weak +//! adversaries. +//! +//! ## Public Functions +//! +//! See the [`Module`](./struct.Module.html) struct for details of publicly available functions. +//! +//! ## Usage +//! +//! ### Prerequisites +//! +//! Import the Randomness Collective Flip module and derive your module's configuration trait from +//! the system trait. +//! +//! ### Example - Get random seed for the current block +//! +//! ``` +//! use support::{decl_module, dispatch::Result, traits::Randomness}; +//! +//! pub trait Trait: system::Trait {} +//! +//! decl_module! { +//! pub struct Module for enum Call where origin: T::Origin { +//! pub fn random_module_example(origin) -> Result { +//! let _random_seed = >::random_seed(); +//! Ok(()) +//! } +//! } +//! } +//! # fn main() { } +//! ``` + +#![cfg_attr(not(feature = "std"), no_std)] + +use rstd::{prelude::*, convert::TryInto}; +use sr_primitives::traits::Hash; +use support::{decl_module, decl_storage, traits::Randomness}; +use safe_mix::TripletMix; +use codec::Encode; +use system::Trait; + +const RANDOM_MATERIAL_LEN: u32 = 81; + +fn block_number_to_index(block_number: T::BlockNumber) -> usize { + // on_initialize is called on the first block after genesis + let index = (block_number - 1.into()) % RANDOM_MATERIAL_LEN.into(); + index.try_into().ok().expect("Something % 81 is always smaller than usize; qed") +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + fn on_initialize(block_number: T::BlockNumber) { + let parent_hash = >::parent_hash(); + + >::mutate(|ref mut values| if values.len() < RANDOM_MATERIAL_LEN as usize { + values.push(parent_hash) + } else { + let index = block_number_to_index::(block_number); + values[index] = parent_hash; + }); + } + } +} + +decl_storage! { + trait Store for Module as RandomnessCollectiveFlip { + /// Series of block headers from the last 81 blocks that acts as random seed material. This + /// is arranged as a ring buffer with `block_number % 81` being the index into the `Vec` of + /// the oldest hash. + RandomMaterial get(fn random_material): Vec; + } +} + +impl Randomness for Module { + /// Get a low-influence "random" value. + /// + /// Being a deterministic block chain, real randomness is difficult to come by. This gives you + /// something that approximates it. `subject` is a context identifier and allows you to get a + /// different result to other callers of this function; use it like + /// `random(&b"my context"[..])`. This is initially implemented through a low-influence + /// "triplet mix" convolution of previous block hash values. In the future it will be generated + /// from a secure verifiable random function (VRF). + /// + /// ### Security Notes + /// + /// This randomness uses a low-influence function, drawing upon the block hashes from the + /// previous 81 blocks. Its result for any given subject will be known far in advance by anyone + /// observing the chain. Any block producer has significant influence over their block hashes + /// bounded only by their computational resources. Our low-influence function reduces the actual + /// block producer's influence over the randomness, but increases the influence of small + /// colluding groups of recent block producers. + /// + /// Some BABE blocks have VRF outputs where the block producer has exactly one bit of influence, + /// either they make the block or they do not make the block and thus someone else makes the + /// next block. Yet, this randomness is not fresh in all BABE blocks. + /// + /// If that is an insufficient security guarantee then two things can be used to improve this + /// randomness: + /// + /// - Name, in advance, the block number whose random value will be used; ensure your module + /// retains a buffer of previous random values for its subject and then index into these in + /// order to obviate the ability of your user to look up the parent hash and choose when to + /// transact based upon it. + /// - Require your user to first commit to an additional value by first posting its hash. + /// Require them to reveal the value to determine the final result, hashing it with the + /// output of this random function. This reduces the ability of a cabal of block producers + /// from conspiring against individuals. + /// + /// WARNING: Hashing the result of this function will remove any low-influence properties it has + /// and mean that all bits of the resulting value are entirely manipulatable by the author of + /// the parent block, who can determine the value of `parent_hash`. + fn random(subject: &[u8]) -> T::Hash { + let block_number = >::block_number(); + let index = block_number_to_index::(block_number); + + let hash_series = >::get(); + if !hash_series.is_empty() { + // Always the case after block 1 is initialised. + hash_series.iter() + .cycle() + .skip(index) + .take(RANDOM_MATERIAL_LEN as usize) + .enumerate() + .map(|(i, h)| (i as i8, subject, h).using_encoded(T::Hashing::hash)) + .triplet_mix() + } else { + T::Hash::default() + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use primitives::H256; + use sr_primitives::{ + Perbill, traits::{BlakeTwo256, OnInitialize, Header as _, IdentityLookup}, testing::Header, + }; + use support::{impl_outer_origin, parameter_types, traits::Randomness}; + + #[derive(Clone, PartialEq, Eq)] + pub struct Test; + + impl_outer_origin! { + pub enum Origin for 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 Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type AvailableBlockRatio = AvailableBlockRatio; + type MaximumBlockLength = MaximumBlockLength; + type Version = (); + } + + type System = system::Module; + type CollectiveFlip = Module; + + fn new_test_ext() -> runtime_io::TestExternalities { + let t = system::GenesisConfig::default().build_storage::().unwrap(); + t.into() + } + + #[test] + fn test_block_number_to_index() { + for i in 1 .. 1000 { + assert_eq!((i - 1) as usize % 81, block_number_to_index::(i)); + } + } + + fn setup_blocks(blocks: u64) { + let mut parent_hash = System::parent_hash(); + + for i in 1 .. (blocks + 1) { + System::initialize(&i, &parent_hash, &Default::default(), &Default::default()); + CollectiveFlip::on_initialize(i); + + let header = System::finalize(); + parent_hash = header.hash(); + System::set_block_number(*header.number()); + } + } + + #[test] + fn test_random_material_parital() { + new_test_ext().execute_with(|| { + let genesis_hash = System::parent_hash(); + + setup_blocks(38); + + let random_material = CollectiveFlip::random_material(); + + assert_eq!(random_material.len(), 38); + assert_eq!(random_material[0], genesis_hash); + }); + } + + #[test] + fn test_random_material_filled() { + new_test_ext().execute_with(|| { + let genesis_hash = System::parent_hash(); + + setup_blocks(81); + + let random_material = CollectiveFlip::random_material(); + + assert_eq!(random_material.len(), 81); + assert_ne!(random_material[0], random_material[1]); + assert_eq!(random_material[0], genesis_hash); + }); + } + + #[test] + fn test_random_material_filled_twice() { + new_test_ext().execute_with(|| { + let genesis_hash = System::parent_hash(); + + setup_blocks(162); + + let random_material = CollectiveFlip::random_material(); + + assert_eq!(random_material.len(), 81); + assert_ne!(random_material[0], random_material[1]); + assert_ne!(random_material[0], genesis_hash); + }); + } + + #[test] + fn test_random() { + new_test_ext().execute_with(|| { + setup_blocks(162); + + assert_eq!(System::block_number(), 162); + assert_eq!(CollectiveFlip::random_seed(), CollectiveFlip::random_seed()); + assert_ne!(CollectiveFlip::random(b"random_1"), CollectiveFlip::random(b"random_2")); + + let random = CollectiveFlip::random_seed(); + + assert_ne!(random, H256::zero()); + assert!(!CollectiveFlip::random_material().contains(&random)); + }); + } +} diff --git a/srml/scored-pool/Cargo.toml b/srml/scored-pool/Cargo.toml index 6494d363facfec06010c5063c854b18b9349786e..e65f71a10d13ed24cadfe957ca7732df661d5291 100644 --- a/srml/scored-pool/Cargo.toml +++ b/srml/scored-pool/Cargo.toml @@ -6,11 +6,11 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -serde = { version = "1.0", optional = true } -sr-io = { path = "../../core/sr-io", default-features = false } +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 } -sr-std = { path = "../../core/sr-std", default-features = false } -srml-support = { path = "../support", 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] @@ -22,9 +22,9 @@ default = ["std"] std = [ "codec/std", "serde", - "sr-io/std", + "runtime-io/std", "sr-primitives/std", - "sr-std/std", - "srml-support/std", + "rstd/std", + "support/std", "system/std", ] diff --git a/srml/scored-pool/src/lib.rs b/srml/scored-pool/src/lib.rs index 1348b738643a25dee3b312f9591d03887dbaf664..5fde1e9c450cf986decd23accb2e47643bd4091a 100644 --- a/srml/scored-pool/src/lib.rs +++ b/srml/scored-pool/src/lib.rs @@ -53,7 +53,7 @@ //! ## Usage //! //! ``` -//! use srml_support::{decl_module, dispatch::Result}; +//! use support::{decl_module, dispatch::Result}; //! use system::ensure_signed; //! use srml_scored_pool::{self as scored_pool}; //! @@ -88,15 +88,18 @@ mod mock; #[cfg(test)] mod tests; -use codec::{Encode, Decode}; -use sr_std::prelude::*; -use srml_support::{ - StorageValue, StorageMap, decl_module, decl_storage, decl_event, ensure, +use codec::FullCodec; +use rstd::{ + fmt::Debug, + 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}, + traits::{EnsureOrigin, SimpleArithmetic, MaybeSerializeDeserialize, Zero, StaticLookup}, }; type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; @@ -117,7 +120,8 @@ pub trait Trait: system::Trait { type Currency: Currency + ReservableCurrency; /// The score attributed to a member or candidate. - type Score: SimpleArithmetic + Clone + Copy + Default + Encode + Decode + MaybeSerializeDebug; + type Score: + SimpleArithmetic + Clone + Copy + Default + FullCodec + MaybeSerializeDeserialize + Debug; /// The overarching event type. type Event: From> + Into<::Event>; @@ -154,50 +158,45 @@ 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; + Pool get(fn 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; + CandidateExists get(fn candidate_exists): map T::AccountId => bool; /// The current membership, stored as an ordered Vec. - Members get(members): Vec; + Members get(fn members): Vec; /// Size of the `Members` set. - MemberCount get(member_count) config(): u32; + MemberCount get(fn member_count) config(): u32; } 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 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); - }); + 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); }) } } @@ -219,7 +218,7 @@ decl_event!( /// See the transaction for who. CandidateScored, /// Phantom member, never used. - Dummy(sr_std::marker::PhantomData<(AccountId, I)>), + Dummy(rstd::marker::PhantomData<(AccountId, I)>), } ); @@ -228,7 +227,7 @@ decl_module! { for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Every `Period` blocks the `Members` set is refreshed from the /// highest scoring members in the pool. diff --git a/srml/scored-pool/src/mock.rs b/srml/scored-pool/src/mock.rs index 86c8b0d8cfd492977cf1899f56c79ac30fcd8e9f..394f486a8bec383bf28e52eef7a0a1c4c7a47aec 100644 --- a/srml/scored-pool/src/mock.rs +++ b/srml/scored-pool/src/mock.rs @@ -19,8 +19,8 @@ use super::*; use std::cell::RefCell; -use srml_support::{impl_outer_origin, parameter_types}; -use primitives::{H256, Blake2Hasher}; +use support::{impl_outer_origin, parameter_types}; +use primitives::H256; // 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::{ @@ -52,8 +52,6 @@ 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 system::Trait for Test { @@ -66,7 +64,6 @@ impl system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -80,15 +77,11 @@ impl balances::Trait for Test { 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! { @@ -132,7 +125,7 @@ impl Trait for Test { // This function basically just builds a genesis storage key/value store according to // our desired mockup. -pub fn new_test_ext() -> sr_io::TestExternalities { +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:: { diff --git a/srml/scored-pool/src/tests.rs b/srml/scored-pool/src/tests.rs index cec27e66cd81b7e4578f83a177efa0a42db70af2..2f47b5da6fe26c5a8c0443155b370fd38e2aa5b9 100644 --- a/srml/scored-pool/src/tests.rs +++ b/srml/scored-pool/src/tests.rs @@ -19,8 +19,7 @@ use super::*; use mock::*; -use srml_support::{assert_ok, assert_noop}; -use sr_io::with_externalities; +use support::{assert_ok, assert_noop}; use sr_primitives::traits::OnInitialize; type ScoredPool = Module; @@ -32,7 +31,7 @@ const INDEX_ERR: &str = "index does not match requested account"; #[test] fn query_membership_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(ScoredPool::members(), vec![20, 40]); assert_eq!(Balances::reserved_balance(&31), CandidateDeposit::get()); assert_eq!(Balances::reserved_balance(&40), CandidateDeposit::get()); @@ -42,7 +41,7 @@ fn query_membership_works() { #[test] fn submit_candidacy_must_not_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!( ScoredPool::submit_candidacy(Origin::signed(99)), "balance too low to submit candidacy" @@ -56,7 +55,7 @@ fn submit_candidacy_must_not_work() { #[test] fn submit_candidacy_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 15; @@ -71,7 +70,7 @@ fn submit_candidacy_works() { #[test] fn scoring_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 15; let score = 99; @@ -89,7 +88,7 @@ fn scoring_works() { #[test] fn scoring_same_element_with_same_score_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 31; let index = find_in_pool(who).expect("entity must be in pool") as u32; @@ -109,7 +108,7 @@ fn scoring_same_element_with_same_score_works() { #[test] fn kicking_works_only_for_authorized() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { 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"); @@ -118,7 +117,7 @@ fn kicking_works_only_for_authorized() { #[test] fn kicking_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 40; assert_eq!(Balances::reserved_balance(&who), CandidateDeposit::get()); @@ -138,7 +137,7 @@ fn kicking_works() { #[test] fn unscored_entities_must_not_be_used_for_filling_members() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given // we submit a candidacy, score will be `None` assert_ok!(ScoredPool::submit_candidacy(Origin::signed(15))); @@ -163,7 +162,7 @@ fn unscored_entities_must_not_be_used_for_filling_members() { #[test] fn refreshing_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 15; assert_ok!(ScoredPool::submit_candidacy(Origin::signed(who))); @@ -181,7 +180,7 @@ fn refreshing_works() { #[test] fn refreshing_happens_every_period() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given System::set_block_number(1); assert_ok!(ScoredPool::submit_candidacy(Origin::signed(15))); @@ -201,7 +200,7 @@ fn refreshing_happens_every_period() { #[test] fn withdraw_candidacy_must_only_work_for_members() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let who = 77; let index = 0; assert_noop!( ScoredPool::withdraw_candidacy(Origin::signed(who), index), INDEX_ERR); @@ -210,7 +209,7 @@ fn withdraw_candidacy_must_only_work_for_members() { #[test] fn oob_index_should_abort() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let who = 40; let oob_index = ScoredPool::pool().len() as u32; assert_noop!(ScoredPool::withdraw_candidacy(Origin::signed(who), oob_index), OOB_ERR); @@ -221,7 +220,7 @@ fn oob_index_should_abort() { #[test] fn index_mismatches_should_abort() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let who = 40; let index = 3; assert_noop!(ScoredPool::withdraw_candidacy(Origin::signed(who), index), INDEX_ERR); @@ -232,7 +231,7 @@ fn index_mismatches_should_abort() { #[test] fn withdraw_unscored_candidacy_must_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 5; @@ -247,7 +246,7 @@ fn withdraw_unscored_candidacy_must_work() { #[test] fn withdraw_scored_candidacy_must_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 40; assert_eq!(Balances::reserved_balance(&who), CandidateDeposit::get()); @@ -265,7 +264,7 @@ fn withdraw_scored_candidacy_must_work() { #[test] fn candidacy_resubmitting_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 15; diff --git a/srml/session/Cargo.toml b/srml/session/Cargo.toml index d0166997656ed78ac38503902997eaa94bf0e540..b114755ad91c203f9c1664bb32568edb9084c572 100644 --- a/srml/session/Cargo.toml +++ b/srml/session/Cargo.toml @@ -5,22 +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 } sr-staking-primitives = { path = "../../core/sr-staking-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 } 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"] @@ -30,9 +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 7e4686e92327fd6a5541ba35d5464ccb276ad47b..d3fbc67b950ec9802e4f98681d81d0c4d43ca72e 100644 --- a/srml/session/src/historical.rs +++ b/srml/session/src/historical.rs @@ -29,10 +29,8 @@ 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}; @@ -58,9 +56,9 @@ pub trait Trait: super::Trait { decl_storage! { trait Store for Module as Session { /// Mapping from historical session indices to session-data root hash and validator count. - HistoricalSessions get(historical_root): map SessionIndex => Option<(T::Hash, ValidatorCount)>; + HistoricalSessions get(fn 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 + CachedObsolete get(fn cached_obsolete): map SessionIndex => Option>; /// The range of historical sessions we store. [first, last) StoredRange: Option<(SessionIndex, SessionIndex)>; @@ -277,7 +275,7 @@ pub struct Proof { trie_nodes: Vec>, } -impl> srml_support::traits::KeyOwnerProofSystem<(KeyTypeId, D)> +impl> support::traits::KeyOwnerProofSystem<(KeyTypeId, D)> for Module { type Proof = Proof; @@ -314,18 +312,17 @@ impl> srml_support::traits::KeyOwnerProofSystem<(KeyTyp #[cfg(test)] mod tests { use super::*; - use runtime_io::with_externalities; - use primitives::{Blake2Hasher, crypto::key_types::DUMMY}; + use primitives::crypto::key_types::DUMMY; use sr_primitives::{traits::OnInitialize, testing::UintAuthorityId}; use crate::mock::{ NEXT_VALIDATORS, force_new_session, set_next_validators, Test, System, Session, }; - use srml_support::traits::KeyOwnerProofSystem; + use support::traits::KeyOwnerProofSystem; type Historical = Module; - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); crate::GenesisConfig:: { keys: NEXT_VALIDATORS.with(|l| @@ -337,7 +334,7 @@ mod tests { #[test] fn generated_proof_is_good() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { set_next_validators(vec![1, 2]); force_new_session(); @@ -378,7 +375,7 @@ mod tests { #[test] fn prune_up_to_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { for i in 1..101u64 { set_next_validators(vec![i]); force_new_session(); diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index f8e13d529b8753d7684cb0ae55c688a1afe5233d..76cc6d0663a49f49d07eedbab07147a5a15eb0a2 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -121,15 +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 sr_staking_primitives::SessionIndex; -use srml_support::{ - dispatch::Result, ConsensusEngineId, StorageValue, StorageDoubleMap, for_each_tuple, - decl_module, decl_event, decl_storage, +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)] @@ -170,6 +170,12 @@ impl< 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 @@ -192,7 +198,11 @@ pub trait SessionHandler { /// should provide the same validator set. fn on_genesis_session(validators: &[(ValidatorId, Ks)]); - /// Session set has changed; act appropriately. + /// 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)], @@ -212,16 +222,24 @@ pub trait SessionHandler { /// 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_genesis_session<'a, I: 'a>(validators: I) where I: Iterator, ValidatorId: 'a; - /// Session set has changed; act appropriately. + /// 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 + changed: bool, + validators: I, + queued_validators: I, ) where I: Iterator, ValidatorId: 'a; @@ -233,62 +251,51 @@ pub trait OneSessionHandler { /// 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_genesis_session(_: &[(AId, Ks)]) {} - fn on_new_session(_: bool, _: &[(AId, Ks)], _: &[(AId, Ks)]) {} - fn on_before_session_ending() {} - 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_genesis_session(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()))); + 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()))); - $t::on_genesis_session(our_keys); - )* - } - 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); - )* - } + Tuple::on_genesis_session(our_keys); + )* + ) + } - fn on_before_session_ending() { - $( - $t::on_before_session_ending(); - )* - } + 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_disabled(i: usize) { - $( - $t::on_disabled(i); - )* - } - } + 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 { @@ -327,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; } @@ -336,20 +349,23 @@ const DEDUP_KEY_PREFIX: &[u8] = b":session:keys"; decl_storage! { trait Store for Module as Session { /// The current set of validators. - Validators get(validators): Vec; + Validators get(fn validators): Vec; /// Current index of the session. - CurrentIndex get(current_index): SessionIndex; - - /// True if anything has changed in this session. - Changed: bool; + CurrentIndex get(fn current_index): SessionIndex; - /// 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)>; + QueuedKeys get(fn 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(fn disabled_validators): Vec; /// The next session keys for a validator. /// @@ -365,41 +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(); - // Tell everyone about the genesis session keys - T::SessionHandler::on_genesis_session::(&queued_keys); + // Tell everyone about the genesis session keys + T::SessionHandler::on_genesis_session::(&queued_keys); - >::put(initial_validators); - >::put(queued_keys); - }); + >::put(initial_validators); + >::put(queued_keys); }); } } @@ -443,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) { @@ -467,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(); @@ -476,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. @@ -492,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); @@ -503,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(()) } @@ -554,8 +624,6 @@ impl Module { let key_data = old_keys.get_raw(id); Self::clear_key_owner(id, key_data); } - - Changed::put(true); } } @@ -572,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)); } } @@ -611,19 +679,16 @@ impl> FindAuthor #[cfg(test)] mod tests { use super::*; - use srml_support::assert_ok; - use runtime_io::with_externalities; - use primitives::{Blake2Hasher, crypto::key_types::DUMMY}; - use sr_primitives::{ - traits::OnInitialize, - testing::UintAuthorityId, - }; + use support::assert_ok; + use primitives::crypto::key_types::DUMMY; + use sr_primitives::{traits::OnInitialize, testing::UintAuthorityId}; 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 { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig:: { keys: NEXT_VALIDATORS.with(|l| @@ -641,7 +706,7 @@ mod tests { #[test] fn simple_setup_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); assert_eq!(Session::validators(), vec![1, 2, 3]); }); @@ -649,7 +714,7 @@ mod tests { #[test] fn put_get_keys() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { Session::put_keys(&10, &UintAuthorityId(10).into()); assert_eq!(Session::load_keys(&10), Some(UintAuthorityId(10).into())); }) @@ -658,7 +723,7 @@ mod tests { #[test] fn keys_cleared_on_kill() { let mut ext = new_test_ext(); - with_externalities(&mut ext, || { + ext.execute_with(|| { assert_eq!(Session::validators(), vec![1, 2, 3]); assert_eq!(Session::load_keys(&1), Some(UintAuthorityId(1).into())); @@ -668,14 +733,14 @@ 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() { - with_externalities(&mut new_test_ext(), || { + reset_before_session_end_called(); + + new_test_ext().execute_with(|| { set_next_validators(vec![1, 2]); force_new_session(); initialize_block(1); @@ -685,6 +750,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); @@ -694,6 +761,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![])); @@ -706,6 +775,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); @@ -721,7 +791,7 @@ mod tests { #[test] fn should_work_with_early_exit() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { set_session_length(10); initialize_block(1); @@ -744,7 +814,7 @@ mod tests { #[test] fn session_change_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // Block 1: No change initialize_block(1); assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); @@ -774,7 +844,7 @@ mod tests { #[test] fn duplicates_are_not_allowed() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); Session::on_initialize(1); assert!(Session::set_keys(Origin::signed(4), UintAuthorityId(1).into(), vec![]).is_err()); @@ -787,38 +857,63 @@ mod tests { #[test] fn session_changed_flag_works() { - with_externalities(&mut new_test_ext(), || { + reset_before_session_end_called(); + + new_test_ext().execute_with(|| { 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(); }); } @@ -853,7 +948,7 @@ mod tests { #[test] fn session_keys_generate_output_works_as_set_keys_input() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let new_keys = mock::MockSessionKeys::generate(None); assert_ok!( Session::set_keys( @@ -864,4 +959,21 @@ mod tests { ); }); } + + #[test] + fn return_true_if_more_than_third_is_disabled() { + new_test_ext().execute_with(|| { + 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 c5608e1a54571756d373ff4e34c23610e1176c06..d680fdc96b0159ce3993c31170092746af717109 100644 --- a/srml/session/src/mock.rs +++ b/srml/session/src/mock.rs @@ -18,7 +18,7 @@ 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}, @@ -44,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)]); @@ -51,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; @@ -76,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 } @@ -92,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)) } } @@ -125,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; @@ -145,7 +168,6 @@ impl system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -160,6 +182,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")] @@ -172,6 +198,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 d985730912c56b6dce2d6cf95e593069200a6ff9..67f3ab41d6583f73deb70ff2e6b01539e73182c6 100644 --- a/srml/staking/Cargo.toml +++ b/srml/staking/Cargo.toml @@ -5,15 +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 } sr-staking-primitives = { path = "../../core/sr-staking-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 } session = { package = "srml-session", path = "../session", default-features = false, features = ["historical"] } authorship = { package = "srml-authorship", path = "../authorship", default-features = false } @@ -22,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", @@ -34,8 +34,9 @@ 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", 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 e7bb42c64dfe5bfc2ef5ba8c3ed761ce282f0a5b..e7d7c073a158433dfc2b09935f5da437bc62a142 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -136,7 +136,7 @@ //! ### 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}; //! @@ -243,50 +243,42 @@ #![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; pub mod inflation; -#[cfg(all(feature = "bench", test))] -mod benches; - -#[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}; -use sr_primitives::Perbill; -use sr_primitives::weights::SimpleDispatchInfo; -use sr_primitives::traits::{ - Convert, Zero, One, StaticLookup, CheckedSub, Saturating, Bounded, - SimpleArithmetic, SaturatedConversion, +use sr_primitives::{ + Perbill, + RuntimeDebug, + curve::PiecewiseLinear, + weights::SimpleDispatchInfo, + traits::{ + Convert, Zero, One, StaticLookup, CheckedSub, Saturating, Bounded, SaturatedConversion, + } }; use sr_staking_primitives::{ - SessionIndex, CurrentElectedSet, + 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 DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4; const MAX_NOMINATIONS: usize = 16; @@ -296,30 +288,34 @@ 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 } } } /// Indicates the initial status of the staker. -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum StakerStatus { /// Chilling. Idle, @@ -330,8 +326,7 @@ pub enum StakerStatus { } /// A destination account for payment. -#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug)] pub enum RewardDestination { /// Pay into the stash account, increasing the amount at stake accordingly. Staked, @@ -348,8 +343,7 @@ impl Default for RewardDestination { } /// Preference of what happens on a slash event. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] pub struct ValidatorPrefs { /// Reward that validator takes up-front; only the rest is split between themselves and /// nominators. @@ -366,8 +360,7 @@ impl Default for ValidatorPrefs { } /// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] pub struct UnlockChunk { /// Amount of funds to be unlocked. #[codec(compact)] @@ -378,8 +371,7 @@ pub struct UnlockChunk { } /// The ledger of a (bonded) stash. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] pub struct StakingLedger { /// The stash account whose balance is actually locked and at stake. pub stash: AccountId, @@ -417,8 +409,7 @@ impl< } /// The amount of exposure (to slashing) than an individual nominator has. -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, RuntimeDebug)] pub struct IndividualExposure { /// The stash account of the nominator in question. who: AccountId, @@ -428,8 +419,7 @@ pub struct IndividualExposure { } /// A snapshot of the stake backing a single validator in the system. -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, RuntimeDebug)] pub struct Exposure { /// The total balance backing this validator. #[codec(compact)] @@ -442,8 +432,7 @@ pub struct Exposure { } /// 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))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, RuntimeDebug)] pub struct SlashJournalEntry { who: AccountId, amount: Balance, @@ -458,22 +447,16 @@ 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. @@ -491,7 +474,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) } @@ -515,7 +498,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. @@ -538,11 +521,14 @@ 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. -#[derive(Copy, Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum Forcing { /// Not forcing anything - just let whatever happen. NotForcing, @@ -560,108 +546,104 @@ decl_storage! { trait Store for Module as Staking { /// The ideal number of staking participants. - pub ValidatorCount get(validator_count) config(): u32; + pub ValidatorCount get(fn validator_count) config(): u32; /// Minimum number of staking participants before emergency conditions are imposed. - pub MinimumValidatorCount get(minimum_validator_count) config(): + pub MinimumValidatorCount get(fn minimum_validator_count) config(): u32 = DEFAULT_MINIMUM_VALIDATOR_COUNT; /// 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 /// invulnerables) and restricted to testnets. - pub Invulnerables get(invulnerables) config(): Vec; + pub Invulnerables get(fn invulnerables) config(): Vec; /// Map from all locked "stash" accounts to the controller account. - pub Bonded get(bonded): map T::AccountId => Option; + pub Bonded get(fn bonded): map T::AccountId => Option; /// Map from all (unlocked) "controller" accounts to the info regarding the staking. - pub Ledger get(ledger): + pub Ledger get(fn ledger): map T::AccountId => Option>>; /// Where the reward payment should be made. Keyed by stash. - pub Payee get(payee): map T::AccountId => RewardDestination; + pub Payee get(fn payee): map T::AccountId => RewardDestination; /// The map from (wannabe) validator stash key to the preferences of that validator. - pub Validators get(validators): linked_map T::AccountId => ValidatorPrefs>; + pub Validators get(fn validators): linked_map T::AccountId => ValidatorPrefs>; /// The map from nominator stash key to the set of stash keys of all validators to nominate. - pub Nominators get(nominators): linked_map T::AccountId => Vec; + pub Nominators get(fn nominators): linked_map T::AccountId => Vec; /// Nominators for a particular account that is in action right now. You can't iterate /// through validators here, but you can find them in the Session module. /// /// This is keyed by the stash account. - pub Stakers get(stakers): map T::AccountId => Exposure>; + pub Stakers get(fn stakers): map T::AccountId => Exposure>; /// The currently elected validator set keyed by stash account ID. - pub CurrentElected get(current_elected): Vec; + pub CurrentElected get(fn current_elected): Vec; /// The current era index. - pub CurrentEra get(current_era) config(): EraIndex; + pub CurrentEra get(fn current_era) config(): EraIndex; /// The start of the current era. - pub CurrentEraStart get(current_era_start): MomentOf; + pub CurrentEraStart get(fn current_era_start): MomentOf; /// The session index at which the current era started. - pub CurrentEraStartSessionIndex get(current_era_start_session_index): SessionIndex; + pub CurrentEraStartSessionIndex get(fn 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(fn current_era_reward): EraPoints; /// The amount of balance actively at stake for each validator slot, currently. /// /// This is used to derive rewards and punishments. - pub SlotStake get(slot_stake) build(|config: &GenesisConfig| { + pub SlotStake get(fn slot_stake) build(|config: &GenesisConfig| { config.stakers.iter().map(|&(_, _, value, _)| value).min().unwrap_or_default() }): BalanceOf; /// True if the next session change will be a new era regardless of index. - pub ForceEra get(force_era) config(): Forcing; + pub ForceEra get(fn 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; + pub SlashRewardFraction get(fn 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): + EraSlashJournal get(fn 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(()) + }; + } }); } } @@ -686,7 +668,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. @@ -698,7 +680,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. /// @@ -735,7 +717,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); @@ -777,7 +759,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. @@ -900,8 +882,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); @@ -1019,8 +1001,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) @@ -1036,7 +1018,7 @@ impl Module { &ledger.stash, ledger.total, T::BlockNumber::max_value(), - WithdrawReasons::except(WithdrawReason::TransactionPayment), + WithdrawReasons::all(), ); >::insert(controller, ledger); } @@ -1179,10 +1161,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() { @@ -1192,23 +1174,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); @@ -1249,90 +1233,81 @@ 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. @@ -1342,11 +1317,24 @@ impl Module { // 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. @@ -1355,6 +1343,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. @@ -1394,7 +1386,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() @@ -1414,7 +1406,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); @@ -1460,31 +1452,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); @@ -1552,10 +1519,11 @@ impl OnOffenceHandler ReportOffence R::report_offence(reporters, offence) } else { >::deposit_event( - RawEvent::OldSlashingReportDiscarded(offence_session).into() + RawEvent::OldSlashingReportDiscarded(offence_session) ) } } } - -/// Returns the currently elected validator set represented by their stash accounts. -pub struct CurrentElectedStashAccounts(rstd::marker::PhantomData); - -impl CurrentElectedSet for CurrentElectedStashAccounts { - fn current_elected_set() -> Vec { - >::current_elected() - } -} diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index aafe065118fa1cf1b7621eb1bbf6809ac420391f..41a2ad4802097ae27e41c07773532319148436af 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -18,13 +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 primitives::H256; 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 @@ -41,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! { @@ -94,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) } @@ -119,7 +118,6 @@ impl system::Trait for Test { type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -130,28 +128,23 @@ impl system::Trait for Test { parameter_types! { pub const TransferFee: Balance = 0; pub const CreationFee: Balance = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = Balance; type OnFreeBalanceZero = Staking; 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 = (); } 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; @@ -162,6 +155,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 { @@ -182,9 +176,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: SessionIndex = 3; pub const BondingDuration: EraIndex = 3; + pub const RewardCurve: &'static PiecewiseLinear<'static> = &I_NPOS; } impl Trait for Test { type Currency = balances::Module; @@ -197,6 +202,7 @@ impl Trait for Test { type SessionsPerEra = SessionsPerEra; type BondingDuration = BondingDuration; type SessionInterface = Self; + type RewardCurve = RewardCurve; } pub struct ExtBuilder { @@ -261,7 +267,7 @@ impl ExtBuilder { pub fn set_associated_consts(&self) { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); } - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> runtime_io::TestExternalities { self.set_associated_consts(); let mut storage = system::GenesisConfig::default().build_storage::().unwrap(); let balance_factor = if self.existential_deposit > 0 { @@ -327,8 +333,8 @@ impl ExtBuilder { keys: validators.iter().map(|x| (*x, UintAuthorityId(*x))).collect(), }.assimilate_storage(&mut storage); - let mut ext = storage.into(); - runtime_io::with_externalities(&mut ext, || { + let mut ext = runtime_io::TestExternalities::from(storage); + ext.execute_with(|| { let validators = Session::validators(); SESSION.with(|x| *x.borrow_mut() = (validators.clone(), HashSet::new()) @@ -381,11 +387,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."); } @@ -393,16 +394,16 @@ 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)); } @@ -416,7 +417,7 @@ pub fn start_session(session_index: SessionIndex) { 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()); } @@ -430,7 +431,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 bbae3615c2b6e68b95794cf728babc83c56fbf01..2cb798115403b8fbb459b7d92aa313eddeb51b50 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -17,28 +17,32 @@ //! Tests for the module. use super::*; -use runtime_io::with_externalities; -use phragmen; -use sr_primitives::traits::OnInitialize; -use sr_staking_primitives::offence::{OffenceDetails, OnOffenceHandler}; -use srml_support::{assert_ok, assert_noop, assert_eq_uvec, EnumerableStorageMap}; use mock::*; -use srml_support::traits::{Currency, ReservableCurrency}; +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, traits::{Currency, ReservableCurrency}}; #[test] fn basic_setup_works() { // Verifies initial conditions of mock - 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 + ExtBuilder::default().build().execute_with(|| { + // 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); @@ -49,8 +53,10 @@ fn basic_setup_works() { (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") { @@ -99,8 +105,7 @@ fn basic_setup_works() { #[test] fn change_controller_works() { - with_externalities(&mut ExtBuilder::default().build(), - || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Staking::bonded(&11), Some(10)); assert!(>::enumerate().map(|(c, _)| c).collect::>().contains(&11)); @@ -126,14 +131,11 @@ fn rewards_should_work() { // * rewards get recorded per session // * rewards get paid per Era // * Check that nominators are also rewarded - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { + ExtBuilder::default().nominate(false).build().execute_with(|| { // 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); @@ -161,7 +163,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); @@ -173,7 +175,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 @@ -183,21 +185,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); }); } @@ -207,19 +209,15 @@ fn multi_era_reward_should_work() { // Should check that: // The value of current_session_reward is set at the end of each era, based on // slot_stake and session_reward. - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { + ExtBuilder::default().nominate(false).build().execute_with(|| { let init_balance_10 = Balances::total_balance(&10); // Set payee to controller 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)]); start_session(0); @@ -232,7 +230,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)]); @@ -250,131 +248,128 @@ fn staking_should_work() { // * new validators can be added to the default set // * new ones will be chosen per era // * either one can unlock the stash and back-down from being a validator via `chill`ing. - with_externalities(&mut ExtBuilder::default() + ExtBuilder::default() .nominate(false) .fair(false) // to give 20 more staked value - .build(), - || { - Timestamp::set_timestamp(1); // Initialize time. + .build() + .execute_with(|| { + Timestamp::set_timestamp(1); // Initialize time. - // remember + compare this along with the test. - assert_eq_uvec!(validator_controllers(), vec![20, 10]); + // remember + compare this along with the test. + assert_eq_uvec!(validator_controllers(), vec![20, 10]); - // put some money in account that we'll use. - for i in 1..5 { let _ = Balances::make_free_balance_be(&i, 2000); } + // put some money in account that we'll use. + for i in 1..5 { let _ = Balances::make_free_balance_be(&i, 2000); } - // --- Block 1: - start_session(1); - // add a new candidate for being a validator. account 3 controlled by 4. - assert_ok!(Staking::bond(Origin::signed(3), 4, 1500, RewardDestination::Controller)); - assert_ok!(Staking::validate(Origin::signed(4), ValidatorPrefs::default())); + // --- Block 1: + start_session(1); + // add a new candidate for being a validator. account 3 controlled by 4. + assert_ok!(Staking::bond(Origin::signed(3), 4, 1500, RewardDestination::Controller)); + assert_ok!(Staking::validate(Origin::signed(4), ValidatorPrefs::default())); - // No effects will be seen so far. - assert_eq_uvec!(validator_controllers(), vec![20, 10]); + // No effects will be seen so far. + assert_eq_uvec!(validator_controllers(), vec![20, 10]); - // --- Block 2: - start_session(2); + // --- Block 2: + start_session(2); - // No effects will be seen so far. Era has not been yet triggered. - assert_eq_uvec!(validator_controllers(), vec![20, 10]); + // No effects will be seen so far. Era has not been yet triggered. + assert_eq_uvec!(validator_controllers(), vec![20, 10]); - // --- Block 3: the validators will now be queued. - start_session(3); - assert_eq!(Staking::current_era(), 1); + // --- Block 3: the validators will now be queued. + start_session(3); + assert_eq!(Staking::current_era(), 1); - // --- Block 4: the validators will now be changed. - start_session(4); + // --- Block 4: the validators will now be changed. + start_session(4); - assert_eq_uvec!(validator_controllers(), vec![20, 4]); - // --- Block 4: Unstake 4 as a validator, freeing up the balance stashed in 3 - // 4 will chill - Staking::chill(Origin::signed(4)).unwrap(); + assert_eq_uvec!(validator_controllers(), vec![20, 4]); + // --- Block 4: Unstake 4 as a validator, freeing up the balance stashed in 3 + // 4 will chill + Staking::chill(Origin::signed(4)).unwrap(); - // --- Block 5: nothing. 4 is still there. - start_session(5); - assert_eq_uvec!(validator_controllers(), vec![20, 4]); + // --- Block 5: nothing. 4 is still there. + start_session(5); + assert_eq_uvec!(validator_controllers(), vec![20, 4]); - // --- Block 6: 4 will not be a validator. - start_session(7); - assert_eq_uvec!(validator_controllers(), vec![20, 10]); + // --- Block 6: 4 will not be a validator. + start_session(7); + assert_eq_uvec!(validator_controllers(), vec![20, 10]); - // Note: the stashed value of 4 is still lock - assert_eq!( - Staking::ledger(&4), - Some(StakingLedger { stash: 3, total: 1500, active: 1500, unlocking: vec![] }) - ); - // e.g. it cannot spend more than 500 that it has free from the total 2000 - assert_noop!(Balances::reserve(&3, 501), "account liquidity restrictions prevent withdrawal"); - assert_ok!(Balances::reserve(&3, 409)); - }); + // Note: the stashed value of 4 is still lock + assert_eq!( + Staking::ledger(&4), + Some(StakingLedger { stash: 3, total: 1500, active: 1500, unlocking: vec![] }) + ); + // e.g. it cannot spend more than 500 that it has free from the total 2000 + assert_noop!(Balances::reserve(&3, 501), "account liquidity restrictions prevent withdrawal"); + assert_ok!(Balances::reserve(&3, 409)); + }); } #[test] fn less_than_needed_candidates_works() { - with_externalities(&mut ExtBuilder::default() + ExtBuilder::default() .minimum_validator_count(1) .validator_count(4) .nominate(false) .num_validators(3) - .build(), - || { - assert_eq!(Staking::validator_count(), 4); - assert_eq!(Staking::minimum_validator_count(), 1); - assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]); - - start_era(1); - - // Previous set is selected. NO election algorithm is even executed. - assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]); - - // But the exposure is updated in a simple way. No external votes exists. This is purely self-vote. - assert_eq!(Staking::stakers(10).others.len(), 0); - assert_eq!(Staking::stakers(20).others.len(), 0); - assert_eq!(Staking::stakers(30).others.len(), 0); - check_exposure_all(); - check_nominator_all(); - }); + .build() + .execute_with(|| { + assert_eq!(Staking::validator_count(), 4); + assert_eq!(Staking::minimum_validator_count(), 1); + assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]); + + start_era(1); + + // Previous set is selected. NO election algorithm is even executed. + assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]); + + // But the exposure is updated in a simple way. No external votes exists. + // This is purely self-vote. + assert_eq!(Staking::stakers(10).others.len(), 0); + assert_eq!(Staking::stakers(20).others.len(), 0); + assert_eq!(Staking::stakers(30).others.len(), 0); + check_exposure_all(); + check_nominator_all(); + }); } #[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() + ExtBuilder::default() .minimum_validator_count(10) .validator_count(15) .num_validators(4) .validator_pool(true) .nominate(false) - .build(), - || { + .build() + .execute_with(|| { + // initial validators + assert_eq_uvec!(validator_controllers(), vec![10, 20, 30, 40]); - // initial validators - assert_eq_uvec!(validator_controllers(), vec![10, 20, 30, 40]); + // set the minimum validator count. + ::MinimumValidatorCount::put(10); + ::ValidatorCount::put(15); + assert_eq!(Staking::validator_count(), 15); - // set the minimum validator count. - ::MinimumValidatorCount::put(10); - ::ValidatorCount::put(15); - assert_eq!(Staking::validator_count(), 15); + let _ = Staking::chill(Origin::signed(10)); - let _ = Staking::chill(Origin::signed(10)); - - // trigger era - System::set_block_number(1); - Session::on_initialize(System::block_number()); + // trigger era + System::set_block_number(1); + Session::on_initialize(System::block_number()); - // Previous ones are elected. chill is invalidates. TODO: #2494 - assert_eq_uvec!(validator_controllers(), vec![10, 20, 30, 40]); - assert_eq!(Staking::current_elected().len(), 0); - }); + // Previous ones are elected. chill is invalidates. TODO: #2494 + assert_eq_uvec!(validator_controllers(), vec![10, 20, 30, 40]); + assert_eq!(Staking::current_elected().len(), 0); + }); } #[test] 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 @@ -408,149 +403,181 @@ fn nominating_and_rewards_should_work() { // 10 with stake 400.0 20 with stake 600.0 30 with stake 0 // 4 has load 0.0005555555555555556 and supported // 10 with stake 600.0 20 with stake 400.0 40 with stake 0.0 - with_externalities(&mut ExtBuilder::default() + ExtBuilder::default() .nominate(false) .validator_pool(true) - .build(), - || { - // initial validators -- everyone is actually even. - assert_eq_uvec!(validator_controllers(), vec![40, 30]); - - // Set payee 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)); - - // give the man some money - let initial_balance = 1000; - for i in [1, 2, 3, 4, 5, 10, 11, 20, 21].iter() { - let _ = Balances::make_free_balance_be(i, initial_balance); - } - - // bond two account pairs and state interest in nomination. - // 2 will nominate for 10, 20, 30 - assert_ok!(Staking::bond(Origin::signed(1), 2, 1000, RewardDestination::Controller)); - assert_ok!(Staking::nominate(Origin::signed(2), vec![11, 21, 31])); - // 4 will nominate for 10, 20, 40 - assert_ok!(Staking::bond(Origin::signed(3), 4, 1000, RewardDestination::Controller)); - 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); - assert!(total_payout_0 > 100); // Test is meaningfull if reward something - >::reward_by_ids(vec![(41, 1)]); - >::reward_by_ids(vec![(31, 1)]); - >::reward_by_ids(vec![(21, 10)]); // must be no-op - >::reward_by_ids(vec![(11, 10)]); // must be no-op - - start_era(1); - - // 10 and 20 have more votes, they will be chosen by phragmen. - 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); - - // ------ 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); - // 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] - ); - assert_eq!( - Staking::stakers(11).others.iter().map(|e| e.who).collect::>(), - vec![3, 1] - ); - // 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); - // 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] - ); - assert_eq!( - Staking::stakers(21).others.iter().map(|e| e.who).collect::>(), - vec![3, 1] - ); - } else { - // 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 + 800); - // 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![400, 400] - ); - assert_eq!( - Staking::stakers(11).others.iter().map(|e| e.who).collect::>(), - vec![3, 1] - ); - // 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); - // 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] - ); - assert_eq!( - Staking::stakers(21).others.iter().map(|e| e.who).collect::>(), - vec![3, 1] - ); - } - - // They are not chosen anymore - assert_eq!(Staking::stakers(31).total, 0); - assert_eq!(Staking::stakers(41).total, 0); - - // the total reward for era 1 - let total_payout_1 = current_total_payout_for_duration(3); - 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 - >::reward_by_ids(vec![(21, 2)]); - >::reward_by_ids(vec![(11, 1)]); - - start_era(2); - - // 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; - 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); - - // Validator 10: got 1000 / 2000 external stake. - assert_eq!(Balances::total_balance(&10), initial_balance + payout_for_10/2); - // Validator 20: got 1000 / 2000 external stake. - assert_eq!(Balances::total_balance(&20), initial_balance + payout_for_20/2); - } 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); - // 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); - - // 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); - // 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); - } - - check_exposure_all(); - check_nominator_all(); - }); + .build() + .execute_with(|| { + // initial validators -- everyone is actually even. + assert_eq_uvec!(validator_controllers(), vec![40, 30]); + + // Set payee 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)); + + // give the man some money + let initial_balance = 1000; + for i in [1, 2, 3, 4, 5, 10, 11, 20, 21].iter() { + let _ = Balances::make_free_balance_be(i, initial_balance); + } + + // bond two account pairs and state interest in nomination. + // 2 will nominate for 10, 20, 30 + assert_ok!(Staking::bond(Origin::signed(1), 2, 1000, RewardDestination::Controller)); + assert_ok!(Staking::nominate(Origin::signed(2), vec![11, 21, 31])); + // 4 will nominate for 10, 20, 40 + assert_ok!(Staking::bond(Origin::signed(3), 4, 1000, RewardDestination::Controller)); + 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(3000); + assert!(total_payout_0 > 100); // Test is meaningfull if reward something + >::reward_by_ids(vec![(41, 1)]); + >::reward_by_ids(vec![(31, 1)]); + >::reward_by_ids(vec![(21, 10)]); // must be no-op + >::reward_by_ids(vec![(11, 10)]); // must be no-op + + start_era(1); + + // 10 and 20 have more votes, they will be chosen by phragmen. + 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); + + // ------ 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_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![600, 400] + ); + assert_eq!( + Staking::stakers(11).others.iter().map(|e| e.who).collect::>(), + vec![3, 1] + ); + // total expo of 20, with 500 coming from nominators (externals), according to phragmen. + assert_eq!(Staking::stakers(21).own, 1000); + 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, 600] + ); + assert_eq!( + Staking::stakers(21).others.iter().map(|e| e.who).collect::>(), + vec![3, 1] + ); + } else { + // 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 + 800); + // 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![400, 400] + ); + assert_eq!( + Staking::stakers(11).others.iter().map(|e| e.who).collect::>(), + vec![3, 1] + ); + // total expo of 20, with 500 coming from nominators (externals), according to phragmen. + assert_eq!(Staking::stakers(21).own, 1000); + 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![600, 600] + ); + assert_eq!( + Staking::stakers(21).others.iter().map(|e| e.who).collect::>(), + vec![3, 1] + ); + } + + // They are not chosen anymore + assert_eq!(Staking::stakers(31).total, 0); + assert_eq!(Staking::stakers(41).total, 0); + + // the total reward for era 1 + 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 + >::reward_by_ids(vec![(21, 2)]); + >::reward_by_ids(vec![(11, 1)]); + + start_era(2); + + // 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; + if cfg!(feature = "equalize") { + // 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_error_rate!( + Balances::total_balance(&10), + initial_balance + payout_for_10 / 2, + 1, + ); + // Validator 20: got 1000 / 2000 external stake. + 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_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_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_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_error_rate!( + Balances::total_balance(&20), + initial_balance + 5 * payout_for_20 / 11, + 1, + ); + } + + check_exposure_all(); + check_nominator_all(); + }); } #[test] @@ -560,7 +587,7 @@ fn nominators_also_get_slashed() { // 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(), || { + ExtBuilder::default().nominate(false).build().execute_with(|| { assert_eq!(Staking::validator_count(), 2); // Set payee to controller @@ -577,7 +604,7 @@ fn nominators_also_get_slashed() { 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)]); @@ -620,47 +647,49 @@ fn double_staking_should_fail() { // * an account already bonded as stash cannot be be stashed again. // * an account already bonded as stash cannot nominate. // * an account already bonded as controller can nominate. - with_externalities(&mut ExtBuilder::default() - .build(), - || { - let arbitrary_value = 5; - // 2 = controller, 1 stashed => ok - assert_ok!( - Staking::bond(Origin::signed(1), 2, arbitrary_value, - RewardDestination::default()) - ); - // 4 = not used so far, 1 stashed => not allowed. - assert_noop!( - Staking::bond(Origin::signed(1), 4, arbitrary_value, - RewardDestination::default()), "stash already bonded" - ); - // 1 = stashed => attempting to nominate should fail. - assert_noop!(Staking::nominate(Origin::signed(1), vec![1]), "not a controller"); - // 2 = controller => nominating should work. - assert_ok!(Staking::nominate(Origin::signed(2), vec![1])); - }); + ExtBuilder::default().build().execute_with(|| { + let arbitrary_value = 5; + // 2 = controller, 1 stashed => ok + assert_ok!( + Staking::bond(Origin::signed(1), 2, arbitrary_value, + RewardDestination::default()) + ); + // 4 = not used so far, 1 stashed => not allowed. + assert_noop!( + Staking::bond(Origin::signed(1), 4, arbitrary_value, + RewardDestination::default()), "stash already bonded" + ); + // 1 = stashed => attempting to nominate should fail. + assert_noop!(Staking::nominate(Origin::signed(1), vec![1]), "not a controller"); + // 2 = controller => nominating should work. + assert_ok!(Staking::nominate(Origin::signed(2), vec![1])); + }); } #[test] fn double_controlling_should_fail() { // should test (in the same order): // * an account already bonded as controller CANNOT be reused as the controller of another account. - with_externalities(&mut ExtBuilder::default() - .build(), - || { - let arbitrary_value = 5; - // 2 = controller, 1 stashed => ok - 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"); - }); + ExtBuilder::default().build().execute_with(|| { + let arbitrary_value = 5; + // 2 = controller, 1 stashed => ok + 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", + ); + }); } #[test] fn session_and_eras_work() { - with_externalities(&mut ExtBuilder::default() - .build(), - || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Staking::current_era(), 0); // Block 1: No change. @@ -702,7 +731,7 @@ fn session_and_eras_work() { #[test] fn forcing_new_era_works() { - with_externalities(&mut ExtBuilder::default().build(),|| { + ExtBuilder::default().build().execute_with(|| { // normal flow of session. assert_eq!(Staking::current_era(), 0); start_session(0); @@ -741,7 +770,7 @@ fn forcing_new_era_works() { #[test] fn cannot_transfer_staked_balance() { // Tests that a stash account cannot transfer funds - with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { + ExtBuilder::default().nominate(false).build().execute_with(|| { // Confirm account 11 is stashed assert_eq!(Staking::bonded(&11), Some(10)); // Confirm account 11 has some free balance @@ -749,7 +778,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); @@ -763,11 +795,7 @@ fn cannot_transfer_staked_balance_2() { // Tests that a stash account cannot transfer funds // Same test as above but with 20, and more accurate. // 21 has 2000 free balance but 1000 at stake - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .fair(true) - .build(), - || { + ExtBuilder::default().nominate(false).fair(true).build().execute_with(|| { // Confirm account 21 is stashed assert_eq!(Staking::bonded(&21), Some(20)); // Confirm account 21 has some free balance @@ -775,7 +803,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)); }); } @@ -783,7 +814,7 @@ fn cannot_transfer_staked_balance_2() { #[test] fn cannot_reserve_staked_balance() { // Checks that a bonded account cannot reserve balance from free balance - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { // Confirm account 11 is stashed assert_eq!(Staking::bonded(&11), Some(10)); // Confirm account 11 has some free balance @@ -803,7 +834,7 @@ fn cannot_reserve_staked_balance() { #[test] fn reward_destination_works() { // Rewards go to the correct destination as determined in Payee - with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { + ExtBuilder::default().nominate(false).build().execute_with(|| { // Check that account 11 is a validator assert!(Staking::current_elected().contains(&11)); // Check the balance of the validator account @@ -819,7 +850,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)]); @@ -841,7 +872,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)]); @@ -868,7 +899,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)]); @@ -895,9 +926,7 @@ fn validator_payment_prefs_work() { // Test that validator preferences are correctly honored // Note: unstake threshold is being directly tested in slashing tests. // This test will focus on validator payment. - with_externalities(&mut ExtBuilder::default() - .build(), - || { + ExtBuilder::default().build().execute_with(|| { // Initial config let validator_cut = 5; let stash_initial_balance = Balances::total_balance(&11); @@ -921,7 +950,7 @@ fn validator_payment_prefs_work() { }); // 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)]); @@ -930,11 +959,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(); @@ -947,8 +976,7 @@ fn bond_extra_works() { // Tests that extra `free_balance` in the stash can be added to stake // NOTE: this tests only verifies `StakingLedger` for correct updates // See `bond_extra_and_withdraw_unbonded_works` for more details and updates on `Exposure`. - with_externalities(&mut ExtBuilder::default().build(), - || { + ExtBuilder::default().build().execute_with(|| { // Check that account 10 is a validator assert!(>::exists(11)); // Check that account 10 is bonded to account 11 @@ -993,10 +1021,7 @@ fn bond_extra_and_withdraw_unbonded_works() { // * It can add extra funds to the bonded account. // * it can unbond a portion of its funds from the stash account. // * Once the unbonding period is done, it can actually take the funds out of the stash. - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { + ExtBuilder::default().nominate(false).build().execute_with(|| { // Set payee to controller. avoids confusion assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); @@ -1080,7 +1105,7 @@ fn bond_extra_and_withdraw_unbonded_works() { #[test] fn too_many_unbond_calls_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { // locked at era 0 until 3 for _ in 0..MAX_UNLOCKING_CHUNKS-1 { assert_ok!(Staking::unbond(Origin::signed(10), 1)); @@ -1109,11 +1134,7 @@ fn too_many_unbond_calls_should_not_work() { fn slot_stake_is_least_staked_validator_and_exposure_defines_maximum_punishment() { // Test that slot_stake is determined by the least staked validator // Test that slot_stake is the maximum punishment that can happen to a validator - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .fair(false) - .build(), - || { + ExtBuilder::default().nominate(false).fair(false).build().execute_with(|| { // Confirm validator count is 2 assert_eq!(Staking::validator_count(), 2); // Confirm account 10 and 20 are validators @@ -1135,7 +1156,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)]); @@ -1144,14 +1165,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); + assert_eq!(Staking::slot_stake(), 69 + total_payout_0 / 2); check_exposure_all(); check_nominator_all(); @@ -1162,10 +1183,7 @@ fn slot_stake_is_least_staked_validator_and_exposure_defines_maximum_punishment( fn on_free_balance_zero_stash_removes_validator() { // Tests that validator storage items are cleaned up when stash is empty // Tests that storage items are untouched when controller is empty - with_externalities(&mut ExtBuilder::default() - .existential_deposit(10) - .build(), - || { + ExtBuilder::default().existential_deposit(10).build().execute_with(|| { // Check the balance of the validator account assert_eq!(Balances::free_balance(&10), 256); // Check the balance of the stash account @@ -1215,10 +1233,7 @@ fn on_free_balance_zero_stash_removes_validator() { fn on_free_balance_zero_stash_removes_nominator() { // Tests that nominator storage items are cleaned up when stash is empty // Tests that storage items are untouched when controller is empty - with_externalities(&mut ExtBuilder::default() - .existential_deposit(10) - .build(), - || { + ExtBuilder::default().existential_deposit(10).build().execute_with(|| { // Make 10 a nominator assert_ok!(Staking::nominate(Origin::signed(10), vec![20])); // Check that account 10 is a nominator @@ -1267,196 +1282,11 @@ fn on_free_balance_zero_stash_removes_nominator() { }); } -#[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() { // Test that it should be possible to switch between roles (nominator, validator, idle) with minimal overhead. - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { + ExtBuilder::default().nominate(false).build().execute_with(|| { Timestamp::set_timestamp(1); // Initialize time. // Reset reward destination @@ -1522,11 +1352,7 @@ fn switching_roles() { #[test] fn wrong_vote_is_null() { - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .validator_pool(true) - .build(), - || { + ExtBuilder::default().nominate(false).validator_pool(true).build().execute_with(|| { assert_eq_uvec!(validator_controllers(), vec![40, 30]); // put some money in account that we'll use. @@ -1550,202 +1376,181 @@ fn wrong_vote_is_null() { fn bond_with_no_staked_value() { // Behavior when someone bonds with no staked value. // Particularly when she votes and the candidate is elected. - with_externalities(&mut ExtBuilder::default() - .validator_count(3) - .existential_deposit(5) - .nominate(false) - .minimum_validator_count(1) - .build(), || { - // 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" - ); - // bonded with absolute minimum value possible. - assert_ok!(Staking::bond(Origin::signed(1), 2, 5, RewardDestination::Controller)); - assert_eq!(Balances::locks(&1)[0].amount, 5); + ExtBuilder::default() + .validator_count(3) + .existential_deposit(5) + .nominate(false) + .minimum_validator_count(1) + .build() + .execute_with(|| { + // 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", + ); + // bonded with absolute minimum value possible. + assert_ok!(Staking::bond(Origin::signed(1), 2, 5, RewardDestination::Controller)); + assert_eq!(Balances::locks(&1)[0].amount, 5); - // unbonding even 1 will cause all to be unbonded. - assert_ok!(Staking::unbond(Origin::signed(2), 1)); - assert_eq!( - Staking::ledger(2), - Some(StakingLedger { - stash: 1, - active: 0, - total: 5, - unlocking: vec![UnlockChunk {value: 5, era: 3}] - }) - ); + // unbonding even 1 will cause all to be unbonded. + assert_ok!(Staking::unbond(Origin::signed(2), 1)); + assert_eq!( + Staking::ledger(2), + Some(StakingLedger { + stash: 1, + active: 0, + total: 5, + unlocking: vec![UnlockChunk {value: 5, era: 3}] + }) + ); - start_era(1); - start_era(2); + start_era(1); + start_era(2); - // not yet removed. - assert_ok!(Staking::withdraw_unbonded(Origin::signed(2))); - assert!(Staking::ledger(2).is_some()); - assert_eq!(Balances::locks(&1)[0].amount, 5); + // not yet removed. + assert_ok!(Staking::withdraw_unbonded(Origin::signed(2))); + assert!(Staking::ledger(2).is_some()); + assert_eq!(Balances::locks(&1)[0].amount, 5); - start_era(3); + start_era(3); - // poof. Account 1 is removed from the staking system. - assert_ok!(Staking::withdraw_unbonded(Origin::signed(2))); - assert!(Staking::ledger(2).is_none()); - assert_eq!(Balances::locks(&1).len(), 0); - }); + // poof. Account 1 is removed from the staking system. + assert_ok!(Staking::withdraw_unbonded(Origin::signed(2))); + assert!(Staking::ledger(2).is_none()); + assert_eq!(Balances::locks(&1).len(), 0); + }); } #[test] fn bond_with_little_staked_value_bounded_by_slot_stake() { // Behavior when someone bonds with little staked value. // Particularly when she votes and the candidate is elected. - with_externalities(&mut ExtBuilder::default() + ExtBuilder::default() .validator_count(3) .nominate(false) .minimum_validator_count(1) - .build(), - || { - - // setup - assert_ok!(Staking::chill(Origin::signed(30))); - assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); - let init_balance_2 = Balances::free_balance(&2); - let init_balance_10 = Balances::free_balance(&10); - - // Stingy validator. - 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); - assert!(total_payout_0 > 100); // Test is meaningfull if reward something - reward_all_elected(); - start_era(1); - - // 2 is elected. - // and fucks up the slot stake. - assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]); - assert_eq!(Staking::slot_stake(), 1); - - // Old ones are rewarded. - 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); - assert!(total_payout_1 > 100); // Test is meaningfull if reward something - reward_all_elected(); - start_era(2); - - 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); - check_exposure_all(); - check_nominator_all(); - }); + .build() + .execute_with(|| { + // setup + assert_ok!(Staking::chill(Origin::signed(30))); + assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); + let init_balance_2 = Balances::free_balance(&2); + let init_balance_10 = Balances::free_balance(&10); + + // Stingy validator. + 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(3000); + assert!(total_payout_0 > 100); // Test is meaningfull if reward something + reward_all_elected(); + start_era(1); + + // 2 is elected. + // and fucks up the slot stake. + assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]); + assert_eq!(Staking::slot_stake(), 1); + + // Old ones are rewarded. + 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(3000); + assert!(total_payout_1 > 100); // Test is meaningfull if reward something + reward_all_elected(); + start_era(2); + + 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, + ); + check_exposure_all(); + check_nominator_all(); + }); } #[cfg(feature = "equalize")] #[test] fn phragmen_linear_worse_case_equalize() { - with_externalities(&mut ExtBuilder::default() + ExtBuilder::default() .nominate(false) .validator_pool(true) .fair(true) - .build(), - || { - - bond_validator(50, 1000); - bond_validator(60, 1000); - bond_validator(70, 1000); - - bond_nominator(2, 2000, vec![11]); - bond_nominator(4, 1000, vec![11, 21]); - bond_nominator(6, 1000, vec![21, 31]); - bond_nominator(8, 1000, vec![31, 41]); - bond_nominator(110, 1000, vec![41, 51]); - bond_nominator(120, 1000, vec![51, 61]); - bond_nominator(130, 1000, vec![61, 71]); - - for i in &[10, 20, 30, 40, 50, 60, 70] { - assert_ok!(Staking::set_payee(Origin::signed(*i), RewardDestination::Controller)); - } - - assert_eq_uvec!(validator_controllers(), vec![40, 30]); - assert_ok!(Staking::set_validator_count(Origin::ROOT, 7)); - - start_era(1); - - 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); - - check_exposure_all(); - check_nominator_all(); - }) + .build() + .execute_with(|| { + bond_validator(50, 1000); + bond_validator(60, 1000); + bond_validator(70, 1000); + + bond_nominator(2, 2000, vec![11]); + bond_nominator(4, 1000, vec![11, 21]); + bond_nominator(6, 1000, vec![21, 31]); + bond_nominator(8, 1000, vec![31, 41]); + bond_nominator(110, 1000, vec![41, 51]); + bond_nominator(120, 1000, vec![51, 61]); + bond_nominator(130, 1000, vec![61, 71]); + + for i in &[10, 20, 30, 40, 50, 60, 70] { + assert_ok!(Staking::set_payee(Origin::signed(*i), RewardDestination::Controller)); + } + + assert_eq_uvec!(validator_controllers(), vec![40, 30]); + assert_ok!(Staking::set_validator_count(Origin::ROOT, 7)); + + start_era(1); + + assert_eq_uvec!(validator_controllers(), vec![10, 60, 40, 20, 50, 30, 70]); + + 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(); + }) } #[test] -fn phragmen_chooses_correct_number_of_validators() { - with_externalities(&mut ExtBuilder::default() +fn new_era_elects_correct_number_of_validators() { + ExtBuilder::default() .nominate(true) .validator_pool(true) .fair(true) .validator_count(1) - .build(), - || { - assert_eq!(Staking::validator_count(), 1); - assert_eq!(validator_controllers().len(), 1); - - System::set_block_number(1); - Session::on_initialize(System::block_number()); - - assert_eq!(validator_controllers().len(), 1); - check_exposure_all(); - check_nominator_all(); - }) -} - - -#[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(); - }) + .build() + .execute_with(|| { + assert_eq!(Staking::validator_count(), 1); + assert_eq!(validator_controllers().len(), 1); + + System::set_block_number(1); + Session::on_initialize(System::block_number()); + + assert_eq!(validator_controllers().len(), 1); + check_exposure_all(); + check_nominator_all(); + }) } #[test] fn phragmen_should_not_overflow_validators() { - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { + ExtBuilder::default().nominate(false).build().execute_with(|| { let _ = Staking::chill(Origin::signed(10)); let _ = Staking::chill(Origin::signed(20)); 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); @@ -1760,15 +1565,12 @@ fn phragmen_should_not_overflow_validators() { #[test] fn phragmen_should_not_overflow_nominators() { - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { + ExtBuilder::default().nominate(false).build().execute_with(|| { 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]); @@ -1785,10 +1587,7 @@ fn phragmen_should_not_overflow_nominators() { #[test] fn phragmen_should_not_overflow_ultimate() { - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { + ExtBuilder::default().nominate(false).build().execute_with(|| { bond_validator(2, u64::max_value()); bond_validator(4, u64::max_value()); @@ -1805,89 +1604,9 @@ 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() - .build(), - || { + ExtBuilder::default().build().execute_with(|| { let stake = u32::max_value() as u64 * 2; let reward_slash = u32::max_value() as u64 * 2; @@ -1918,9 +1637,7 @@ fn reward_validator_slashing_validator_doesnt_overflow() { #[test] fn reward_from_authorship_event_handler_works() { - with_externalities(&mut ExtBuilder::default() - .build(), - || { + ExtBuilder::default().build().execute_with(|| { use authorship::EventHandler; assert_eq!(>::author(), 11); @@ -1937,17 +1654,15 @@ 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); }) } #[test] fn add_reward_points_fns_works() { - with_externalities(&mut ExtBuilder::default() - .build(), - || { + ExtBuilder::default().build().execute_with(|| { let validators = >::current_elected(); // Not mandatory but must be coherent with rewards assert_eq!(validators, vec![21, 11]); @@ -1966,14 +1681,14 @@ 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); }) } #[test] fn unbonded_balance_is_not_slashable() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { // total amount staked is slashable. assert_eq!(Staking::slashable_balance_of(&11), 1000); @@ -1988,7 +1703,7 @@ fn unbonded_balance_is_not_slashable() { 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(), || { + ExtBuilder::default().build().execute_with(|| { start_era(1); assert_eq!(Staking::current_era_start_session_index(), SessionsPerEra::get()); @@ -2008,7 +1723,7 @@ fn era_is_always_same_length() { #[test] fn offence_forces_new_era() { - with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { Staking::on_offence( &[OffenceDetails { offender: ( @@ -2028,7 +1743,7 @@ fn offence_forces_new_era() { 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(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Staking::stakers(&11).own, 1000); // Handle an offence with a historical exposure. @@ -2056,7 +1771,7 @@ fn slashing_performed_according_exposure() { 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(), || { + ExtBuilder::default().build().execute_with(|| { // The reporters' reward is calculated from the total exposure. #[cfg(feature = "equalize")] let initial_balance = 1250; @@ -2086,44 +1801,41 @@ fn reporters_receive_their_slice() { #[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)], - ); + ExtBuilder::default().invulnerables(vec![11]).build().execute_with(|| { + #[cfg(feature = "equalize")] + let initial_balance = 1250; + #[cfg(not(feature = "equalize"))] + let initial_balance = 1375; - // 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)); - }, - ); + 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(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Balances::free_balance(&11), 1000); Staking::on_offence( 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..7801384abcc2fe7b3f3e7e4fb2102e3d6a41221e 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,12 +192,14 @@ decl_event!( Sudid(bool), /// The sudoer just switched identity; the old key is supplied. KeyChanged(AccountId), + /// A sudo just took place. + SudoAsDone(bool), } ); decl_storage! { trait Store for Module as Sudo { /// The `AccountId` of the sudo key. - Key get(key) config(): T::AccountId; + Key get(fn key) config(): T::AccountId; } } diff --git a/srml/support/Cargo.toml b/srml/support/Cargo.toml index 2befc11b19538def8b23f695cdea80925c50ae0e..2b8c4cb9f98b80a17ab9b13d4c1ccfe6c315501b 100644 --- a/srml/support/Cargo.toml +++ b/srml/support/Cargo.toml @@ -5,18 +5,20 @@ 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"] } +log = "0.4" +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 +30,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 674b90458f104977c1cf27b61746f4b93f3628a4..792f739f1c35761c6bc370fd0cfb112f5e403a3a 100644 --- a/srml/support/procedural/src/lib.rs +++ b/srml/support/procedural/src/lib.rs @@ -33,7 +33,7 @@ use proc_macro::TokenStream; /// ```nocompile /// decl_storage! { /// trait Store for Module as Example { -/// Foo get(foo) config(): u32=12; +/// Foo get(fn foo) config(): u32=12; /// Bar: map u32 => u32; /// pub Zed build(|config| vec![(0, 0)]): linked_map u32 => u32; /// } @@ -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. /// -/// /!\ Be careful with each key pair in the double map that is inserted in the trie. -/// The final key is calculated as follows: +/// The generator is implemented with: +/// * `prefix`: `$module_prefix ++ " " ++ $storage_name` +/// * `head_key`: `"head of " ++ $module_prefix ++ " " ++ $storage_name` +/// * `Hasher`: $hash /// -/// ```nocompile -/// $hash(module_name ++ " " ++ storage_name ++ encoding(first_key)) ++ $hash2(encoding(second_key)) -/// ``` +/// * 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). +/// +/// `$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. @@ -93,11 +120,11 @@ use proc_macro::TokenStream; /// /// Basic storage can be extended as such: /// -/// `#vis #name get(#getter) config(#field_name) build(#closure): #type = #default;` +/// `#vis #name get(fn #getter) config(#field_name) build(#closure): #type = #default;` /// /// * `#vis`: Set the visibility of the structure. `pub` or nothing. /// * `#name`: Name of the storage item, used as a prefix in storage. -/// * [optional] `get(#getter)`: Implements the function #getter to `Module`. +/// * [optional] `get(fn #getter)`: Implements the function #getter to `Module`. /// * [optional] `config(#field_name)`: `field_name` is optional if get is set. /// Will include the item in `GenesisConfig`. /// * [optional] `build(#closure)`: Closure called with storage overlays. @@ -126,7 +153,7 @@ use proc_macro::TokenStream; /// config(genesis_field): GenesisFieldType; /// config(genesis_field2): GenesisFieldType; /// ... -/// build(|_: &mut StorageOverlay, _: &mut ChildrenStorageOverlay, _: &GenesisConfig| { +/// build(|_: &Self| { /// // Modification of storage /// }) /// } @@ -186,5 +213,5 @@ use proc_macro::TokenStream; /// #[proc_macro] pub fn decl_storage(input: TokenStream) -> TokenStream { - storage::transformation::decl_storage_impl(input) + storage::decl_storage_impl(input) } diff --git a/srml/support/procedural/src/storage/genesis_config/builder_def.rs b/srml/support/procedural/src/storage/genesis_config/builder_def.rs new file mode 100644 index 0000000000000000000000000000000000000000..fc425e4a6d53261fb5f9868127be0ce90ddff5e1 --- /dev/null +++ b/srml/support/procedural/src/storage/genesis_config/builder_def.rs @@ -0,0 +1,111 @@ +// 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 . + +//! Builder logic definition used to build genesis storage. + +use srml_support_procedural_tools::syn_ext as ext; +use proc_macro2::TokenStream; +use syn::spanned::Spanned; +use quote::{quote, quote_spanned}; +use super::super::{DeclStorageDefExt, StorageLineTypeDef}; + +/// Definition of builder blocks, each block insert some value in the storage. +/// They must be called inside externalities, and with `self` being the genesis config. +pub struct BuilderDef { + /// Contains: + /// * build block for storage with build attribute. + /// * build block for storage with config attribute and no build attribute. + /// * build block for extra genesis build expression. + pub blocks: Vec, + /// The build blocks requires generic traits. + pub is_generic: bool, +} + +impl BuilderDef { + pub fn from_def(scrate: &TokenStream, def: &DeclStorageDefExt) -> Self { + let mut blocks = Vec::new(); + let mut is_generic = false; + + for line in def.storage_lines.iter() { + let storage_struct = &line.storage_struct; + let storage_trait = &line.storage_trait; + let value_type = &line.value_type; + + // Contains the data to inset at genesis either from build or config. + let mut data = None; + + if let Some(builder) = &line.build { + is_generic |= ext::expr_contains_ident(&builder, &def.module_runtime_generic); + is_generic |= line.is_generic; + + data = Some(quote_spanned!(builder.span() => &(#builder)(self))); + } else if let Some(config) = &line.config { + is_generic |= line.is_generic; + + data = Some(quote!(&self.#config;)); + }; + + if let Some(data) = data { + blocks.push(match &line.storage_type { + StorageLineTypeDef::Simple(_) => { + quote!{{ + let v: &#value_type = #data; + <#storage_struct as #scrate::#storage_trait>::put::<&#value_type>(v); + }} + }, + StorageLineTypeDef::Map(map) | StorageLineTypeDef::LinkedMap(map) => { + let key = &map.key; + quote!{{ + let data: &#scrate::rstd::vec::Vec<(#key, #value_type)> = #data; + data.iter().for_each(|(k, v)| { + <#storage_struct as #scrate::#storage_trait>::insert::< + &#key, &#value_type + >(k, v); + }); + }} + }, + StorageLineTypeDef::DoubleMap(map) => { + let key1 = &map.key1; + let key2 = &map.key2; + quote!{{ + let data: &#scrate::rstd::vec::Vec<(#key1, #key2, #value_type)> = #data; + data.iter().for_each(|(k1, k2, v)| { + <#storage_struct as #scrate::#storage_trait>::insert::< + &#key1, &#key2, &#value_type + >(k1, k2, v); + }); + }} + }, + }); + } + } + + if let Some(builder) = def.extra_genesis_build.as_ref() { + is_generic |= ext::expr_contains_ident(&builder, &def.module_runtime_generic); + + blocks.push(quote_spanned! { builder.span() => + let extra_genesis_builder: fn(&Self) = #builder; + extra_genesis_builder(self); + }); + } + + + Self { + blocks, + is_generic, + } + } +} diff --git a/srml/support/procedural/src/storage/genesis_config/genesis_config_def.rs b/srml/support/procedural/src/storage/genesis_config/genesis_config_def.rs new file mode 100644 index 0000000000000000000000000000000000000000..f9d2f8abe8055a8128ba1ef222f5e5342ba1b138 --- /dev/null +++ b/srml/support/procedural/src/storage/genesis_config/genesis_config_def.rs @@ -0,0 +1,144 @@ +// 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 . + +//! Genesis config defintion. + +use srml_support_procedural_tools::syn_ext as ext; +use proc_macro2::TokenStream; +use syn::parse_quote; +use quote::quote; +use super::super::{DeclStorageDefExt, StorageLineTypeDef}; + +pub struct GenesisConfigFieldDef { + pub doc: Vec, + pub name: syn::Ident, + pub typ: syn::Type, + pub default: TokenStream, +} + +pub struct GenesisConfigDef { + pub is_generic: bool, + pub fields: Vec, + /// For example: `, I: Instance=DefaultInstance>`. + pub genesis_struct_decl: TokenStream, + /// For example: ``. + pub genesis_struct: TokenStream, + /// For example: `, I: Instance>`. + pub genesis_impl: TokenStream, + /// The where clause to use to constrain generics if genesis config is generic. + pub genesis_where_clause: Option, +} + +impl GenesisConfigDef { + pub fn from_def(def: &DeclStorageDefExt) -> Self { + let fields = Self::get_genesis_config_field_defs(def); + + let is_generic = fields.iter() + .any(|field| ext::type_contains_ident(&field.typ, &def.module_runtime_generic)); + + let ( + genesis_struct_decl, + genesis_impl, + genesis_struct, + genesis_where_clause + ) = if is_generic { + let runtime_generic = &def.module_runtime_generic; + let runtime_trait = &def.module_runtime_trait; + let optional_instance = &def.optional_instance; + let optional_instance_bound = &def.optional_instance_bound; + let optional_instance_bound_optional_default = &def.optional_instance_bound_optional_default; + let where_clause = &def.where_clause; + ( + quote!(<#runtime_generic: #runtime_trait, #optional_instance_bound_optional_default>), + quote!(<#runtime_generic: #runtime_trait, #optional_instance_bound>), + quote!(<#runtime_generic, #optional_instance>), + where_clause.clone(), + ) + } else { + (quote!(), quote!(), quote!(), None) + }; + + Self { + is_generic, + fields, + genesis_struct_decl, + genesis_struct, + genesis_impl, + genesis_where_clause, + } + } + + fn get_genesis_config_field_defs(def: &DeclStorageDefExt) -> Vec { + let mut config_field_defs = Vec::new(); + + for (config_field, line) in def.storage_lines.iter() + .filter_map(|line| line.config.as_ref().map(|config_field| (config_field.clone(), line))) + { + let value_type = &line.value_type; + + let typ = match &line.storage_type { + StorageLineTypeDef::Simple(_) => (*value_type).clone(), + StorageLineTypeDef::Map(map) | StorageLineTypeDef::LinkedMap(map) => { + let key = &map.key; + parse_quote!( Vec<(#key, #value_type)> ) + }, + StorageLineTypeDef::DoubleMap(map) => { + let key1 = &map.key1; + let key2 = &map.key2; + + parse_quote!( Vec<(#key1, #key2, #value_type)> ) + }, + }; + + let default = line.default_value.as_ref() + .map(|d| { + if line.is_option { + quote!( #d.unwrap_or_default() ) + } else { + quote!( #d ) + } + }) + .unwrap_or_else(|| quote!( Default::default() )); + + config_field_defs.push(GenesisConfigFieldDef { + doc: line.doc_attrs.clone(), + name: config_field, + typ, + default, + }); + } + + for line in &def.extra_genesis_config_lines { + let doc = line.attrs.iter() + .filter_map(|a| a.parse_meta().ok()) + .filter(|m| m.name() == "doc") + .collect(); + + let default = line.default.as_ref().map(|e| quote!( #e )) + .unwrap_or_else(|| quote!( Default::default() )); + + + config_field_defs.push(GenesisConfigFieldDef { + doc, + name: line.name.clone(), + typ: line.typ.clone(), + default, + }); + } + + config_field_defs + } +} diff --git a/srml/support/procedural/src/storage/genesis_config/mod.rs b/srml/support/procedural/src/storage/genesis_config/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..2d4d4af3861ed56c186f15de4352b0aa0a9ca372 --- /dev/null +++ b/srml/support/procedural/src/storage/genesis_config/mod.rs @@ -0,0 +1,203 @@ +// 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 . + +//! Declaration of genesis config structure and implementation of build storage trait and +//! functions. + +use proc_macro2::{TokenStream, Span}; +use quote::quote; +use super::{DeclStorageDefExt, instance_trait::DEFAULT_INSTANTIABLE_TRAIT_NAME}; +use genesis_config_def::GenesisConfigDef; +use builder_def::BuilderDef; + +mod genesis_config_def; +mod builder_def; + +const DEFAULT_INSTANCE_NAME: &str = "__GeneratedInstance"; + +fn decl_genesis_config_and_impl_default( + scrate: &TokenStream, + genesis_config: &GenesisConfigDef, +) -> TokenStream { + let config_fields = genesis_config.fields.iter().map(|field| { + let (name, typ, doc) = (&field.name, &field.typ, &field.doc); + quote!( #( #[ #doc] )* pub #name: #typ, ) + }); + + let config_field_defaults = genesis_config.fields.iter().map(|field| { + let (name, default, doc) = (&field.name, &field.default, &field.doc); + quote!( #( #[ #doc] )* #name: #default, ) + }); + + let serde_bug_bound = if !genesis_config.fields.is_empty() { + let mut b_ser = String::new(); + let mut b_dser = String::new(); + + for typ in genesis_config.fields.iter().map(|c| &c.typ) { + let typ = quote!( #typ ); + b_ser.push_str(&format!("{} : {}::serde::Serialize, ", typ, scrate)); + b_dser.push_str(&format!("{} : {}::serde::de::DeserializeOwned, ", typ, scrate)); + } + + quote! { + #[serde(bound(serialize = #b_ser))] + #[serde(bound(deserialize = #b_dser))] + } + } else { + quote!() + }; + + let genesis_struct_decl = &genesis_config.genesis_struct_decl; + let genesis_struct = &genesis_config.genesis_struct; + let genesis_impl = &genesis_config.genesis_impl; + let genesis_where_clause = &genesis_config.genesis_where_clause; + + quote!( + #[derive(#scrate::Serialize, #scrate::Deserialize)] + #[cfg(feature = "std")] + #[serde(rename_all = "camelCase")] + #[serde(deny_unknown_fields)] + #serde_bug_bound + pub struct GenesisConfig#genesis_struct_decl #genesis_where_clause { + #( #config_fields )* + } + + #[cfg(feature = "std")] + impl#genesis_impl Default for GenesisConfig#genesis_struct #genesis_where_clause { + fn default() -> Self { + GenesisConfig { + #( #config_field_defaults )* + } + } + } + ) +} + +fn impl_build_storage( + scrate: &TokenStream, + def: &DeclStorageDefExt, + genesis_config: &GenesisConfigDef, + builders: &BuilderDef, +) -> TokenStream { + let runtime_generic = &def.module_runtime_generic; + let runtime_trait = &def.module_runtime_trait; + let optional_instance = &def.optional_instance; + let optional_instance_bound = &def.optional_instance_bound; + let where_clause = &def.where_clause; + + let inherent_instance = def.optional_instance.clone().unwrap_or_else(|| { + let name = syn::Ident::new(DEFAULT_INSTANCE_NAME, Span::call_site()); + quote!( #name ) + }); + let inherent_instance_bound = def.optional_instance_bound.clone().unwrap_or_else(|| { + let bound = syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site()); + quote!( #inherent_instance: #bound ) + }); + + let build_storage_impl = quote!( + <#runtime_generic: #runtime_trait, #inherent_instance_bound> + ); + + let genesis_struct = &genesis_config.genesis_struct; + let genesis_impl = &genesis_config.genesis_impl; + let genesis_where_clause = &genesis_config.genesis_where_clause; + + let ( + fn_generic, + fn_traitinstance, + fn_where_clause + ) = if !genesis_config.is_generic && builders.is_generic { + ( + quote!( <#runtime_generic: #runtime_trait, #optional_instance_bound> ), + quote!( #runtime_generic, #optional_instance ), + Some(&def.where_clause), + ) + } else { + (quote!(), quote!(), None) + }; + + let builder_blocks = &builders.blocks; + + let build_storage_impl_trait = quote!( + #scrate::sr_primitives::BuildModuleGenesisStorage<#runtime_generic, #inherent_instance> + ); + + quote!{ + #[cfg(feature = "std")] + impl#genesis_impl GenesisConfig#genesis_struct #genesis_where_clause { + pub fn build_storage #fn_generic (&self) -> std::result::Result< + ( + #scrate::sr_primitives::StorageOverlay, + #scrate::sr_primitives::ChildrenStorageOverlay, + ), + String + > #fn_where_clause { + let mut storage = (Default::default(), Default::default()); + self.assimilate_storage::<#fn_traitinstance>(&mut storage)?; + Ok(storage) + } + + /// Assimilate the storage for this module into pre-existing overlays. + pub fn assimilate_storage #fn_generic ( + &self, + tuple_storage: &mut ( + #scrate::sr_primitives::StorageOverlay, + #scrate::sr_primitives::ChildrenStorageOverlay, + ), + ) -> std::result::Result<(), String> #fn_where_clause { + #scrate::with_storage(tuple_storage, || { + #( #builder_blocks )* + Ok(()) + }) + } + } + + #[cfg(feature = "std")] + impl#build_storage_impl #build_storage_impl_trait for GenesisConfig#genesis_struct + #where_clause + { + fn build_module_genesis_storage( + &self, + storage: &mut ( + #scrate::sr_primitives::StorageOverlay, + #scrate::sr_primitives::ChildrenStorageOverlay, + ), + ) -> std::result::Result<(), String> { + self.assimilate_storage::<#fn_traitinstance> (storage) + } + } + } +} + +pub fn genesis_config_and_build_storage( + scrate: &TokenStream, + def: &DeclStorageDefExt, +) -> TokenStream { + let builders = BuilderDef::from_def(scrate, def); + if !builders.blocks.is_empty() { + let genesis_config = &GenesisConfigDef::from_def(def); + let decl_genesis_config_and_impl_default = + decl_genesis_config_and_impl_default(scrate, genesis_config); + let impl_build_storage = impl_build_storage(scrate, def, genesis_config, &builders); + + quote!{ + #decl_genesis_config_and_impl_default + #impl_build_storage + } + } else { + quote!() + } +} diff --git a/srml/support/procedural/src/storage/getters.rs b/srml/support/procedural/src/storage/getters.rs new file mode 100644 index 0000000000000000000000000000000000000000..f30e489eb58bc7907bcce3fed2bae031ae12e893 --- /dev/null +++ b/srml/support/procedural/src/storage/getters.rs @@ -0,0 +1,80 @@ +// 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 . + +//! Implementation of getters on module structure. + +use proc_macro2::TokenStream; +use quote::quote; +use super::{DeclStorageDefExt, StorageLineTypeDef}; + +pub fn impl_getters(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStream { + let mut getters = TokenStream::new(); + + for (get_fn, line) in def.storage_lines.iter() + .filter_map(|line| line.getter.as_ref().map(|get_fn| (get_fn, line))) + { + let attrs = &line.doc_attrs; + + let storage_struct = &line.storage_struct; + let storage_trait = &line.storage_trait; + + let getter = match &line.storage_type { + StorageLineTypeDef::Simple(value) => { + quote!{ + #( #[ #attrs ] )* + pub fn #get_fn() -> #value { + <#storage_struct as #scrate::#storage_trait>::get() + } + } + }, + StorageLineTypeDef::Map(map) | StorageLineTypeDef::LinkedMap(map) => { + let key = &map.key; + let value = &map.value; + quote!{ + #( #[ #attrs ] )* + pub fn #get_fn>(key: K) -> #value { + <#storage_struct as #scrate::#storage_trait>::get(key) + } + } + }, + StorageLineTypeDef::DoubleMap(map) => { + let key1 = &map.key1; + let key2 = &map.key2; + let value = &map.value; + quote!{ + pub fn #get_fn(k1: KArg1, k2: KArg2) -> #value + where + KArg1: #scrate::codec::EncodeLike<#key1>, + KArg2: #scrate::codec::EncodeLike<#key2>, + { + <#storage_struct as #scrate::#storage_trait>::get(k1, k2) + } + } + }, + }; + getters.extend(getter); + } + + let module_struct = &def.module_struct; + let module_impl = &def.module_impl; + let where_clause = &def.where_clause; + + quote!( + impl#module_impl #module_struct #where_clause { + #getters + } + ) +} diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs deleted file mode 100644 index dd936636735141231ee6352e14c4032a00ad35df..0000000000000000000000000000000000000000 --- a/srml/support/procedural/src/storage/impls.rs +++ /dev/null @@ -1,873 +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::storage::transformation::{DeclStorageTypeInfos, InstanceOpts}; - -use srml_support_procedural_tools::syn_ext as ext; -use proc_macro2::TokenStream as TokenStream2; -use syn::Ident; -use quote::quote; - -pub fn option_unwrap(is_option: bool) -> TokenStream2 { - if !is_option { - // raw type case - quote!( unwrap_or_else ) - } else { - // Option<> type case - quote!( or_else ) - } -} - -// prefix for consts in trait Instance -pub(crate) const PREFIX_FOR: &str = "PREFIX_FOR_"; -pub(crate) const HEAD_KEY_FOR: &str = "HEAD_KEY_FOR_"; - -pub(crate) struct Impls<'a, I: Iterator> { - pub scrate: &'a TokenStream2, - pub visibility: &'a syn::Visibility, - pub traitinstance: &'a syn::Ident, - pub traittype: &'a syn::TypeParamBound, - pub instance_opts: &'a InstanceOpts, - pub type_infos: DeclStorageTypeInfos<'a>, - pub fielddefault: TokenStream2, - pub prefix: String, - pub cratename: &'a syn::Ident, - pub name: &'a syn::Ident, - pub attrs: I, - pub where_clause: &'a Option, -} - -impl<'a, I: Iterator> Impls<'a, I> { - pub fn simple_value(self) -> TokenStream2 { - let Self { - scrate, - visibility, - traitinstance, - traittype, - instance_opts, - type_infos, - fielddefault, - prefix, - name, - attrs, - where_clause, - .. - } = 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 InstanceOpts { - equal_default_instance, - bound_instantiable, - instance, - .. - } = instance_opts; - - let final_prefix = if let Some(instance) = instance { - let const_name = Ident::new(&format!("{}{}", PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site()); - quote!{ #instance::#const_name.as_bytes() } - } else { - quote!{ #prefix.as_bytes() } - }; - - let (struct_trait, impl_trait, trait_and_instance, where_clause) = if ext::type_contains_ident( - value_type, traitinstance - ) { - ( - 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), - None, - ) - }; - - // generator for value - quote! { - #( #[ #attrs ] )* - #visibility struct #name<#struct_trait>( - #scrate::rstd::marker::PhantomData<(#trait_and_instance)> - ) #where_clause; - - impl<#impl_trait> #scrate::storage::hashed::generator::StorageValue<#typ> - for #name<#trait_and_instance> #where_clause - { - type Query = #value_type; - - /// Get the storage key. - fn 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) - } - - /// 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 - } - } - } - } - - pub fn map(self, hasher: TokenStream2, kty: &syn::Type) -> TokenStream2 { - let Self { - scrate, - visibility, - traitinstance, - traittype, - instance_opts, - type_infos, - fielddefault, - prefix, - name, - attrs, - where_clause, - .. - } = 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 InstanceOpts { - equal_default_instance, - bound_instantiable, - instance, - .. - } = instance_opts; - - let final_prefix = if let Some(instance) = instance { - let const_name = syn::Ident::new( - &format!("{}{}", PREFIX_FOR, name.to_string()), - proc_macro2::Span::call_site(), - ); - quote! { #instance::#const_name.as_bytes() } - } else { - quote! { #prefix.as_bytes() } - }; - - let trait_required = ext::type_contains_ident(value_type, traitinstance) - || ext::type_contains_ident(kty, traitinstance); - - 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), - None, - ) - }; - - // generator for map - quote!{ - #( #[ #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> - 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) - } - - /// 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 - } - } - - impl<#impl_trait> #scrate::storage::hashed::generator::AppendableStorageMap<#kty, #typ> - for #name<#trait_and_instance> #where_clause - {} - } - } - - pub fn linked_map(self, hasher: TokenStream2, kty: &syn::Type) -> TokenStream2 { - let Self { - scrate, - visibility, - traitinstance, - traittype, - instance_opts, - type_infos, - fielddefault, - prefix, - name, - attrs, - where_clause, - .. - } = self; - - let InstanceOpts { - equal_default_instance, - bound_instantiable, - instance, - .. - } = instance_opts; - - let final_prefix = if let Some(instance) = instance { - let const_name = Ident::new( - &format!("{}{}", PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site() - ); - quote!{ #instance::#const_name.as_bytes() } - } else { - quote!{ #prefix.as_bytes() } - }; - - // make sure to use different prefix for head and elements. - let final_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 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 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 { - ( - quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance), - quote!(#traitinstance: #traittype, #instance #bound_instantiable), - quote!(#traitinstance, #instance), - ) - } 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 - - impl<#impl_trait> #scrate::storage::hashed::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(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 - } - - /// 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) - } - - /// 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(), - }) - } - } - } - } - - pub fn double_map( - self, - hasher: TokenStream2, - k1ty: &syn::Type, - k2ty: &syn::Type, - k2_hasher: TokenStream2, - ) -> TokenStream2 { - let Self { - scrate, - visibility, - traitinstance, - traittype, - type_infos, - fielddefault, - prefix, - name, - attrs, - instance_opts, - where_clause, - .. - } = 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 InstanceOpts { - equal_default_instance, - bound_instantiable, - instance, - .. - } = instance_opts; - - let final_prefix = if let Some(instance) = instance { - let const_name = Ident::new( - &format!("{}{}", PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site() - ); - quote!{ #instance::#const_name.as_bytes() } - } else { - quote!{ #prefix.as_bytes() } - }; - - let (struct_trait, impl_trait, trait_and_instance, where_clause) = if ext::type_contains_ident( - value_type, traitinstance - ) || ext::type_contains_ident(k1ty, traitinstance) || ext::type_contains_ident(k2ty, traitinstance) - { - ( - 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), - None, - ) - }; - - // generator for double map - quote!{ - #( #[ #attrs ] )* - #visibility struct #name<#struct_trait> - (#scrate::rstd::marker::PhantomData<(#trait_and_instance)>); - - impl<#impl_trait> #scrate::storage::unhashed::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; - - let mut key = #as_double_map::prefix().to_vec(); - #scrate::codec::Encode::encode_to(k1, &mut key); - #scrate::#hasher::hash(&key[..]).to_vec() - } - - fn 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 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 - } - } - } - } -} diff --git a/srml/support/procedural/src/storage/instance_trait.rs b/srml/support/procedural/src/storage/instance_trait.rs new file mode 100644 index 0000000000000000000000000000000000000000..1a7add89a4b80024f35f512176db7eba61655fd2 --- /dev/null +++ b/srml/support/procedural/src/storage/instance_trait.rs @@ -0,0 +1,200 @@ +// 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 . + +//! Implementation of the trait instance and the instance structures implementing it. +//! (For not instantiable traits there is still the inherent instance implemented). + +use proc_macro2::{TokenStream, Span}; +use quote::quote; +use super::{DeclStorageDefExt, StorageLineTypeDef}; + +const NUMBER_OF_INSTANCE: usize = 16; +const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance"; +pub(crate) const DEFAULT_INSTANTIABLE_TRAIT_NAME: &str = "__GeneratedInstantiable"; + +// prefix for consts in trait Instance +pub(crate) const PREFIX_FOR: &str = "PREFIX_FOR_"; +pub(crate) const HEAD_KEY_FOR: &str = "HEAD_KEY_FOR_"; + +// Used to generate the const: +// `const $name: &'static str = $value_prefix ++ instance_prefix ++ $value_suffix` +struct InstanceConstDef { + name: syn::Ident, + value_prefix: String, + value_suffix: String, +} + +// Used to generate an instance implementation. +struct InstanceDef { + prefix: String, + instance_struct: syn::Ident, + doc: TokenStream, +} + +pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStream { + let mut impls = TokenStream::new(); + + let mut const_defs = vec![]; + + for line in def.storage_lines.iter() { + let storage_prefix = format!("{} {}", def.crate_name, line.name); + + let const_name = syn::Ident::new( + &format!("{}{}", PREFIX_FOR, line.name.to_string()), proc_macro2::Span::call_site() + ); + const_defs.push(InstanceConstDef { + name: const_name, + value_prefix: String::new(), + value_suffix: storage_prefix.clone(), + }); + + if let StorageLineTypeDef::LinkedMap(_) = line.storage_type { + let const_name = syn::Ident::new( + &format!("{}{}", HEAD_KEY_FOR, line.name.to_string()), proc_macro2::Span::call_site() + ); + const_defs.push(InstanceConstDef { + name: const_name, + value_prefix: "head of ".into(), + value_suffix: storage_prefix, + }); + } + } + + impls.extend(create_instance_trait(&const_defs, def)); + + // Implementation of instances. + if let Some(module_instance) = &def.module_instance { + let instance_defs = (0..NUMBER_OF_INSTANCE) + .map(|i| { + let name = format!("Instance{}", i); + InstanceDef { + instance_struct: syn::Ident::new(&name, proc_macro2::Span::call_site()), + prefix: name, + doc: quote!(#[doc=r"Module instance"]), + } + }) + .chain( + module_instance.instance_default.as_ref().map(|ident| InstanceDef { + prefix: String::new(), + instance_struct: ident.clone(), + doc: quote!(#[doc=r"Default module instance"]), + }) + ); + + for instance_def in instance_defs { + impls.extend(create_and_impl_instance_struct(scrate, &instance_def, &const_defs, def)); + } + } + + // The name of the inherently available instance. + let inherent_instance = syn::Ident::new(INHERENT_INSTANCE_NAME, Span::call_site()); + + // Implementation of inherent instance. + if let Some(default_instance) = def.module_instance.as_ref() + .and_then(|i| i.instance_default.as_ref()) + { + impls.extend(quote! { + #[doc(hidden)] + pub type #inherent_instance = #default_instance; + }); + } else { + let instance_def = InstanceDef { + prefix: String::new(), + instance_struct: inherent_instance, + doc: quote!(#[doc(hidden)]), + }; + impls.extend(create_and_impl_instance_struct(scrate, &instance_def, &const_defs, def)); + } + + impls +} + +fn create_instance_trait( + const_defs: &[InstanceConstDef], + def: &DeclStorageDefExt, +) -> TokenStream { + let instance_trait = def.module_instance.as_ref().map(|i| i.instance_trait.clone()) + .unwrap_or_else(|| syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site())); + + let mut const_impls = TokenStream::new(); + for const_def in const_defs { + let const_name = &const_def.name; + const_impls.extend(quote! { + const #const_name: &'static str; + }); + } + + let optional_hide = if def.module_instance.is_some() { + quote!() + } else { + quote!(#[doc(hidden)]) + }; + + quote! { + /// Tag a type as an instance of a module. + /// + /// Defines storage prefixes, they must be unique. + #optional_hide + pub trait #instance_trait: 'static { + /// The prefix used by any storage entry of an instance. + const PREFIX: &'static str; + #const_impls + } + } +} + +fn create_and_impl_instance_struct( + scrate: &TokenStream, + instance_def: &InstanceDef, + const_defs: &[InstanceConstDef], + def: &DeclStorageDefExt, +) -> TokenStream { + let mut const_impls = TokenStream::new(); + + for const_def in const_defs { + let const_value = format!( + "{}{}{}", const_def.value_prefix, instance_def.prefix, const_def.value_suffix + ); + let const_name = &const_def.name; + + const_impls.extend(quote! { + const #const_name: &'static str = #const_value; + }); + } + + let instance_trait = def.module_instance.as_ref().map(|i| i.instance_trait.clone()) + .unwrap_or_else(|| syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site())); + + let instance_struct = &instance_def.instance_struct; + let prefix = format!("{}{}", instance_def.prefix, def.crate_name.to_string()); + let doc = &instance_def.doc; + + quote! { + // Those trait are derived because of wrong bounds for generics + #[derive( + Clone, Eq, PartialEq, + #scrate::codec::Encode, + #scrate::codec::Decode, + #scrate::RuntimeDebug, + )] + #doc + pub struct #instance_struct; + impl #instance_trait for #instance_struct { + const PREFIX: &'static str = #prefix; + #const_impls + } + } +} diff --git a/srml/support/procedural/src/storage/metadata.rs b/srml/support/procedural/src/storage/metadata.rs new file mode 100644 index 0000000000000000000000000000000000000000..e280c7d8a20c6c45fc88eb25d7cd1af4905094cc --- /dev/null +++ b/srml/support/procedural/src/storage/metadata.rs @@ -0,0 +1,230 @@ +// 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 . + +//! Implementation of `storage_metadata` on module structure, used by construct_runtime. + +use srml_support_procedural_tools::clean_type_string; +use proc_macro2::TokenStream; +use quote::quote; +use super::{DeclStorageDefExt, StorageLineDefExt, StorageLineTypeDef}; + +fn storage_line_metadata_type(scrate: &TokenStream, line: &StorageLineDefExt) -> TokenStream { + let value_type = &line.value_type; + let value_type = clean_type_string("e!( #value_type ).to_string()); + match &line.storage_type { + StorageLineTypeDef::Simple(_) => { + quote!{ + #scrate::metadata::StorageEntryType::Plain( + #scrate::metadata::DecodeDifferent::Encode(#value_type), + ) + } + }, + StorageLineTypeDef::Map(map) => { + let hasher = map.hasher.into_metadata(); + let key = &map.key; + let key = clean_type_string("e!(#key).to_string()); + quote!{ + #scrate::metadata::StorageEntryType::Map { + hasher: #scrate::metadata::#hasher, + key: #scrate::metadata::DecodeDifferent::Encode(#key), + value: #scrate::metadata::DecodeDifferent::Encode(#value_type), + is_linked: false, + } + } + }, + StorageLineTypeDef::LinkedMap(map) => { + let hasher = map.hasher.into_metadata(); + let key = &map.key; + let key = clean_type_string("e!(#key).to_string()); + quote!{ + #scrate::metadata::StorageEntryType::Map { + hasher: #scrate::metadata::#hasher, + key: #scrate::metadata::DecodeDifferent::Encode(#key), + value: #scrate::metadata::DecodeDifferent::Encode(#value_type), + is_linked: true, + } + } + }, + StorageLineTypeDef::DoubleMap(map) => { + let hasher1 = map.hasher1.into_metadata(); + let hasher2 = map.hasher2.into_metadata(); + let key1 = &map.key1; + let key1 = clean_type_string("e!(#key1).to_string()); + let key2 = &map.key2; + let key2 = clean_type_string("e!(#key2).to_string()); + quote!{ + #scrate::metadata::StorageEntryType::DoubleMap { + hasher: #scrate::metadata::#hasher1, + key1: #scrate::metadata::DecodeDifferent::Encode(#key1), + key2: #scrate::metadata::DecodeDifferent::Encode(#key2), + value: #scrate::metadata::DecodeDifferent::Encode(#value_type), + key2_hasher: #scrate::metadata::#hasher2, + } + } + }, + } +} + +fn default_byte_getter( + scrate: &TokenStream, + line: &StorageLineDefExt, + def: &DeclStorageDefExt, +) -> (TokenStream, TokenStream) { + let default = line.default_value.as_ref().map(|d| quote!( #d )) + .unwrap_or_else(|| quote!( Default::default() )); + + let str_name = line.name.to_string(); + let struct_name = syn::Ident::new(&("__GetByteStruct".to_string() + &str_name), line.name.span()); + let cache_name = syn::Ident::new(&("__CACHE_GET_BYTE_STRUCT_".to_string() + &str_name), line.name.span()); + + let runtime_generic = &def.module_runtime_generic; + let runtime_trait = &def.module_runtime_trait; + let optional_instance_bound_optional_default = &def.optional_instance_bound_optional_default; + let optional_instance_bound = &def.optional_instance_bound; + let optional_instance = &def.optional_instance; + let optional_comma_instance = optional_instance.as_ref().map(|i| quote!(, #i)); + let where_clause = &def.where_clause; + + let query_type = &line.query_type; + + let struct_def = quote! { + #[doc(hidden)] + pub struct #struct_name< + #runtime_generic, #optional_instance_bound_optional_default + >(pub #scrate::rstd::marker::PhantomData<(#runtime_generic #optional_comma_instance)>); + + #[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::new(); + + #[cfg(feature = "std")] + impl<#runtime_generic: #runtime_trait, #optional_instance_bound> + #scrate::metadata::DefaultByte + for #struct_name<#runtime_generic, #optional_instance> + #where_clause + { + fn default_byte(&self) -> #scrate::rstd::vec::Vec { + use #scrate::codec::Encode; + #cache_name.get_or_init(|| { + let def_val: #query_type = #default; + <#query_type as Encode>::encode(&def_val) + }).clone() + } + } + + unsafe impl<#runtime_generic: #runtime_trait, #optional_instance_bound> Send + for #struct_name<#runtime_generic, #optional_instance> #where_clause {} + + unsafe impl<#runtime_generic: #runtime_trait, #optional_instance_bound> Sync + for #struct_name<#runtime_generic, #optional_instance> #where_clause {} + + #[cfg(not(feature = "std"))] + impl<#runtime_generic: #runtime_trait, #optional_instance_bound> + #scrate::metadata::DefaultByte + for #struct_name<#runtime_generic, #optional_instance> + #where_clause + { + fn default_byte(&self) -> #scrate::rstd::vec::Vec { + use #scrate::codec::Encode; + let def_val: #query_type = #default; + <#query_type as Encode>::encode(&def_val) + } + } + }; + let struct_instance = quote!( + #struct_name::<#runtime_generic, #optional_instance>(#scrate::rstd::marker::PhantomData) + ); + + (struct_def, struct_instance) +} + +pub fn impl_metadata(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStream { + let mut entries = TokenStream::new(); + let mut default_byte_getter_struct_defs = TokenStream::new(); + + for line in def.storage_lines.iter() { + let str_name = line.name.to_string(); + + let modifier = if line.is_option { + quote!(#scrate::metadata::StorageEntryModifier::Optional) + } else { + quote!(#scrate::metadata::StorageEntryModifier::Default) + }; + + let ty = storage_line_metadata_type(scrate, line); + + let ( + default_byte_getter_struct_def, + default_byte_getter_struct_instance, + ) = default_byte_getter(scrate, line, def); + + let mut docs = TokenStream::new(); + for attr in line.attrs.iter().filter_map(|v| v.parse_meta().ok()) { + if let syn::Meta::NameValue(meta) = attr { + if meta.ident == "doc" { + let lit = meta.lit; + docs.extend(quote!(#lit,)); + } + } + } + + let entry = quote! { + #scrate::metadata::StorageEntryMetadata { + name: #scrate::metadata::DecodeDifferent::Encode(#str_name), + modifier: #modifier, + ty: #ty, + default: #scrate::metadata::DecodeDifferent::Encode( + #scrate::metadata::DefaultByteGetter(&#default_byte_getter_struct_instance) + ), + documentation: #scrate::metadata::DecodeDifferent::Encode(&[ #docs ]), + }, + }; + + default_byte_getter_struct_defs.extend(default_byte_getter_struct_def); + entries.extend(entry); + } + + let prefix = if let Some(instance) = &def.module_instance { + let instance_generic = &instance.instance_generic; + quote!(#instance_generic::PREFIX) + } else { + let prefix = def.crate_name.to_string(); + quote!(#prefix) + }; + + let store_metadata = quote!( + #scrate::metadata::StorageMetadata { + prefix: #scrate::metadata::DecodeDifferent::Encode(#prefix), + entries: #scrate::metadata::DecodeDifferent::Encode(&[ #entries ][..]), + } + ); + + let module_struct = &def.module_struct; + let module_impl = &def.module_impl; + let where_clause = &def.where_clause; + + quote!( + #default_byte_getter_struct_defs + + impl#module_impl #module_struct #where_clause { + #[doc(hidden)] + pub fn storage_metadata() -> #scrate::metadata::StorageMetadata { + #store_metadata + } + } + ) +} diff --git a/srml/support/procedural/src/storage/mod.rs b/srml/support/procedural/src/storage/mod.rs index 4253206f44da064d5903362c3ed72aedbb51a0c7..9a6931d87e9c8eef5a2a46b506d12a989877a144 100644 --- a/srml/support/procedural/src/storage/mod.rs +++ b/srml/support/procedural/src/storage/mod.rs @@ -14,191 +14,358 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] -//! `decl_storage` macro -// end::description[] +//! `decl_storage` input definition and expansion. + +mod storage_struct; +mod parse; +mod store_trait; +mod getters; +mod metadata; +mod instance_trait; +mod genesis_config; -use srml_support_procedural_tools::{ToTokens, Parse, syn_ext as ext}; -use syn::{Ident, Token}; -use proc_macro2::TokenStream as TokenStream2; use quote::quote; +use srml_support_procedural_tools::{ + generate_crate_access, generate_hidden_includes, syn_ext as ext +}; -mod impls; - -pub mod transformation; - -mod keyword { - syn::custom_keyword!(hiddencrate); - syn::custom_keyword!(add_extra_genesis); - syn::custom_keyword!(extra_genesis_skip_phantom_data_field); - syn::custom_keyword!(config); - syn::custom_keyword!(build); - syn::custom_keyword!(get); - syn::custom_keyword!(map); - syn::custom_keyword!(linked_map); - syn::custom_keyword!(double_map); - syn::custom_keyword!(blake2_256); - syn::custom_keyword!(blake2_128); - syn::custom_keyword!(twox_256); - syn::custom_keyword!(twox_128); - syn::custom_keyword!(twox_64_concat); - syn::custom_keyword!(hasher); +/// All informations contained in input of decl_storage +pub struct DeclStorageDef { + /// Name of the module used to import hidden imports. + hidden_crate: Option, + /// Visibility of store trait. + visibility: syn::Visibility, + /// Name of store trait: usually `Store`. + store_trait: syn::Ident, + /// Module name used by construct_runtime: usually `Module`. + module_name: syn::Ident, + /// Usually `T`. + module_runtime_generic: syn::Ident, + /// Usually `Trait` + module_runtime_trait: syn::Path, + /// For instantiable module: usually `I: Instance=DefaultInstance`. + module_instance: Option, + /// Where claused used to constrain T and I even more. + where_clause: Option, + /// The extra build function used to build storage at genesis. + extra_genesis_build: Option, + /// The extra genesis config fields. + extra_genesis_config_lines: Vec, + /// Definition of storages. + storage_lines: Vec, + /// Name of the crate, used for storage prefixes. + crate_name: syn::Ident, } -/// Parsing usage only -#[derive(Parse, ToTokens, Debug)] -struct StorageDefinition { - pub hidden_crate: ext::Opt, - pub visibility: syn::Visibility, - pub trait_token: Token![trait], - pub ident: Ident, - pub for_token: Token![for], - pub module_ident: Ident, - pub mod_lt_token: Token![<], - pub mod_param: syn::GenericParam, - pub mod_instance_param_token: Option, - pub mod_instance: Option, - pub mod_instantiable_token: Option, - pub mod_instantiable: Option, - pub mod_default_instance_token: Option, - pub mod_default_instance: Option, - pub mod_gt_token: Token![>], - pub as_token: Token![as], - pub crate_ident: Ident, - pub where_clause: Option, - pub content: ext::Braces>, - pub extra_genesis: ext::Opt, +impl syn::parse::Parse for DeclStorageDef { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + parse::parse(input) + } } -#[derive(Parse, ToTokens, Debug)] -struct SpecificHiddenCrate { - pub keyword: keyword::hiddencrate, - pub ident: ext::Parens, +/// Extended version of `DeclStorageDef` with useful precomputed value. +pub struct DeclStorageDefExt { + /// Name of the module used to import hidden imports. + hidden_crate: Option, + /// Visibility of store trait. + visibility: syn::Visibility, + /// Name of store trait: usually `Store`. + store_trait: syn::Ident, + /// Module name used by construct_runtime: usually `Module`. + #[allow(unused)] + module_name: syn::Ident, + /// Usually `T`. + module_runtime_generic: syn::Ident, + /// Usually `Trait`. + module_runtime_trait: syn::Path, + /// For instantiable module: usually `I: Instance=DefaultInstance`. + module_instance: Option, + /// Where claused used to constrain T and I even more. + where_clause: Option, + /// The extra build function used to build storage at genesis. + extra_genesis_build: Option, + /// The extra genesis config fields. + extra_genesis_config_lines: Vec, + /// Definition of storages. + storage_lines: Vec, + /// Name of the crate, used for storage prefixes. + crate_name: syn::Ident, + /// Full struct expansion: `Module`. + module_struct: proc_macro2::TokenStream, + /// Impl block for module: ``. + module_impl: proc_macro2::TokenStream, + /// For instantiable: `I`. + optional_instance: Option, + /// For instantiable: `I: Instance`. + optional_instance_bound: Option, + /// For instantiable: `I: Instance = DefaultInstance`. + optional_instance_bound_optional_default: Option, } -#[derive(Parse, ToTokens, Debug)] -struct AddExtraGenesis { - pub extragenesis_keyword: keyword::add_extra_genesis, - pub content: ext::Braces, -} +impl From for DeclStorageDefExt { + fn from(mut def: DeclStorageDef) -> Self { + let storage_lines = def.storage_lines.drain(..).collect::>(); + let storage_lines = storage_lines.into_iter() + .map(|line| StorageLineDefExt::from_def(line, &def)) + .collect(); + + let ( + optional_instance, + optional_instance_bound, + optional_instance_bound_optional_default, + ) = if let Some(instance) = def.module_instance.as_ref() { + let instance_generic = &instance.instance_generic; + let instance_trait= &instance.instance_trait; + let optional_equal_instance_default = instance.instance_default.as_ref() + .map(|d| quote!( = #d )); + ( + Some(quote!(#instance_generic)), + Some(quote!(#instance_generic: #instance_trait)), + Some(quote!(#instance_generic: #instance_trait #optional_equal_instance_default)), + ) + } else { + (None, None, None) + }; + + let module_runtime_generic = &def.module_runtime_generic; + let module_runtime_trait = &def.module_runtime_trait; + let module_name = &def.module_name; -#[derive(Parse, ToTokens, Debug)] -struct AddExtraGenesisContent { - pub lines: ext::Punctuated, + let module_struct = quote!( + #module_name<#module_runtime_generic, #optional_instance> + ); + + let module_impl = quote!( + <#module_runtime_generic: #module_runtime_trait + 'static, #optional_instance_bound> + ); + + Self { + hidden_crate: def.hidden_crate, + visibility: def.visibility, + store_trait: def.store_trait, + module_name: def.module_name, + module_runtime_generic: def.module_runtime_generic, + module_runtime_trait: def.module_runtime_trait, + module_instance: def.module_instance, + where_clause: def.where_clause, + extra_genesis_build: def.extra_genesis_build, + extra_genesis_config_lines: def.extra_genesis_config_lines, + crate_name: def.crate_name, + storage_lines, + module_struct, + module_impl, + optional_instance, + optional_instance_bound, + optional_instance_bound_optional_default, + } + } } -#[derive(Parse, ToTokens, Debug)] -enum AddExtraGenesisLineEnum { - AddExtraGenesisLine(AddExtraGenesisLine), - AddExtraGenesisBuild(DeclStorageBuild), +/// Usually `I: Instance=DefaultInstance`. +pub struct ModuleInstanceDef { + /// Usually: `I`. + instance_generic: syn::Ident, + /// Usually: `Instance`. + instance_trait: syn::Ident, + /// Usually: `DefaultInstance`. + instance_default: Option, } -#[derive(Parse, ToTokens, Debug)] -struct AddExtraGenesisLine { - pub attrs: ext::OuterAttributes, - pub config_keyword: keyword::config, - pub extra_field: ext::Parens, - pub coldot_token: Token![:], - pub extra_type: syn::Type, - pub default_value: ext::Opt, +pub struct StorageLineDef { + attrs: Vec, + /// Visibility of the storage struct. + visibility: syn::Visibility, + name: syn::Ident, + /// The name of getter function to be implemented on Module struct. + getter: Option, + /// The name of the field to be used in genesis config if any. + config: Option, + /// The build function of the storage if any. + build: Option, + /// Default value of genesis config field and also for storage when no value available. + default_value: Option, + storage_type: StorageLineTypeDef, } -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageLine { - // attrs (main use case is doc) - pub attrs: ext::OuterAttributes, - // visibility (no need to make optional - pub visibility: syn::Visibility, - // name - pub name: Ident, - pub getter: ext::Opt, - pub config: ext::Opt, - pub build: ext::Opt, - pub coldot_token: Token![:], - pub storage_type: DeclStorageType, - pub default_value: ext::Opt, +pub struct StorageLineDefExt { + #[allow(unused)] + attrs: Vec, + /// Visibility of the storage struct. + visibility: syn::Visibility, + name: syn::Ident, + /// The name of getter function to be implemented on Module struct. + getter: Option, + /// The name of the field to be used in genesis config if any. + config: Option, + /// The build function of the storage if any. + build: Option, + /// Default value of genesis config field and also for storage when no value available. + default_value: Option, + storage_type: StorageLineTypeDef, + doc_attrs: Vec, + /// Either the type stored in storage or wrapped in an Option. + query_type: syn::Type, + /// The type stored in storage. + value_type: syn::Type, + /// Full struct, for example: `StorageName`. + storage_struct: proc_macro2::TokenStream, + /// If storage is generic over runtime then `T`. + optional_storage_runtime_comma: Option, + /// If storage is generic over runtime then `T: Trait`. + optional_storage_runtime_bound_comma: Option, + /// The where clause to use to constrain generics if storage is generic over runtime. + optional_storage_where_clause: Option, + /// Full trait, for example: `storage::StorageMap`. + storage_trait: proc_macro2::TokenStream, + /// Full trait, for example: `storage::generator::StorageMap`. + storage_generator_trait: proc_macro2::TokenStream, + /// Weither the storage is generic. + is_generic: bool, + /// Weither the storage value is an option. + is_option: bool, } +impl StorageLineDefExt { + fn from_def(storage_def: StorageLineDef, def: &DeclStorageDef) -> Self { + let is_generic = match &storage_def.storage_type { + StorageLineTypeDef::Simple(value) => { + ext::type_contains_ident(&value, &def.module_runtime_generic) + }, + StorageLineTypeDef::Map(map) => { + ext::type_contains_ident(&map.key, &def.module_runtime_generic) + || ext::type_contains_ident(&map.value, &def.module_runtime_generic) + } + StorageLineTypeDef::LinkedMap(map) => { + ext::type_contains_ident(&map.key, &def.module_runtime_generic) + || ext::type_contains_ident(&map.value, &def.module_runtime_generic) + } + StorageLineTypeDef::DoubleMap(map) => { + ext::type_contains_ident(&map.key1, &def.module_runtime_generic) + || ext::type_contains_ident(&map.key2, &def.module_runtime_generic) + || ext::type_contains_ident(&map.value, &def.module_runtime_generic) + } + }; -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageGetter { - pub getter_keyword: keyword::get, - pub getfn: ext::Parens, -} + let query_type = match &storage_def.storage_type { + StorageLineTypeDef::Simple(value) => value.clone(), + StorageLineTypeDef::Map(map) => map.value.clone(), + StorageLineTypeDef::LinkedMap(map) => map.value.clone(), + StorageLineTypeDef::DoubleMap(map) => map.value.clone(), + }; + let is_option = ext::extract_type_option(&query_type).is_some(); + let value_type = ext::extract_type_option(&query_type).unwrap_or(query_type.clone()); -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageConfig { - pub config_keyword: keyword::config, - pub expr: ext::Parens>, -} + let module_runtime_generic = &def.module_runtime_generic; + let module_runtime_trait = &def.module_runtime_trait; + let optional_storage_runtime_comma = if is_generic { + Some(quote!( #module_runtime_generic, )) + } else { + None + }; + let optional_storage_runtime_bound_comma = if is_generic { + Some(quote!( #module_runtime_generic: #module_runtime_trait, )) + } else { + None + }; -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageBuild { - pub build_keyword: keyword::build, - pub expr: ext::Parens, -} + let storage_name = &storage_def.name; + let optional_instance_generic = def.module_instance.as_ref().map(|i| { + let instance_generic = &i.instance_generic; + quote!( #instance_generic ) + }); + let storage_struct = quote!( + #storage_name<#optional_storage_runtime_comma #optional_instance_generic> + ); -#[derive(Parse, ToTokens, Debug)] -enum DeclStorageType { - Map(DeclStorageMap), - LinkedMap(DeclStorageLinkedMap), - DoubleMap(DeclStorageDoubleMap), - Simple(syn::Type), + let optional_storage_where_clause = if is_generic { + def.where_clause.as_ref().map(|w| quote!( #w )) + } else { + None + }; + + let storage_trait_trunkated = match &storage_def.storage_type { + StorageLineTypeDef::Simple(_) => { + quote!( StorageValue<#value_type> ) + }, + StorageLineTypeDef::Map(map) => { + let key = &map.key; + quote!( StorageMap<#key, #value_type> ) + }, + StorageLineTypeDef::LinkedMap(map) => { + let key = &map.key; + quote!( StorageLinkedMap<#key, #value_type> ) + }, + StorageLineTypeDef::DoubleMap(map) => { + let key1 = &map.key1; + let key2 = &map.key2; + quote!( StorageDoubleMap<#key1, #key2, #value_type> ) + }, + }; + + let storage_trait = quote!( storage::#storage_trait_trunkated ); + let storage_generator_trait = quote!( storage::generator::#storage_trait_trunkated ); + + let doc_attrs = storage_def.attrs.iter() + .filter_map(|a| a.parse_meta().ok()) + .filter(|m| m.name() == "doc") + .collect(); + + Self { + attrs: storage_def.attrs, + visibility: storage_def.visibility, + name: storage_def.name, + getter: storage_def.getter, + config: storage_def.config, + build: storage_def.build, + default_value: storage_def.default_value, + storage_type: storage_def.storage_type, + doc_attrs, + query_type, + value_type, + storage_struct, + optional_storage_runtime_comma, + optional_storage_runtime_bound_comma, + optional_storage_where_clause, + storage_trait, + storage_generator_trait, + is_generic, + is_option, + } + } } -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageMap { - pub map_keyword: keyword::map, - pub hasher: ext::Opt, - pub key: syn::Type, - pub ass_keyword: Token![=>], - pub value: syn::Type, +pub enum StorageLineTypeDef { + Map(MapDef), + LinkedMap(MapDef), + DoubleMap(DoubleMapDef), + Simple(syn::Type), } -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageLinkedMap { - pub map_keyword: keyword::linked_map, - pub hasher: ext::Opt, +pub struct MapDef { + pub hasher: HasherKind, pub key: syn::Type, - pub ass_keyword: Token![=>], + /// This is the query value not the inner value used in storage trait implementation. pub value: syn::Type, } -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageDoubleMap { - pub map_keyword: keyword::double_map, - pub hasher: ext::Opt, +pub struct DoubleMapDef { + pub hasher1: HasherKind, + pub hasher2: HasherKind, pub key1: syn::Type, - pub comma_keyword: Token![,], - pub key2_hasher: Hasher, - pub key2: ext::Parens, - pub ass_keyword: Token![=>], + pub key2: syn::Type, + /// This is the query value not the inner value used in storage trait implementation. pub value: syn::Type, } -#[derive(Parse, ToTokens, Debug)] -enum Hasher { - Blake2_256(keyword::blake2_256), - Blake2_128(keyword::blake2_128), - Twox256(keyword::twox_256), - Twox128(keyword::twox_128), - Twox64Concat(keyword::twox_64_concat), -} - -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageDefault { - pub equal_token: Token![=], - pub expr: syn::Expr, -} - -#[derive(Parse, ToTokens, Debug)] -struct SetHasher { - pub hasher_keyword: keyword::hasher, - pub inner: ext::Parens, +pub struct ExtraGenesisLineDef { + attrs: Vec, + name: syn::Ident, + typ: syn::Type, + default: Option, } #[derive(Debug, Clone)] -enum HasherKind { +pub enum HasherKind { Blake2_256, Blake2_128, Twox256, @@ -206,26 +373,8 @@ enum HasherKind { Twox64Concat, } -impl From<&SetHasher> for HasherKind { - fn from(set_hasher: &SetHasher) -> Self { - (&set_hasher.inner.content).into() - } -} - -impl From<&Hasher> for HasherKind { - fn from(hasher: &Hasher) -> Self { - match hasher { - Hasher::Blake2_256(_) => HasherKind::Blake2_256, - Hasher::Blake2_128(_) => HasherKind::Blake2_128, - Hasher::Twox256(_) => HasherKind::Twox256, - Hasher::Twox128(_) => HasherKind::Twox128, - Hasher::Twox64Concat(_) => HasherKind::Twox64Concat, - } - } -} - impl HasherKind { - fn into_storage_hasher_struct(&self) -> TokenStream2 { + fn to_storage_hasher_struct(&self) -> proc_macro2::TokenStream { match self { HasherKind::Blake2_256 => quote!( Blake2_256 ), HasherKind::Blake2_128 => quote!( Blake2_128 ), @@ -235,7 +384,7 @@ impl HasherKind { } } - fn into_metadata(&self) -> TokenStream2 { + fn into_metadata(&self) -> proc_macro2::TokenStream { match self { HasherKind::Blake2_256 => quote!( StorageHasher::Blake2_256 ), HasherKind::Blake2_128 => quote!( StorageHasher::Blake2_128 ), @@ -245,3 +394,39 @@ impl HasherKind { } } } + +/// Full implementation of decl_storage. +pub fn decl_storage_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let def = syn::parse_macro_input!(input as DeclStorageDef); + let def_ext = DeclStorageDefExt::from(def); + + let hidden_crate_name = def_ext.hidden_crate.as_ref().map(|i| i.to_string()) + .unwrap_or_else(|| "decl_storage".to_string()); + + let scrate = generate_crate_access(&hidden_crate_name, "srml-support"); + let scrate_decl = generate_hidden_includes(&hidden_crate_name, "srml-support"); + + let store_trait = store_trait::decl_and_impl(&def_ext); + let getters = getters::impl_getters(&scrate, &def_ext); + let metadata = metadata::impl_metadata(&scrate, &def_ext); + let instance_trait = instance_trait::decl_and_impl(&scrate, &def_ext); + let genesis_config = genesis_config::genesis_config_and_build_storage(&scrate, &def_ext); + let storage_struct = storage_struct::decl_and_impl(&scrate, &def_ext); + + quote!( + use #scrate::{ + StorageValue as _, + StorageMap as _, + StorageLinkedMap as _, + StorageDoubleMap as _ + }; + + #scrate_decl + #store_trait + #getters + #metadata + #instance_trait + #genesis_config + #storage_struct + ).into() +} diff --git a/srml/support/procedural/src/storage/parse.rs b/srml/support/procedural/src/storage/parse.rs new file mode 100644 index 0000000000000000000000000000000000000000..53da5ae33e92f1343762c140a3333be3383b030a --- /dev/null +++ b/srml/support/procedural/src/storage/parse.rs @@ -0,0 +1,382 @@ +// 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 . + +//! Parsing of decl_storage input. + +use srml_support_procedural_tools::{ToTokens, Parse, syn_ext as ext}; +use syn::{Ident, Token}; + +mod keyword { + syn::custom_keyword!(hiddencrate); + syn::custom_keyword!(add_extra_genesis); + syn::custom_keyword!(extra_genesis_skip_phantom_data_field); + syn::custom_keyword!(config); + syn::custom_keyword!(build); + syn::custom_keyword!(get); + syn::custom_keyword!(map); + syn::custom_keyword!(linked_map); + syn::custom_keyword!(double_map); + syn::custom_keyword!(blake2_256); + syn::custom_keyword!(blake2_128); + syn::custom_keyword!(twox_256); + syn::custom_keyword!(twox_128); + syn::custom_keyword!(twox_64_concat); + syn::custom_keyword!(hasher); +} + +/// Parsing usage only +#[derive(Parse, ToTokens, Debug)] +struct StorageDefinition { + pub hidden_crate: ext::Opt, + pub visibility: syn::Visibility, + pub trait_token: Token![trait], + pub ident: Ident, + pub for_token: Token![for], + pub module_ident: Ident, + pub mod_lt_token: Token![<], + pub mod_param_generic: syn::Ident, + pub mod_param_bound_token: Option, + pub mod_param_bound: syn::Path, + pub mod_instance_param_token: Option, + pub mod_instance: Option, + pub mod_instantiable_token: Option, + pub mod_instantiable: Option, + pub mod_default_instance_token: Option, + pub mod_default_instance: Option, + pub mod_gt_token: Token![>], + pub as_token: Token![as], + pub crate_ident: Ident, + pub where_clause: Option, + pub content: ext::Braces>, + pub extra_genesis: ext::Opt, +} + +#[derive(Parse, ToTokens, Debug)] +struct SpecificHiddenCrate { + pub keyword: keyword::hiddencrate, + pub ident: ext::Parens, +} + +#[derive(Parse, ToTokens, Debug)] +struct AddExtraGenesis { + pub extragenesis_keyword: keyword::add_extra_genesis, + pub content: ext::Braces, +} + +#[derive(Parse, ToTokens, Debug)] +struct AddExtraGenesisContent { + pub lines: ext::Punctuated, +} + +#[derive(Parse, ToTokens, Debug)] +enum AddExtraGenesisLineEnum { + AddExtraGenesisLine(AddExtraGenesisLine), + AddExtraGenesisBuild(DeclStorageBuild), +} + +#[derive(Parse, ToTokens, Debug)] +struct AddExtraGenesisLine { + pub attrs: ext::OuterAttributes, + pub config_keyword: keyword::config, + pub extra_field: ext::Parens, + pub coldot_token: Token![:], + pub extra_type: syn::Type, + pub default_value: ext::Opt, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageLine { + // attrs (main use case is doc) + pub attrs: ext::OuterAttributes, + // visibility (no need to make optional + pub visibility: syn::Visibility, + // name + pub name: Ident, + pub getter: ext::Opt, + pub config: ext::Opt, + pub build: ext::Opt, + pub coldot_token: Token![:], + pub storage_type: DeclStorageType, + pub default_value: ext::Opt, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageGetterBody { + fn_keyword: Option, + ident: Ident, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageGetter { + pub getter_keyword: keyword::get, + pub getfn: ext::Parens, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageConfig { + pub config_keyword: keyword::config, + pub expr: ext::Parens>, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageBuild { + pub build_keyword: keyword::build, + pub expr: ext::Parens, +} + +#[derive(Parse, ToTokens, Debug)] +enum DeclStorageType { + Map(DeclStorageMap), + LinkedMap(DeclStorageLinkedMap), + DoubleMap(DeclStorageDoubleMap), + Simple(syn::Type), +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageMap { + pub map_keyword: keyword::map, + pub hasher: ext::Opt, + pub key: syn::Type, + pub ass_keyword: Token![=>], + pub value: syn::Type, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageLinkedMap { + pub map_keyword: keyword::linked_map, + pub hasher: ext::Opt, + pub key: syn::Type, + pub ass_keyword: Token![=>], + pub value: syn::Type, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageDoubleMap { + pub map_keyword: keyword::double_map, + pub hasher: ext::Opt, + pub key1: syn::Type, + pub comma_keyword: Token![,], + pub key2_hasher: Hasher, + pub key2: ext::Parens, + pub ass_keyword: Token![=>], + pub value: syn::Type, +} + +#[derive(Parse, ToTokens, Debug)] +enum Hasher { + Blake2_256(keyword::blake2_256), + Blake2_128(keyword::blake2_128), + Twox256(keyword::twox_256), + Twox128(keyword::twox_128), + Twox64Concat(keyword::twox_64_concat), +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageDefault { + pub equal_token: Token![=], + pub expr: syn::Expr, +} + +#[derive(Parse, ToTokens, Debug)] +struct SetHasher { + pub hasher_keyword: keyword::hasher, + pub inner: ext::Parens, +} + +impl From for super::HasherKind { + fn from(set_hasher: SetHasher) -> Self { + set_hasher.inner.content.into() + } +} + +impl From for super::HasherKind { + fn from(hasher: Hasher) -> Self { + match hasher { + Hasher::Blake2_256(_) => super::HasherKind::Blake2_256, + Hasher::Blake2_128(_) => super::HasherKind::Blake2_128, + Hasher::Twox256(_) => super::HasherKind::Twox256, + Hasher::Twox128(_) => super::HasherKind::Twox128, + Hasher::Twox64Concat(_) => super::HasherKind::Twox64Concat, + } + } +} + +fn get_module_instance( + instance: Option, + instantiable: Option, + default_instance: Option, +) -> syn::Result> { + let right_syntax = "Should be $Instance: $Instantiable = $DefaultInstance"; + + match (instance, instantiable, default_instance) { + (Some(instance), Some(instantiable), default_instance) => { + Ok(Some(super::ModuleInstanceDef { + instance_generic: instance, + instance_trait: instantiable, + instance_default: default_instance, + })) + }, + (None, None, None) => Ok(None), + (Some(instance), None, _) => Err( + syn::Error::new( + instance.span(), + format!( + "Expect instantiable trait bound for instance: {}. {}", + instance, + right_syntax, + ) + ) + ), + (None, Some(instantiable), _) => Err( + syn::Error::new( + instantiable.span(), + format!( + "Expect instance generic for bound instantiable: {}. {}", + instantiable, + right_syntax, + ) + ) + ), + (None, _, Some(default_instance)) => Err( + syn::Error::new( + default_instance.span(), + format!( + "Expect instance generic for default instance: {}. {}", + default_instance, + right_syntax, + ) + ) + ), + } +} + +pub fn parse(input: syn::parse::ParseStream) -> syn::Result { + use syn::parse::Parse; + use syn::spanned::Spanned; + + let def = StorageDefinition::parse(input)?; + + let module_instance = get_module_instance( + def.mod_instance, + def.mod_instantiable, + def.mod_default_instance, + )?; + + let mut extra_genesis_config_lines = vec![]; + let mut extra_genesis_build = None; + + for line in def.extra_genesis.inner.into_iter() + .flat_map(|o| o.content.content.lines.inner.into_iter()) + { + match line { + AddExtraGenesisLineEnum::AddExtraGenesisLine(def) => { + extra_genesis_config_lines.push(super::ExtraGenesisLineDef{ + attrs: def.attrs.inner, + name: def.extra_field.content, + typ: def.extra_type, + default: def.default_value.inner.map(|o| o.expr), + }); + } + AddExtraGenesisLineEnum::AddExtraGenesisBuild(def) => { + if extra_genesis_build.is_some() { + return Err(syn::Error::new( + def.span(), + "Only one build expression allowed for extra genesis" + )) + } + + extra_genesis_build = Some(def.expr.content); + } + } + } + + let mut storage_lines = vec![]; + + for line in def.content.content.inner.into_iter() { + let getter = line.getter.inner.map(|o| o.getfn.content.ident); + let config = if let Some(config) = line.config.inner { + if let Some(ident) = config.expr.content { + Some(ident) + } else if let Some(ref ident) = getter { + Some(ident.clone()) + } else { + return Err(syn::Error::new( + config.span(), + "Invalid storage definiton, couldn't find config identifier: storage must either have a get \ + identifier `get(fn ident)` or a defined config identifier `config(ident)`" + )) + } + } else { + None + }; + + let storage_type = match line.storage_type { + DeclStorageType::Map(map) => super::StorageLineTypeDef::Map( + super::MapDef { + hasher: map.hasher.inner.map(Into::into) + .unwrap_or(super::HasherKind::Blake2_256), + key: map.key, + value: map.value, + } + ), + DeclStorageType::LinkedMap(map) => super::StorageLineTypeDef::LinkedMap( + super::MapDef { + hasher: map.hasher.inner.map(Into::into) + .unwrap_or(super::HasherKind::Blake2_256), + key: map.key, + value: map.value, + } + ), + DeclStorageType::DoubleMap(map) => super::StorageLineTypeDef::DoubleMap( + super::DoubleMapDef { + hasher1: map.hasher.inner.map(Into::into) + .unwrap_or(super::HasherKind::Blake2_256), + hasher2: map.key2_hasher.into(), + key1: map.key1, + key2: map.key2.content, + value: map.value, + } + ), + DeclStorageType::Simple(expr) => super::StorageLineTypeDef::Simple(expr), + }; + + storage_lines.push(super::StorageLineDef { + attrs: line.attrs.inner, + visibility: line.visibility, + name: line.name, + getter, + config, + build: line.build.inner.map(|o| o.expr.content), + default_value: line.default_value.inner.map(|o| o.expr), + storage_type, + }) + } + + Ok(super::DeclStorageDef { + hidden_crate: def.hidden_crate.inner.map(|i| i.ident.content), + visibility: def.visibility, + module_name: def.module_ident, + store_trait: def.ident, + module_runtime_generic: def.mod_param_generic, + module_runtime_trait: def.mod_param_bound, + where_clause: def.where_clause, + crate_name: def.crate_ident, + module_instance, + extra_genesis_build, + extra_genesis_config_lines, + storage_lines, + }) +} diff --git a/srml/support/procedural/src/storage/storage_struct.rs b/srml/support/procedural/src/storage/storage_struct.rs new file mode 100644 index 0000000000000000000000000000000000000000..e195fb53e8a2c3a28e773f6fcb845f0bdc2dffc8 --- /dev/null +++ b/srml/support/procedural/src/storage/storage_struct.rs @@ -0,0 +1,220 @@ +// 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 storage structures and implementation of storage traits on them. + +use proc_macro2::TokenStream; +use quote::quote; +use super::{ + DeclStorageDefExt, StorageLineTypeDef, + instance_trait::{PREFIX_FOR, HEAD_KEY_FOR}, +}; + +fn from_optional_value_to_query(is_option: bool, default: &Option) -> TokenStream { + let default = default.as_ref().map(|d| quote!( #d )) + .unwrap_or_else(|| quote!( Default::default() )); + + if !is_option { + // raw type case + quote!( v.unwrap_or_else(|| #default ) ) + } else { + // Option<> type case + quote!( v.or_else(|| #default ) ) + } +} + +fn from_query_to_optional_value(is_option: bool) -> TokenStream { + if !is_option { + // raw type case + quote!( Some(v) ) + } else { + // Option<> type case + quote!( v ) + } +} + +pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStream { + let mut impls = TokenStream::new(); + + for line in &def.storage_lines { + + // Propagate doc attributes. + let attrs = &line.doc_attrs; + + let visibility = &line.visibility; + let optional_storage_runtime_comma = &line.optional_storage_runtime_comma; + let optional_storage_runtime_bound_comma = &line.optional_storage_runtime_bound_comma; + let optional_storage_where_clause = &line.optional_storage_where_clause; + let optional_instance_bound_optional_default = &def.optional_instance_bound_optional_default; + let optional_instance_bound = &def.optional_instance_bound; + let optional_instance = &def.optional_instance; + let name = &line.name; + + let struct_decl = quote!( + #( #[ #attrs ] )* + #visibility struct #name< + #optional_storage_runtime_bound_comma #optional_instance_bound_optional_default + >( + #scrate::rstd::marker::PhantomData< + (#optional_storage_runtime_comma #optional_instance) + > + ) #optional_storage_where_clause; + ); + + let from_query_to_optional_value = from_query_to_optional_value(line.is_option); + let from_optional_value_to_query = + from_optional_value_to_query(line.is_option, &line.default_value); + + let final_prefix = if let Some(instance) = def.module_instance.as_ref() { + let instance = &instance.instance_generic; + let const_name = syn::Ident::new( + &format!("{}{}", PREFIX_FOR, line.name.to_string()), proc_macro2::Span::call_site() + ); + quote!( #instance::#const_name.as_bytes() ) + } else { + let prefix = format!("{} {}", def.crate_name, line.name); + quote!( #prefix.as_bytes() ) + }; + + + let storage_generator_trait = &line.storage_generator_trait; + let storage_struct = &line.storage_struct; + let impl_trait = quote!( #optional_storage_runtime_bound_comma #optional_instance_bound ); + let value_type = &line.value_type; + let query_type = &line.query_type; + + let struct_impl = match &line.storage_type { + StorageLineTypeDef::Simple(_) => { + quote!( + impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct + #optional_storage_where_clause + { + type Query = #query_type; + + fn unhashed_key() -> &'static [u8] { + #final_prefix + } + + fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { + #from_optional_value_to_query + } + + fn from_query_to_optional_value(v: Self::Query) -> Option<#value_type> { + #from_query_to_optional_value + } + } + ) + }, + StorageLineTypeDef::Map(map) => { + let hasher = map.hasher.to_storage_hasher_struct(); + quote!( + impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct + #optional_storage_where_clause + { + type Query = #query_type; + type Hasher = #scrate::#hasher; + + fn prefix() -> &'static [u8] { + #final_prefix + } + + fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { + #from_optional_value_to_query + } + + fn from_query_to_optional_value(v: Self::Query) -> Option<#value_type> { + #from_query_to_optional_value + } + } + ) + }, + StorageLineTypeDef::LinkedMap(map) => { + let hasher = map.hasher.to_storage_hasher_struct(); + + // make sure to use different prefix for head and elements. + let head_key = if let Some(instance) = def.module_instance.as_ref() { + let instance = &instance.instance_generic; + let const_name = syn::Ident::new( + &format!("{}{}", HEAD_KEY_FOR, line.name.to_string()), proc_macro2::Span::call_site() + ); + quote!( #instance::#const_name.as_bytes() ) + } else { + let prefix = format!("head of {} {}", def.crate_name, line.name); + quote!( #prefix.as_bytes() ) + }; + + quote!( + impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct + #optional_storage_where_clause + { + type Query = #query_type; + type Hasher = #scrate::#hasher; + + fn prefix() -> &'static [u8] { + #final_prefix + } + + fn head_key() -> &'static [u8] { + #head_key + } + + fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { + #from_optional_value_to_query + } + + fn from_query_to_optional_value(v: Self::Query) -> Option<#value_type> { + #from_query_to_optional_value + } + } + ) + }, + StorageLineTypeDef::DoubleMap(map) => { + let hasher1 = map.hasher1.to_storage_hasher_struct(); + let hasher2 = map.hasher2.to_storage_hasher_struct(); + quote!( + impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct + #optional_storage_where_clause + { + type Query = #query_type; + + type Hasher1 = #scrate::#hasher1; + + type Hasher2 = #scrate::#hasher2; + + fn key1_prefix() -> &'static [u8] { + #final_prefix + } + + fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { + #from_optional_value_to_query + } + + fn from_query_to_optional_value(v: Self::Query) -> Option<#value_type> { + #from_query_to_optional_value + } + } + ) + } + }; + + impls.extend(quote!( + #struct_decl + #struct_impl + )) + } + + impls +} diff --git a/srml/support/procedural/src/storage/store_trait.rs b/srml/support/procedural/src/storage/store_trait.rs new file mode 100644 index 0000000000000000000000000000000000000000..4c9d96b6bb27a9ba644f5f559df9408a46139eb2 --- /dev/null +++ b/srml/support/procedural/src/storage/store_trait.rs @@ -0,0 +1,54 @@ +// 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 . + +//! Declaration of store trait and implementation on module structure. + +use proc_macro2::TokenStream; +use quote::quote; +use super::DeclStorageDefExt; + +pub fn decl_and_impl(def: &DeclStorageDefExt) -> TokenStream { + let decl_store_items = def.storage_lines.iter() + .map(|sline| &sline.name) + .fold(TokenStream::new(), |mut items, name| { + items.extend(quote!(type #name;)); + items + }); + + let impl_store_items = def.storage_lines.iter() + .fold(TokenStream::new(), |mut items, line| { + let name = &line.name; + let storage_struct = &line.storage_struct; + + items.extend(quote!(type #name = #storage_struct;)); + items + }); + + let visibility = &def.visibility; + let store_trait = &def.store_trait; + let module_struct = &def.module_struct; + let module_impl = &def.module_impl; + let where_clause = &def.where_clause; + + quote!( + #visibility trait #store_trait { + #decl_store_items + } + impl#module_impl #store_trait for #module_struct #where_clause { + #impl_store_items + } + ) +} diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs deleted file mode 100644 index d378907cb1e72fbc2af14dc66beac2340b477af9..0000000000000000000000000000000000000000 --- a/srml/support/procedural/src/storage/transformation.rs +++ /dev/null @@ -1,1232 +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 . - -//! `decl_storage` macro transformation - -use srml_support_procedural_tools::syn_ext as ext; -use srml_support_procedural_tools::{ - generate_crate_access, generate_hidden_includes, clean_type_string -}; - -use proc_macro::TokenStream; -use proc_macro2::{TokenStream as TokenStream2, Span}; - -use syn::{ - Ident, - GenericParam, - WhereClause, - spanned::Spanned, - parse::{ - Error, - Result, - }, - parse_macro_input, -}; -use quote::quote; - -use super::*; - -const NUMBER_OF_INSTANCE: usize = 16; -const DEFAULT_INSTANTIABLE_TRAIT_NAME: &str = "__GeneratedInstantiable"; -const DEFAULT_INSTANCE_NAME: &str = "__GeneratedInstance"; -const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance"; - -// try macro but returning tokenized error -macro_rules! try_tok(( $expre : expr ) => { - match $expre { - Ok(r) => r, - Err (err) => { - return err.to_compile_error().into() - } - } -}); - -pub fn decl_storage_impl(input: TokenStream) -> TokenStream { - let def = parse_macro_input!(input as StorageDefinition); - - let StorageDefinition { - hidden_crate, - visibility, - ident: storetype, - module_ident, - mod_param: strait, - mod_instance, - mod_instantiable, - mod_default_instance, - crate_ident: cratename, - content: ext::Braces { content: storage_lines, ..}, - extra_genesis, - where_clause, - .. - } = def; - - let instance_opts = match get_instance_opts( - mod_instance, - mod_instantiable, - mod_default_instance - ) { - Ok(opts) => opts, - Err(err) => return err.to_compile_error().into(), - }; - - let hidden_crate_name = hidden_crate.inner.map(|rc| rc.ident.content).map(|i| i.to_string()) - .unwrap_or_else(|| "decl_storage".to_string()); - let scrate = generate_crate_access(&hidden_crate_name, "srml-support"); - let scrate_decl = generate_hidden_includes( - &hidden_crate_name, - "srml-support", - ); - - let ( - traitinstance, - traittypes, - ) = if let GenericParam::Type(syn::TypeParam {ident, bounds, ..}) = strait { - (ident, bounds) - } else { - return try_tok!(Err(Error::new(strait.span(), "Missing declare store generic params"))); - }; - - let traittype = if let Some(traittype) = traittypes.first() { - traittype.into_value() - } else { - return try_tok!(Err(Error::new(traittypes.span(), "Trait bound expected"))); - }; - - let extra_genesis = try_tok!(decl_store_extra_genesis( - &scrate, - &traitinstance, - &traittype, - &instance_opts, - &storage_lines, - &extra_genesis.inner, - &where_clause, - )); - let decl_storage_items = decl_storage_items( - &scrate, - &traitinstance, - &traittype, - &instance_opts, - &cratename, - &storage_lines, - &where_clause, - ); - - let decl_store_items = decl_store_items( - &storage_lines, - ); - let impl_store_items = impl_store_items( - &traitinstance, - &instance_opts.instance, - &storage_lines, - ); - let impl_store_fns = impl_store_fns( - &scrate, - &traitinstance, - &instance_opts.instance, - &storage_lines, - ); - let (store_default_struct, store_metadata) = store_functions_to_metadata( - &scrate, - &traitinstance, - &traittype, - &instance_opts, - &storage_lines, - &where_clause, - &cratename, - ); - - let InstanceOpts { - instance, - bound_instantiable, - .. - } = instance_opts; - - let expanded = quote! { - #scrate_decl - #decl_storage_items - #visibility trait #storetype { - #decl_store_items - } - #store_default_struct - impl<#traitinstance: #traittype, #instance #bound_instantiable> #storetype - for #module_ident<#traitinstance, #instance> #where_clause - { - #impl_store_items - } - impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable> - #module_ident<#traitinstance, #instance> #where_clause - { - #impl_store_fns - #[doc(hidden)] - pub fn storage_metadata() -> #scrate::metadata::StorageMetadata { - #store_metadata - } - } - - #extra_genesis - }; - - expanded.into() -} - -fn decl_store_extra_genesis( - scrate: &TokenStream2, - traitinstance: &Ident, - traittype: &syn::TypeParamBound, - instance_opts: &InstanceOpts, - storage_lines: &ext::Punctuated, - extra_genesis: &Option, - where_clause: &Option, -) -> Result { - - let InstanceOpts { - equal_default_instance, - bound_instantiable, - instance, - .. - } = instance_opts; - - let mut is_trait_needed = false; - let mut serde_complete_bound = Vec::new(); - let mut config_field = TokenStream2::new(); - let mut config_field_default = TokenStream2::new(); - let mut builders = TokenStream2::new(); - let mut assimilate_require_generic = instance.is_some(); - let mut builders_clone_bound = Vec::new(); - - for sline in storage_lines.inner.iter() { - let DeclStorageLine { - attrs, - name, - getter, - config, - build, - storage_type, - default_value, - .. - } = sline; - - let type_infos = get_type_infos(storage_type); - - let opt_build = build - .inner - .as_ref() - .map(|b| { - assimilate_require_generic |= ext::expr_contains_ident(&b.expr.content, traitinstance); - &b.expr.content - }) - .map(|b| quote!( #b )); - - // need build line - let builder = if let Some(ref config) = config.inner { - let ident = if let Some(ident) = config.expr.content.as_ref() { - quote!( #ident ) - } else if let Some(ref getter) = getter.inner { - let ident = &getter.getfn.content; - quote!( #ident ) - } else { - return Err( - Error::new_spanned( - name, - "Invalid storage definiton, couldn't find config identifier: storage must either have a get identifier \ - `get(ident)` or a defined config identifier `config(ident)`" - ) - ); - }; - - if ext::type_contains_ident(type_infos.value_type, traitinstance) { - is_trait_needed = true; - } - - if opt_build.is_none() { - builders_clone_bound.push(type_infos.value_type.clone()); - } - - let value_type = &type_infos.value_type; - serde_complete_bound.push(quote!( #value_type )); - match type_infos.kind { - DeclStorageTypeInfosKind::Map { key_type, .. } => { - serde_complete_bound.push(quote!( #key_type )); - is_trait_needed = is_trait_needed - || ext::type_contains_ident(key_type, traitinstance); - - if opt_build.is_none() { - builders_clone_bound.push(key_type.clone()); - } - }, - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, .. } => { - serde_complete_bound.push(quote!( #key1_type )); - serde_complete_bound.push(quote!( #key2_type )); - is_trait_needed = is_trait_needed - || ext::type_contains_ident(key1_type, traitinstance) - || ext::type_contains_ident(key2_type, traitinstance); - if opt_build.is_none() { - builders_clone_bound.push(key1_type.clone()); - builders_clone_bound.push(key2_type.clone()); - } - }, - _ => {}, - } - - if type_infos.is_option { - serde_complete_bound.push(type_infos.typ.clone()); - } - - // Propagate doc attributes. - let attrs = attrs.inner.iter().filter_map(|a| a.parse_meta().ok()).filter(|m| m.name() == "doc"); - - let storage_type = type_infos.typ.clone(); - config_field.extend(match type_infos.kind { - DeclStorageTypeInfosKind::Simple => { - quote!( #( #[ #attrs ] )* pub #ident: #storage_type, ) - }, - DeclStorageTypeInfosKind::Map {key_type, .. } => { - quote!( #( #[ #attrs ] )* pub #ident: Vec<(#key_type, #storage_type)>, ) - }, - DeclStorageTypeInfosKind::DoubleMap {key1_type, key2_type, .. } => { - quote!( #( #[ #attrs ] )* pub #ident: Vec<(#key1_type, #key2_type, #storage_type)>, ) - }, - }); - - let fielddefault = default_value.inner.as_ref().map(|d| &d.expr).map(|d| - if type_infos.is_option { - quote!( #d.unwrap_or_default() ) - } else { - quote!( #d ) - }).unwrap_or_else(|| quote!( Default::default() )); - - config_field_default.extend(quote!( #ident: #fielddefault, )); - - opt_build.or_else(|| Some(quote!( (|config: &Self| config.#ident.clone()) ))) - } else { - opt_build - }; - - let typ = type_infos.typ; - if let Some(builder) = builder { - builders.extend(match type_infos.kind { - DeclStorageTypeInfosKind::Simple => { - let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) { - assimilate_require_generic = true; - quote!(#traitinstance,) - } else { - quote!() - }; - - quote!{{ - let v = (#builder)(&self); - < - #name<#struct_trait #instance> as - #scrate::storage::hashed::generator::StorageValue<#typ> - >::put(&v, storage); - }} - }, - DeclStorageTypeInfosKind::Map { key_type, .. } => { - let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) - || ext::type_contains_ident(key_type, traitinstance) - { - assimilate_require_generic = true; - quote!(#traitinstance,) - } else { - quote!() - }; - - 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); - }); - }} - }, - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, .. } => { - let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) - || ext::type_contains_ident(key1_type, traitinstance) - || ext::type_contains_ident(key2_type, traitinstance) - { - assimilate_require_generic = true; - quote!(#traitinstance,) - } else { - quote!() - }; - - quote!{{ - let data = (#builder)(&self); - 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); - }); - }} - }, - }); - } - } - - let mut has_scall = false; - let mut scall = quote!{ ( |_, _| {} ) }; - let mut genesis_extrafields = TokenStream2::new(); - let mut genesis_extrafields_default = TokenStream2::new(); - - // extra genesis - if let Some(eg) = extra_genesis { - for ex_content in eg.content.content.lines.inner.iter() { - match ex_content { - AddExtraGenesisLineEnum::AddExtraGenesisLine(AddExtraGenesisLine { - attrs, - extra_field, - extra_type, - default_value, - .. - }) => { - if ext::type_contains_ident(&extra_type, traitinstance) { - is_trait_needed = true; - } - - serde_complete_bound.push(quote!( #extra_type )); - - let extrafield = &extra_field.content; - genesis_extrafields.extend(quote!{ - #attrs pub #extrafield: #extra_type, - }); - let extra_default = default_value.inner.as_ref().map(|d| &d.expr).map(|e| quote!{ #e }) - .unwrap_or_else(|| quote!( Default::default() )); - genesis_extrafields_default.extend(quote!{ - #extrafield: #extra_default, - }); - }, - AddExtraGenesisLineEnum::AddExtraGenesisBuild(DeclStorageBuild{ expr, .. }) => { - if has_scall { - return Err(Error::new(expr.span(), "Only one build expression allowed for extra genesis")); - } - assimilate_require_generic |= ext::expr_contains_ident(&expr.content, traitinstance); - let content = &expr.content; - scall = quote!( ( #content ) ); - has_scall = true; - }, - } - } - } - - let serde_bug_bound = if !serde_complete_bound.is_empty() { - let mut b_ser = String::new(); - let mut b_dser = String::new(); - - serde_complete_bound.into_iter().for_each(|bound| { - let stype = quote!(#bound); - b_ser.push_str(&format!("{} : {}::serde::Serialize, ", stype, scrate)); - b_dser.push_str(&format!("{} : {}::serde::de::DeserializeOwned, ", stype, scrate)); - }); - - quote! { - #[serde(bound(serialize = #b_ser))] - #[serde(bound(deserialize = #b_dser))] - } - } else { - quote!() - }; - - let is_extra_genesis_needed = has_scall - || !config_field.is_empty() - || !genesis_extrafields.is_empty() - || !builders.is_empty(); - if is_extra_genesis_needed { - let (inherent_instance, inherent_bound_instantiable) = if instance.is_some() { - (instance.clone(), bound_instantiable.clone()) - } else { - let instantiable = Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site()); - ( - Some(Ident::new(DEFAULT_INSTANCE_NAME, Span::call_site())), - quote!(: #instantiable), - ) - }; - - let (fparam_struct, fparam_impl, sparam, build_storage_impl) = if is_trait_needed { - ( - quote!(<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>), - quote!(<#traitinstance: #traittype, #instance #bound_instantiable>), - quote!(<#traitinstance, #instance>), - quote!(<#traitinstance: #traittype, #inherent_instance #inherent_bound_instantiable>), - ) - } else { - // do not even need type parameter - ( - quote!(), - quote!(), - quote!(), - quote!(<#traitinstance: #traittype, #inherent_instance #inherent_bound_instantiable>), - ) - }; - - let (fn_generic, fn_traitinstance) = if !is_trait_needed && assimilate_require_generic { - ( - quote!( <#traitinstance: #traittype, #instance #bound_instantiable> ), - quote!( #traitinstance, #instance ) - ) - } else { - (quote!(), quote!()) - }; - - let impl_trait = quote!(BuildModuleGenesisStorage<#traitinstance, #inherent_instance>); - - let extend_where_clause = |to_extend: &mut WhereClause| { - if let Some(where_clause) = where_clause { - to_extend.predicates.extend(where_clause.predicates.iter().cloned()); - } - }; - - let mut genesis_where_clause: WhereClause = syn::parse_quote!( - where #( #builders_clone_bound: Clone ),* - ); - let mut fn_where_clause = genesis_where_clause.clone(); - - - let mut build_storage_where_clause = genesis_where_clause.clone(); - extend_where_clause(&mut build_storage_where_clause); - - if is_trait_needed { - extend_where_clause(&mut genesis_where_clause); - } else if assimilate_require_generic { - extend_where_clause(&mut fn_where_clause); - } - - let res = quote!{ - #[derive(#scrate::Serialize, #scrate::Deserialize)] - #[cfg(feature = "std")] - #[serde(rename_all = "camelCase")] - #[serde(deny_unknown_fields)] - #serde_bug_bound - pub struct GenesisConfig#fparam_struct #genesis_where_clause { - #config_field - #genesis_extrafields - } - - #[cfg(feature = "std")] - impl#fparam_impl Default for GenesisConfig#sparam #genesis_where_clause { - fn default() -> Self { - GenesisConfig { - #config_field_default - #genesis_extrafields_default - } - } - } - - #[cfg(feature = "std")] - impl#fparam_impl GenesisConfig#sparam #genesis_where_clause { - pub fn build_storage #fn_generic (self) -> std::result::Result< - ( - #scrate::sr_primitives::StorageOverlay, - #scrate::sr_primitives::ChildrenStorageOverlay, - ), - String - > #fn_where_clause { - let mut storage = (Default::default(), Default::default()); - self.assimilate_storage::<#fn_traitinstance>(&mut storage)?; - Ok(storage) - } - - /// Assimilate the storage for this module into pre-existing overlays. - pub fn assimilate_storage #fn_generic ( - self, - tuple_storage: &mut ( - #scrate::sr_primitives::StorageOverlay, - #scrate::sr_primitives::ChildrenStorageOverlay, - ), - ) -> std::result::Result<(), String> #fn_where_clause { - let storage = &mut tuple_storage.0; - - #builders - - #scall(tuple_storage, &self); - - Ok(()) - } - } - - #[cfg(feature = "std")] - impl#build_storage_impl #scrate::sr_primitives::#impl_trait - for GenesisConfig#sparam #build_storage_where_clause - { - fn build_module_genesis_storage( - self, - storage: &mut ( - #scrate::sr_primitives::StorageOverlay, - #scrate::sr_primitives::ChildrenStorageOverlay, - ), - ) -> std::result::Result<(), String> { - self.assimilate_storage::<#fn_traitinstance> (storage) - } - } - }; - - Ok(res) - } else { - Ok(quote!()) - } -} - -fn create_and_impl_instance( - instance_prefix: &str, - ident: &Ident, - doc: &TokenStream2, - const_names: &[(Ident, 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); - const_impls.extend(quote! { - const #const_name: &'static str = #const_value; - }); - } - - let prefix = format!("{}{}", instance_prefix, cratename.to_string()); - - quote! { - // Those trait are derived because of wrong bounds for generics - #[cfg_attr(feature = "std", derive(Debug))] - #[derive(Clone, Eq, PartialEq, #scrate::codec::Encode, #scrate::codec::Decode)] - #doc - pub struct #ident; - impl #instantiable for #ident { - const PREFIX: &'static str = #prefix; - #const_impls - } - } -} - -fn decl_storage_items( - scrate: &TokenStream2, - traitinstance: &Ident, - traittype: &syn::TypeParamBound, - instance_opts: &InstanceOpts, - cratename: &Ident, - storage_lines: &ext::Punctuated, - where_clause: &Option, -) -> TokenStream2 { - let mut impls = TokenStream2::new(); - - let InstanceOpts { - instance, - default_instance, - instantiable, - .. - } = instance_opts; - - let build_prefix = |cratename, name| format!("{} {}", cratename, name); - - // Build Instantiable trait - let mut const_names = vec![]; - - for sline in storage_lines.inner.iter() { - let DeclStorageLine { - storage_type, - name, - .. - } = sline; - - let prefix = build_prefix(cratename, name); - - let type_infos = get_type_infos(storage_type); - - 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)); - - 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)); - } - } - - let instantiable = instantiable - .clone() - .unwrap_or_else(|| Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site())); - - // Declare Instance trait - { - let mut const_impls = TokenStream2::new(); - for (const_name, _) in &const_names { - const_impls.extend(quote! { - const #const_name: &'static str; - }); - } - - let hide = if instance.is_some() { - quote!() - } else { - quote!(#[doc(hidden)]) - }; - - impls.extend(quote! { - /// Tag a type as an instance of a module. - /// - /// Defines storage prefixes, they must be unique. - #hide - pub trait #instantiable: 'static { - /// The prefix used by any storage entry of an instance. - const PREFIX: &'static str; - #const_impls - } - }); - } - - if instance.is_some() { - let instances = (0..NUMBER_OF_INSTANCE) - .map(|i| { - let name = format!("Instance{}", i); - let ident = Ident::new(&name, proc_macro2::Span::call_site()); - (name, ident, quote! {#[doc=r"Module instance"]}) - }) - .chain( - default_instance - .clone() - .map(|ident| - (String::new(), ident, quote! {#[doc=r"Default module instance"]}) - ) - ); - - // Impl Instance trait for instances - for (instance_prefix, ident, doc) in instances { - impls.extend( - create_and_impl_instance( - &instance_prefix, &ident, &doc, &const_names, scrate, &instantiable, cratename - ) - ); - } - } - - // The name of the inherently available instance. - let inherent_instance = Ident::new(INHERENT_INSTANCE_NAME, Span::call_site()); - - if default_instance.is_some() { - impls.extend(quote! { - #[doc(hidden)] - pub type #inherent_instance = #default_instance; - }); - } else { - impls.extend( - create_and_impl_instance( - "", - &inherent_instance, - "e!(#[doc(hidden)]), - &const_names, - scrate, - &instantiable, - cratename, - ) - ); - } - - for sline in storage_lines.inner.iter() { - let DeclStorageLine { - attrs, - name, - storage_type, - default_value, - visibility, - .. - } = sline; - - let type_infos = get_type_infos(storage_type); - 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"); - - let i = impls::Impls { - scrate, - visibility, - cratename, - traitinstance, - 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() }), - prefix: build_prefix(cratename, name), - name, - attrs, - where_clause, - }; - - let implementation = match kind { - DeclStorageTypeInfosKind::Simple => { - i.simple_value() - }, - DeclStorageTypeInfosKind::Map { key_type, is_linked: false, hasher } => { - i.map(hasher.into_storage_hasher_struct(), key_type) - }, - DeclStorageTypeInfosKind::Map { key_type, is_linked: true, hasher } => { - i.linked_map(hasher.into_storage_hasher_struct(), key_type) - }, - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher, hasher } => { - i.double_map(hasher.into_storage_hasher_struct(), key1_type, key2_type, key2_hasher.into_storage_hasher_struct()) - }, - }; - impls.extend(implementation) - } - impls -} - -fn decl_store_items(storage_lines: &ext::Punctuated) -> TokenStream2 { - storage_lines.inner.iter().map(|sline| &sline.name) - .fold(TokenStream2::new(), |mut items, name| { - items.extend(quote!(type #name;)); - items - }) -} - -fn impl_store_items( - traitinstance: &Ident, - instance: &Option, - storage_lines: &ext::Punctuated, -) -> TokenStream2 { - storage_lines.inner - .iter() - .fold(TokenStream2::new(), |mut items, line| { - let name = &line.name; - let type_infos = get_type_infos(&line.storage_type); - let requires_trait = match type_infos.kind { - DeclStorageTypeInfosKind::Simple => { - ext::type_contains_ident(&type_infos.value_type, traitinstance) - }, - DeclStorageTypeInfosKind::Map { key_type, .. } => { - ext::type_contains_ident(&type_infos.value_type, traitinstance) - || ext::type_contains_ident(key_type, traitinstance) - } - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, .. } => { - ext::type_contains_ident(&type_infos.value_type, traitinstance) - || ext::type_contains_ident(key1_type, traitinstance) - || ext::type_contains_ident(key2_type, traitinstance) - } - }; - - let struct_trait = if requires_trait { - quote!(#traitinstance,) - } else { - quote!() - }; - - items.extend( - quote!( - type #name = #name<#struct_trait #instance>; - ) - ); - items - }) -} - -fn impl_store_fns( - scrate: &TokenStream2, - traitinstance: &Ident, - instance: &Option, - storage_lines: &ext::Punctuated, -) -> TokenStream2 { - let mut items = TokenStream2::new(); - for sline in storage_lines.inner.iter() { - let DeclStorageLine { - attrs, - name, - getter, - storage_type, - .. - } = sline; - - if let Some(getter) = getter.inner.as_ref() { - let get_fn = &getter.getfn.content; - - let type_infos = get_type_infos(storage_type); - let value_type = type_infos.value_type; - - // Propagate doc attributes. - let attrs = attrs.inner.iter().filter_map(|a| a.parse_meta().ok()).filter(|m| m.name() == "doc"); - - let typ = type_infos.typ; - let item = match type_infos.kind { - DeclStorageTypeInfosKind::Simple => { - let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) { - quote!(#traitinstance,) - } else { - quote!() - }; - - quote!{ - #( #[ #attrs ] )* - pub fn #get_fn() -> #value_type { - <#name<#struct_trait #instance> as - #scrate::storage::hashed::generator::StorageValue<#typ>> :: get( - &#scrate::storage::RuntimeStorage - ) - } - } - }, - DeclStorageTypeInfosKind::Map { key_type, .. } => { - let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) - || ext::type_contains_ident(key_type, traitinstance) - { - quote!(#traitinstance,) - } else { - quote!() - }; - - quote!{ - #( #[ #attrs ] )* - 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) - } - } - } - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, .. } => { - let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) - || ext::type_contains_ident(key1_type, traitinstance) - || ext::type_contains_ident(key2_type, traitinstance) - { - quote!(#traitinstance,) - } else { - quote!() - }; - - quote!{ - 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, - { - < - #name<#struct_trait #instance> as - #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ> - >::get(k1, k2, &#scrate::storage::RuntimeStorage) - } - } - } - }; - items.extend(item); - } - } - items -} - -fn store_functions_to_metadata ( - scrate: &TokenStream2, - traitinstance: &Ident, - traittype: &syn::TypeParamBound, - instance_opts: &InstanceOpts, - storage_lines: &ext::Punctuated, - where_clause: &Option, - cratename: &Ident, -) -> (TokenStream2, TokenStream2) { - let InstanceOpts { - comma_instance, - equal_default_instance, - bound_instantiable, - instance, - .. - } = instance_opts; - - let mut items = TokenStream2::new(); - let mut default_getter_struct_def = TokenStream2::new(); - for sline in storage_lines.inner.iter() { - let DeclStorageLine { - attrs, - name, - storage_type, - default_value, - .. - } = sline; - - let type_infos = get_type_infos(storage_type); - let value_type = type_infos.value_type; - - let typ = type_infos.typ; - let styp = clean_type_string(&typ.to_string()); - let stype = match type_infos.kind { - DeclStorageTypeInfosKind::Simple => { - quote!{ - #scrate::metadata::StorageEntryType::Plain( - #scrate::metadata::DecodeDifferent::Encode(#styp), - ) - } - }, - DeclStorageTypeInfosKind::Map { key_type, is_linked, hasher } => { - let hasher = hasher.into_metadata(); - let kty = clean_type_string("e!(#key_type).to_string()); - quote!{ - #scrate::metadata::StorageEntryType::Map { - hasher: #scrate::metadata::#hasher, - key: #scrate::metadata::DecodeDifferent::Encode(#kty), - value: #scrate::metadata::DecodeDifferent::Encode(#styp), - is_linked: #is_linked, - } - } - }, - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher, hasher } => { - let hasher = hasher.into_metadata(); - let k1ty = clean_type_string("e!(#key1_type).to_string()); - let k2ty = clean_type_string("e!(#key2_type).to_string()); - let k2_hasher = key2_hasher.into_metadata(); - quote!{ - #scrate::metadata::StorageEntryType::DoubleMap { - hasher: #scrate::metadata::#hasher, - key1: #scrate::metadata::DecodeDifferent::Encode(#k1ty), - key2: #scrate::metadata::DecodeDifferent::Encode(#k2ty), - value: #scrate::metadata::DecodeDifferent::Encode(#styp), - key2_hasher: #scrate::metadata::#k2_hasher, - } - } - }, - }; - let modifier = if type_infos.is_option { - quote!{ - #scrate::metadata::StorageEntryModifier::Optional - } - } else { - quote!{ - #scrate::metadata::StorageEntryModifier::Default - } - }; - let default = default_value.inner.as_ref().map(|d| &d.expr) - .map(|d| { - quote!( #d ) - }) - .unwrap_or_else(|| quote!( Default::default() )); - let mut docs = TokenStream2::new(); - for attr in attrs.inner.iter().filter_map(|v| v.parse_meta().ok()) { - if let syn::Meta::NameValue(syn::MetaNameValue{ - ref ident, - ref lit, - .. - }) = attr { - if ident == "doc" { - docs.extend(quote!(#lit,)); - } - } - } - let str_name = name.to_string(); - let struct_name = proc_macro2::Ident::new(&("__GetByteStruct".to_string() + &str_name), name.span()); - let cache_name = proc_macro2::Ident::new(&("__CACHE_GET_BYTE_STRUCT_".to_string() + &str_name), name.span()); - - let item = quote! { - #scrate::metadata::StorageEntryMetadata { - name: #scrate::metadata::DecodeDifferent::Encode(#str_name), - modifier: #modifier, - ty: #stype, - default: #scrate::metadata::DecodeDifferent::Encode( - #scrate::metadata::DefaultByteGetter( - &#struct_name::<#traitinstance, #instance>(#scrate::rstd::marker::PhantomData) - ) - ), - documentation: #scrate::metadata::DecodeDifferent::Encode(&[ #docs ]), - }, - }; - items.extend(item); - - let def_get = quote! { - #[doc(hidden)] - pub struct #struct_name< - #traitinstance, #instance #bound_instantiable #equal_default_instance - >(pub #scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>); - - #[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; - - #[cfg(feature = "std")] - impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::metadata::DefaultByte - for #struct_name<#traitinstance, #instance> #where_clause - { - fn default_byte(&self) -> #scrate::rstd::vec::Vec { - use #scrate::codec::Encode; - #cache_name.get_or_init(|| { - let def_val: #value_type = #default; - <#value_type as Encode>::encode(&def_val) - }).clone() - } - } - - unsafe impl<#traitinstance: #traittype, #instance #bound_instantiable> Send - for #struct_name<#traitinstance, #instance> #where_clause {} - - unsafe impl<#traitinstance: #traittype, #instance #bound_instantiable> Sync - for #struct_name<#traitinstance, #instance> #where_clause {} - - #[cfg(not(feature = "std"))] - impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::metadata::DefaultByte - for #struct_name<#traitinstance, #instance> #where_clause - { - fn default_byte(&self) -> #scrate::rstd::vec::Vec { - use #scrate::codec::Encode; - let def_val: #value_type = #default; - <#value_type as Encode>::encode(&def_val) - } - } - }; - - default_getter_struct_def.extend(def_get); - } - - let prefix = cratename.to_string(); - let prefix = instance.as_ref().map_or_else(|| quote!(#prefix), |i| quote!(#i::PREFIX)); - - (default_getter_struct_def, quote!{ - #scrate::metadata::StorageMetadata { - prefix: #scrate::metadata::DecodeDifferent::Encode(#prefix), - entries: #scrate::metadata::DecodeDifferent::Encode(&[ #items ][..]), - } - }) -} - - -#[derive(Debug, Clone)] -pub(crate) struct DeclStorageTypeInfos<'a> { - pub is_option: bool, - pub typ: TokenStream2, - pub value_type: &'a syn::Type, - kind: DeclStorageTypeInfosKind<'a>, -} - -#[derive(Debug, Clone)] -enum DeclStorageTypeInfosKind<'a> { - Simple, - Map { - hasher: HasherKind, - key_type: &'a syn::Type, - is_linked: bool, - }, - DoubleMap { - hasher: HasherKind, - key1_type: &'a syn::Type, - key2_type: &'a syn::Type, - key2_hasher: HasherKind, - } -} - -fn get_type_infos(storage_type: &DeclStorageType) -> DeclStorageTypeInfos { - let (value_type, kind) = match storage_type { - DeclStorageType::Simple(ref st) => (st, DeclStorageTypeInfosKind::Simple), - DeclStorageType::Map(ref map) => (&map.value, DeclStorageTypeInfosKind::Map { - hasher: map.hasher.inner.as_ref().map(|h| h.into()).unwrap_or(HasherKind::Blake2_256), - key_type: &map.key, - is_linked: false, - }), - DeclStorageType::LinkedMap(ref map) => (&map.value, DeclStorageTypeInfosKind::Map { - hasher: map.hasher.inner.as_ref().map(|h| h.into()).unwrap_or(HasherKind::Blake2_256), - key_type: &map.key, - is_linked: true, - }), - DeclStorageType::DoubleMap(ref map) => (&map.value, DeclStorageTypeInfosKind::DoubleMap { - hasher: map.hasher.inner.as_ref().map(|h| h.into()).unwrap_or(HasherKind::Blake2_256), - key1_type: &map.key1, - key2_type: &map.key2.content, - key2_hasher: (&map.key2_hasher).into(), - }), - }; - - let extracted_type = ext::extract_type_option(value_type); - let is_option = extracted_type.is_some(); - let typ = extracted_type.unwrap_or(quote!( #value_type )); - - DeclStorageTypeInfos { - is_option, - typ, - value_type, - kind, - } - -} - -#[derive(Default)] -pub(crate) struct InstanceOpts { - pub instance: Option, - pub default_instance: Option, - pub instantiable: Option, - pub comma_instance: TokenStream2, - pub equal_default_instance: TokenStream2, - pub bound_instantiable: TokenStream2, -} - -fn get_instance_opts( - instance: Option, - instantiable: Option, - default_instance: Option, -) -> Result { - let right_syntax = "Should be $Instance: $Instantiable = $DefaultInstance"; - - match (instance, instantiable, default_instance) { - (Some(instance), Some(instantiable), default_instance) => { - let (equal_default_instance, default_instance) = if let Some(def) = default_instance { - (quote!{= #def}, Some(def)) - } else { - (quote!(), None) - }; - - Ok(InstanceOpts { - comma_instance: quote!{, #instance}, - equal_default_instance, - bound_instantiable: quote!{: #instantiable}, - instance: Some(instance), - default_instance, - instantiable: Some(instantiable), - }) - }, - (None, None, None) => Ok(Default::default()), - (Some(instance), None, _) => Err( - Error::new( - instance.span(), - format!( - "Expect instantiable trait bound for instance: {}. {}", - instance, - right_syntax, - ) - ) - ), - (None, Some(instantiable), _) => Err( - Error::new( - instantiable.span(), - format!( - "Expect instance generic for bound instantiable: {}. {}", - instantiable, - right_syntax, - ) - ) - ), - (None, _, Some(default_instance)) => Err( - Error::new( - default_instance.span(), - format!( - "Expect instance generic for default instance: {}. {}", - default_instance, - right_syntax, - ) - ) - ), - } -} 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/procedural/tools/src/syn_ext.rs b/srml/support/procedural/tools/src/syn_ext.rs index 1033ebcce2de5b7da84e3d7ebc21bc0220ae4bfe..1658a6b4aea25caabe196066885b6b5c82202af4 100644 --- a/srml/support/procedural/tools/src/syn_ext.rs +++ b/srml/support/procedural/tools/src/syn_ext.rs @@ -184,13 +184,15 @@ impl ToTokens for Opt

{ } } -pub fn extract_type_option(typ: &syn::Type) -> Option { +pub fn extract_type_option(typ: &syn::Type) -> Option { if let syn::Type::Path(ref path) = typ { let v = path.path.segments.last()?; if v.value().ident == "Option" { - if let syn::PathArguments::AngleBracketed(ref a) = v.value().arguments { - let args = &a.args; - return Some(quote!{ #args }) + // Option has only one type argument in angle bracket. + if let syn::PathArguments::AngleBracketed(a) = &v.value().arguments { + if let syn::GenericArgument::Type(typ) = a.args.last()?.value() { + return Some(typ.clone()) + } } } } @@ -253,4 +255,4 @@ pub fn expr_contains_ident(expr: &syn::Expr, ident: &Ident) -> bool { visit::visit_expr(&mut visit, expr); visit.result -} \ No newline at end of file +} diff --git a/srml/support/src/debug.rs b/srml/support/src/debug.rs new file mode 100644 index 0000000000000000000000000000000000000000..1c4e463bf1234bbd98aba63415d85add5db97dff --- /dev/null +++ b/srml/support/src/debug.rs @@ -0,0 +1,209 @@ +// 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 debugging and logging utilities. +//! +//! This module contains macros and functions that will allow +//! you to print logs out of the runtime code. +//! +//! First and foremost be aware that adding regular logging code to +//! your runtime will have a negative effect on the performance +//! and size of the blob. Luckily there are some ways to mitigate +//! this that are described below. +//! +//! First component to utilize debug-printing and loggin is actually +//! located in `primitives` crate: `primitives::RuntimeDebug`. +//! This custom-derive generates `core::fmt::Debug` implementation, +//! just like regular `derive(Debug)`, however it does not generate +//! any code when the code is compiled to WASM. This means that +//! you can safely sprinkle `RuntimeDebug` in your runtime codebase, +//! without affecting the size. This also allows you to print/log +//! both when the code is running natively or in WASM, but note +//! that WASM debug formatting of structs will be empty. +//! +//! ```rust,no_run +//! use srml_support::debug; +//! +//! #[derive(primitives::RuntimeDebug)] +//! struct MyStruct { +//! a: u64, +//! } +//! +//! // First initialize the logger. +//! // +//! // This is only required when you want the logs to be printed +//! // also during non-native run. +//! // Note that enabling the logger has performance impact on +//! // WASM runtime execution and should be used sparingly. +//! debug::RuntimeLogger::init(); +//! +//! let x = MyStruct { a: 5 }; +//! // will log an info line `"My struct: MyStruct{a:5}"` when running +//! // natively, but will only print `"My struct: "` when running WASM. +//! debug::info!("My struct: {:?}", x); +//! +//! // same output here, although this will print to stdout +//! // (and without log format) +//! debug::print!("My struct: {:?}", x); +//! ``` +//! +//! If you want to avoid extra overhead in WASM, but still be able +//! to print / log when the code is executed natively you can use +//! macros coming from `native` sub-module. This module enables +//! logs conditionally and strips out logs in WASM. +//! +//! ```rust,no_run +//! use srml_support::debug::native; +//! +//! #[derive(primitives::RuntimeDebug)] +//! struct MyStruct { +//! a: u64, +//! } +//! +//! // We don't initialize the logger, since +//! // we are not printing anything out in WASM. +//! // debug::RuntimeLogger::init(); +//! +//! let x = MyStruct { a: 5 }; +//! +//! // Displays an info log when running natively, nothing when WASM. +//! native::info!("My struct: {:?}", x); +//! +//! // same output to stdout, no overhead on WASM. +//! native::print!("My struct: {:?}", x); +//! ``` + +use rstd::vec::Vec; +use rstd::fmt::{self, Debug}; + +pub use log::{info, debug, error, trace, warn}; +pub use crate::runtime_print as print; + +/// Native-only logging. +/// +/// Using any functions from this module will have any effect +/// only if the runtime is running natively (i.e. not via WASM) +#[cfg(feature = "std")] +pub mod native { + pub use super::{info, debug, error, trace, warn, print}; +} + +/// Native-only logging. +/// +/// Using any functions from this module will have any effect +/// only if the runtime is running natively (i.e. not via WASM) +#[cfg(not(feature = "std"))] +pub mod native { + #[macro_export] + macro_rules! noop { + ($($arg:tt)+) => {} + } + pub use noop as info; + pub use noop as debug; + pub use noop as error; + pub use noop as trace; + pub use noop as warn; + pub use noop as print; +} + +/// Print out a formatted message. +#[macro_export] +macro_rules! runtime_print { + ($($arg:tt)+) => { + use core::fmt::Write; + let mut w = $crate::debug::Writer::default(); + let _ = core::write!(&mut w, $($arg)+); + w.print(); + } +} + +/// Print out the debuggable type. +pub fn debug(data: &impl Debug) { + runtime_print!("{:?}", data); +} + +/// A target for `core::write!` macro - constructs a string in memory. +#[derive(Default)] +pub struct Writer(Vec); + +impl fmt::Write for Writer { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.0.extend(s.as_bytes()); + Ok(()) + } +} + +impl Writer { + /// Print the content of this `Writer` out. + pub fn print(&self) { + runtime_io::print_utf8(&self.0) + } +} + +/// Runtime logger implementation - `log` crate backend. +/// +/// The logger should be initialized if you want to display +/// logs inside the runtime that is not necessarily running natively. +/// +/// When runtime is executed natively any log statements are displayed +/// even if this logger is NOT initialized. +/// +/// Note that even though the logs are not displayed in WASM, they +/// may still affect the size and performance of the generated runtime. +/// To lower the footprint make sure to only use macros from `native` +/// sub-module. +pub struct RuntimeLogger; + +impl RuntimeLogger { + /// Initialize the logger. + /// + /// This is a no-op when running natively (`std`). + #[cfg(feature = "std")] + pub fn init() {} + + /// Initialize the logger. + /// + /// This is a no-op when running natively (`std`). + #[cfg(not(feature = "std"))] + pub fn init() { + static LOGGER: RuntimeLogger = RuntimeLogger;; + let _ = log::set_logger(&LOGGER); + } +} + +impl log::Log for RuntimeLogger { + fn enabled(&self, _metadata: &log::Metadata) -> bool { + // to avoid calling to host twice, we pass everything + // and let the host decide what to print. + // If someone is initializing the logger they should + // know what they are doing. + true + } + + fn log(&self, record: &log::Record) { + use fmt::Write; + let mut w = Writer::default(); + let _ = core::write!(&mut w, "{}", record.args()); + + runtime_io::log( + record.level().into(), + record.target().as_bytes(), + &w.0, + ); + } + + fn flush(&self) {} +} diff --git a/srml/support/src/dispatch.rs b/srml/support/src/dispatch.rs index d77da619a9c8265ca7d23ea181ea4bb9ed1cc48f..df86f436117a1bf7c66508bb26a56251473bacbb 100644 --- a/srml/support/src/dispatch.rs +++ b/srml/support/src/dispatch.rs @@ -17,26 +17,26 @@ //! Dispatch system. Contains a macro for defining runtime modules and //! generating values representing lazy module function calls. -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::rstd::{result, fmt, prelude::{Vec, Clone, Eq, PartialEq}, marker}; +pub use crate::codec::{Codec, EncodeLike, Decode, Encode, Input, Output, HasCompact, EncodeAsRef}; pub use srml_metadata::{ FunctionMetadata, DecodeDifferent, DecodeDifferentArray, FunctionArgumentMetadata, - ModuleConstantMetadata, DefaultByte, DefaultByteGetter, + ModuleConstantMetadata, DefaultByte, DefaultByteGetter, ModuleErrorMetadata, ErrorMetadata }; -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. @@ -48,17 +48,8 @@ pub trait Callable { // https://github.com/rust-lang/rust/issues/51331 pub type CallableCallFor = >::Call; -#[cfg(feature = "std")] -pub trait Parameter: Codec + Clone + Eq + fmt::Debug {} - -#[cfg(feature = "std")] -impl Parameter for T where T: Codec + Clone + Eq + fmt::Debug {} - -#[cfg(not(feature = "std"))] -pub trait Parameter: Codec + Clone + Eq {} - -#[cfg(not(feature = "std"))] -impl Parameter for T where T: Codec + Clone + Eq {} +pub trait Parameter: Codec + EncodeLike + Clone + Eq + fmt::Debug {} +impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// Declares a `Module` struct and a `Call` enum, which implements the dispatch logic. /// @@ -203,7 +194,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: /// @@ -239,6 +230,7 @@ macro_rules! decl_module { {} {} {} + {} [] $($t)* ); @@ -270,6 +262,7 @@ macro_rules! decl_module { {} {} {} + {} [] $($t)* ); @@ -286,9 +279,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 @@ -296,11 +290,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)* ); @@ -315,25 +310,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 @@ -346,9 +330,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 @@ -361,6 +346,7 @@ macro_rules! decl_module { { fn on_finalize( $( $param_name : $param ),* ) { $( $impl )* } } { $( $offchain )* } { $( $constants )* } + { $( $error_type )* } [ $( $dispatchables )* ] $($rest)* ); @@ -375,9 +361,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 @@ -390,6 +377,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { $( $offchain )* } { $( $constants )* } + { $( $error_type )* } [ $( $dispatchables )* ] $($rest)* ); @@ -407,9 +395,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 @@ -424,6 +413,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { fn offchain_worker( $( $param_name : $param ),* ) { $( $impl )* } } { $( $constants )* } + { $( $error_type )* } [ $( $dispatchables )* ] $($rest)* ); @@ -443,6 +433,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; @@ -465,10 +456,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 @@ -484,11 +549,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)* ) => { @@ -504,6 +570,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { $( $offchain )* } { $( $constants )* } + { $error_type } [ $( $dispatchables )* $(#[doc = $doc_attr])* @@ -530,10 +597,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)* ) => { @@ -549,6 +617,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { $( $offchain )* } { $( $constants )* } + { $( $error_type )* } [ $( $dispatchables )* ] $(#[doc = $doc_attr])* #[weight = $crate::dispatch::SimpleDispatchInfo::default()] @@ -569,11 +638,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)* ) => { @@ -593,11 +663,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)* ) => { @@ -617,11 +688,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)* ) => { @@ -642,6 +714,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] ) => { $crate::decl_module!(@imp @@ -656,6 +729,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { $( $offchain )* } { $( $constants )* } + { $( $error_type )* } ); }; @@ -685,25 +759,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()) } } }; @@ -821,6 +880,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 ( @@ -831,7 +891,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(()) @@ -842,6 +902,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 ( @@ -996,12 +1057,12 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $error_type:ty } ) => { $crate::__check_reserved_fn_name! { $( $fn_name )* } // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, Copy, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive(Clone, Copy, PartialEq, Eq, $crate::RuntimeDebug)] pub struct $mod_type< $trait_instance: $trait_name $(, $instance: $instantiable $( = $module_default_instance)?)? @@ -1047,6 +1108,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 ( @@ -1151,7 +1213,6 @@ macro_rules! decl_module { for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )* {} - #[cfg(feature = "std")] impl<$trait_instance: $trait_name $(, $instance: $instantiable)?> $crate::dispatch::fmt::Debug for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )* { @@ -1177,7 +1238,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 ),* ) => { @@ -1204,8 +1266,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) } } @@ -1225,6 +1287,14 @@ macro_rules! decl_module { { $( $other_where_bounds )* } $( $constants )* } + + impl<$trait_instance: $trait_name $(, $instance: $instantiable)?> $crate::dispatch::ModuleErrorMetadata + for $mod_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )* + { + fn metadata() -> &'static [$crate::dispatch::ErrorMetadata] { + <$error_type as $crate::dispatch::ModuleErrorMetadata>::metadata() + } + } } } @@ -1244,8 +1314,12 @@ macro_rules! impl_outer_dispatch { } ) => { $(#[$attr])* - #[derive(Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive( + Clone, PartialEq, Eq, + $crate::codec::Encode, + $crate::codec::Decode, + $crate::RuntimeDebug, + )] pub enum $call_type { $( $camelcase ( $crate::dispatch::CallableCallFor<$camelcase, $runtime> ) @@ -1261,9 +1335,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 ),* } } } @@ -1285,6 +1369,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 )* + } } } @@ -1610,19 +1731,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..9aa13713daafb7f418cd82efee587613e0841d32 --- /dev/null +++ b/srml/support/src/error.rs @@ -0,0 +1,166 @@ +// 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; +pub use srml_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent}; + +/// 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 { + $( + $( #[doc = $doc_attr:tt] )* + $name:ident + ),* + $(,)? + } + ) => { + #[derive(Clone, PartialEq, Eq, $crate::RuntimeDebug)] + $(#[$attr])* + pub enum $error { + Other(&'static str), + CannotLookup, + $( + $( #[doc = $doc_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())) + } + } + + impl $crate::error::ModuleErrorMetadata for $error { + fn metadata() -> &'static [$crate::error::ErrorMetadata] { + &[ + $( + $crate::error::ErrorMetadata { + name: $crate::error::DecodeDifferent::Encode(stringify!($name)), + documentation: $crate::error::DecodeDifferent::Encode(&[ + $( $doc_attr ),* + ]), + } + ),* + ] + } + } + }; + (@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..3411c93922e2b08c034171d117adaa69cce989a3 100644 --- a/srml/support/src/event.rs +++ b/srml/support/src/event.rs @@ -121,8 +121,12 @@ macro_rules! decl_event { } ) => { // 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))] + #[derive( + Clone, PartialEq, Eq, + $crate::codec::Encode, + $crate::codec::Decode, + $crate::RuntimeDebug, + )] /// Events for this module. /// $(#[$attr])* @@ -260,9 +264,12 @@ macro_rules! __decl_generic_event { /// [`Trait`]: trait.Trait.html pub type Event<$event_generic_param $(, $instance $( = $event_default_instance)? )?> = RawEvent<$( $generic_type ),* $(, $instance)? >; - // 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))] + #[derive( + Clone, PartialEq, Eq, + $crate::codec::Encode, + $crate::codec::Decode, + $crate::RuntimeDebug, + )] /// Events for this module. /// $(#[$attr])* @@ -452,31 +459,48 @@ 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, + $crate::RuntimeDebug, + )] + $(#[$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..cbd78f603241eb5746045be59f6c4f462af77b49 --- /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) + .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..2a9f66bd526e2f48dd3caa759f54a707b4b04717 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,21 @@ pub use codec; pub use once_cell; #[doc(hidden)] pub use paste; +#[cfg(feature = "std")] +#[doc(hidden)] +pub use runtime_io::with_storage; +#[doc(hidden)] +pub use runtime_io::storage_root; +#[doc(hidden)] +pub use sr_primitives::RuntimeDebug; -pub use self::storage::hashed::generator::{ - HashedStorage, Twox256, Twox128, Blake2_256, Blake2_128, Twox64Concat -}; -pub use self::storage::unhashed::generator::UnhashedStorage; - +#[macro_use] +pub mod debug; #[macro_use] pub mod dispatch; #[macro_use] pub mod storage; -mod hashable; +mod hash; #[macro_use] pub mod event; #[macro_use] @@ -58,17 +62,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 +131,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 +145,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 +165,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)); } } @@ -173,10 +177,10 @@ macro_rules! assert_err { #[macro_export] #[cfg(feature = "std")] macro_rules! assert_ok { - ( $x:expr ) => { + ( $x:expr $(,)? ) => { assert_eq!($x, Ok(())); }; - ( $x:expr, $y:expr ) => { + ( $x:expr, $y:expr $(,)? ) => { assert_eq!($x, Ok($y)); } } @@ -222,75 +226,27 @@ 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)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Eq, PartialEq, RuntimeDebug)] pub enum Void {} #[cfg(feature = "std")] #[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}; - pub use srml_metadata::{ + use codec::{Codec, EncodeLike}; + use srml_metadata::{ DecodeDifferent, StorageEntryMetadata, StorageMetadata, StorageEntryType, - StorageEntryModifier, DefaultByte, DefaultByteGetter, StorageHasher + StorageEntryModifier, DefaultByteGetter, StorageHasher, }; - pub use rstd::marker::PhantomData; + use rstd::marker::PhantomData; pub trait Trait { - type BlockNumber: Codec + Default; + type BlockNumber: Codec + EncodeLike + Default; type Origin; } @@ -307,10 +263,11 @@ mod tests { decl_storage! { trait Store for Module as Example { - pub Data get(data) build(|_| vec![(15u32, 42u64)]): linked_map hasher(twox_64_concat) u32 => u64; + pub Data get(fn data) build(|_| vec![(15u32, 42u64)]): linked_map hasher(twox_64_concat) u32 => u64; pub OptionLinkedMap: linked_map u32 => Option; - pub GenericData get(generic_data): linked_map hasher(twox_128) T::BlockNumber => T::BlockNumber; - pub GenericData2 get(generic_data2): linked_map T::BlockNumber => Option; + pub GenericData get(fn generic_data): linked_map hasher(twox_128) T::BlockNumber => T::BlockNumber; + pub GenericData2 get(fn generic_data2): linked_map T::BlockNumber => Option; + pub GetterNoFnKeyword get(no_fn): Option; pub DataDM config(test_config) build(|_| vec![(15u32, 16u32, 42u64)]): double_map hasher(twox_64_concat) u32, blake2_256(u32) => u64; @@ -326,7 +283,7 @@ mod tests { type Origin = u32; } - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { GenesisConfig::default().build_storage().unwrap().into() } @@ -334,7 +291,7 @@ mod tests { #[test] fn linked_map_issue_3318() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { OptionLinkedMap::insert(1, 1); assert_eq!(OptionLinkedMap::get(1), Some(1)); OptionLinkedMap::insert(1, 2); @@ -342,9 +299,38 @@ mod tests { }); } + #[test] + fn linked_map_swap_works() { + new_test_ext().execute_with(|| { + 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(), || { + new_test_ext().execute_with(|| { // initialized during genesis assert_eq!(Map::get(&15u32), 42u64); @@ -370,7 +356,7 @@ mod tests { #[test] fn linked_map_enumeration_and_head_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Map::head(), Some(15)); assert_eq!(Map::enumerate().collect::>(), vec![(15, 42)]); // insert / remove @@ -422,7 +408,7 @@ mod tests { #[test] fn double_map_basic_insert_remove_remove_prefix_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { type DoubleMap = DataDM; // initialized during genesis assert_eq!(DoubleMap::get(&15u32, &16u32), 42u64); @@ -462,7 +448,7 @@ mod tests { #[test] fn double_map_append_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { type DoubleMap = AppendableDM; let key1 = 17u32; @@ -534,6 +520,15 @@ mod tests { ), documentation: DecodeDifferent::Encode(&[]), }, + StorageEntryMetadata { + name: DecodeDifferent::Encode("GetterNoFnKeyword"), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructGetterNoFnKeyword(PhantomData::)) + ), + documentation: DecodeDifferent::Encode(&[]), + }, StorageEntryMetadata { name: DecodeDifferent::Encode("DataDM"), modifier: StorageEntryModifier::Default, diff --git a/srml/support/src/metadata.rs b/srml/support/src/metadata.rs index 4bc1f906dad55821f6e8326d31177d582849fc33..a223a14f9e4050e64fe559804769b073f211154c 100644 --- a/srml/support/src/metadata.rs +++ b/srml/support/src/metadata.rs @@ -17,7 +17,7 @@ pub use srml_metadata::{ DecodeDifferent, FnEncode, RuntimeMetadata, ModuleMetadata, RuntimeMetadataLastVersion, DefaultByteGetter, RuntimeMetadataPrefixed, StorageEntryMetadata, StorageMetadata, - StorageEntryType, StorageEntryModifier, DefaultByte, StorageHasher + StorageEntryType, StorageEntryModifier, DefaultByte, StorageHasher, ModuleErrorMetadata }; /// Implements the metadata support for the given runtime and all its modules. @@ -96,6 +96,11 @@ macro_rules! __runtime_modules_to_metadata { $crate::metadata::FnEncode( $mod::$module::<$runtime $(, $mod::$instance )?>::module_constants_metadata ) + ), + errors: $crate::metadata::DecodeDifferent::Encode( + $crate::metadata::FnEncode( + <$mod::$module::<$runtime $(, $mod::$instance )?> as $crate::metadata::ModuleErrorMetadata>::metadata + ) ) }; $( $rest )* @@ -227,6 +232,7 @@ mod tests { use srml_metadata::{ EventMetadata, StorageEntryModifier, StorageEntryType, FunctionMetadata, StorageEntryMetadata, ModuleMetadata, RuntimeMetadataPrefixed, DefaultByte, ModuleConstantMetadata, DefaultByteGetter, + ErrorMetadata, }; use codec::{Encode, Decode}; use crate::traits::Get; @@ -278,7 +284,7 @@ mod tests { } mod event_module { - use crate::dispatch::Result; + use crate::dispatch::DispatchResult; pub trait Trait { type Origin; @@ -296,7 +302,19 @@ mod tests { decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn aux_0(_origin) -> Result { unreachable!() } + type Error = Error; + + fn aux_0(_origin) -> DispatchResult { unreachable!() } + } + } + + crate::decl_error! { + pub enum Error { + /// Some user input error + UserInputError, + /// Something bad happened + /// this could be due to many reasons + BadThingHappened, } } } @@ -324,7 +342,7 @@ mod tests { StorageMethod : Option; } add_extra_genesis { - build(|_, _| {}); + build(|_| {}); } } } @@ -447,6 +465,7 @@ mod tests { } ]) ), + errors: DecodeDifferent::Encode(FnEncode(|| &[])), }, ModuleMetadata { name: DecodeDifferent::Encode("Module"), @@ -469,6 +488,19 @@ mod tests { ]) )), constants: DecodeDifferent::Encode(FnEncode(|| &[])), + errors: DecodeDifferent::Encode(FnEncode(|| &[ + ErrorMetadata { + name: DecodeDifferent::Encode("UserInputError"), + documentation: DecodeDifferent::Encode(&[" Some user input error"]), + }, + ErrorMetadata { + name: DecodeDifferent::Encode("BadThingHappened"), + documentation: DecodeDifferent::Encode(&[ + " Something bad happened", + " this could be due to many reasons", + ]), + }, + ])), }, ModuleMetadata { name: DecodeDifferent::Encode("Module2"), @@ -505,6 +537,7 @@ mod tests { ]) )), constants: DecodeDifferent::Encode(FnEncode(|| &[])), + errors: DecodeDifferent::Encode(FnEncode(|| &[])), }, ]) }; diff --git a/srml/support/src/origin.rs b/srml/support/src/origin.rs index f3fec6e3ae6ce16909abd27487262923e8286ee2..6da9bc13858364f42aa9ab58ac750802b8588157 100644 --- a/srml/support/src/origin.rs +++ b/srml/support/src/origin.rs @@ -151,9 +151,7 @@ macro_rules! impl_outer_origin { $( $module:ident $( < $generic:ident > )? $( { $generic_instance:ident } )? ,)* ) => { $crate::paste::item! { - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive(Clone, PartialEq, Eq, $crate::RuntimeDebug)] $(#[$attr])* #[allow(non_camel_case_types)] pub enum $name { diff --git a/srml/support/src/runtime.rs b/srml/support/src/runtime.rs index 6c5eccb125339ea74ec6f62910e14f5dac40d997..52bf48baa574096c81835cf47b57972ddb76f4bb 100644 --- a/srml/support/src/runtime.rs +++ b/srml/support/src/runtime.rs @@ -191,8 +191,7 @@ macro_rules! construct_runtime { )* }; ) => { - #[derive(Clone, Copy, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive(Clone, Copy, PartialEq, Eq, $crate::RuntimeDebug)] pub struct $runtime; impl $crate::sr_primitives::traits::GetNodeBlockType for $runtime { type NodeBlock = $node_block; @@ -220,6 +219,7 @@ macro_rules! construct_runtime { $runtime; ; {}; + {}; $( $name: $module:: $( < $module_instance >:: )? { $( $modules ),* }, )* @@ -434,6 +434,7 @@ macro_rules! __decl_all_modules { $runtime:ident; ; { $( $parsed:tt )* }; + { $( $parsed_nested:tt )* }; System: $module:ident::{ Module $(, $modules:ident )* }, $( $rest:tt )* ) => { @@ -441,6 +442,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 )* ); }; @@ -448,6 +469,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 )* ) => { @@ -458,6 +480,7 @@ macro_rules! __decl_all_modules { $( $parsed )* $module::$name $(<$module_instance>)?, }; + { ( $( $parsed_nested )*, $name, ) }; $( $rest )* ); }; @@ -465,6 +488,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 )* ) => { @@ -472,6 +496,7 @@ macro_rules! __decl_all_modules { $runtime; $( $system )?; { $( $parsed )* }; + { $( $parsed_nested )* }; $name: $module::{ $( $modules ),* }, $( $rest )* ); @@ -487,6 +512,7 @@ macro_rules! __decl_all_modules { $runtime; $( $system )?; { $( $parsed )* }; + { $( $parsed_nested )* }; $( $rest )* ); }; @@ -494,12 +520,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..1edf9c03db61aa5bc62ead0fe35c7e275b8b1554 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) - } - - /// Take a value from storage, removing it afterwards. - fn take>(storage: &mut S) -> Self::Query { - storage.$taker($key) + fn from_optional_value_to_query(v: Option<$ty>) -> Self::Query { + $crate::storage::storage_items::$into_query(v) } - /// 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 - } - - /// 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[..]) + fn from_optional_value_to_query(v: Option<$ty>) -> Self::Query { + $crate::storage::storage_items::$into_query(v) } - /// 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,48 +300,48 @@ 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. - GETU32 get(u32_getter): T::Origin; - 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); - 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); + GETU32 get(fn u32_getter): T::Origin; + pub PUBGETU32 get(fn pub_u32_getter) build(|config: &GenesisConfig| config.u32_getter_with_config): u32; + GETU32WITHCONFIG get(fn u32_getter_with_config) config(): u32; + pub PUBGETU32WITHCONFIG get(fn pub_u32_getter_with_config) config(): u32; + GETU32MYDEF get(fn u32_getter_mydef): Option; + pub PUBGETU32MYDEF get(fn pub_u32_getter_mydef) config(): u32 = 3; + GETU32WITHCONFIGMYDEF get(fn u32_getter_with_config_mydef) config(): u32 = 2; + pub PUBGETU32WITHCONFIGMYDEF get(fn pub_u32_getter_with_config_mydef) config(): u32 = 1; + PUBGETU32WITHCONFIGMYDEFOPT get(fn 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; - pub PUBGETMAPU32 get(pub_map_u32_getter): map u32 => String; + GETMAPU32 get(fn map_u32_getter): map u32 => String; + pub PUBGETMAPU32 get(fn pub_map_u32_getter): map u32 => String; - GETMAPU32MYDEF get(map_u32_getter_mydef): map u32 => String = "map".into(); - pub PUBGETMAPU32MYDEF get(pub_map_u32_getter_mydef): map u32 => String = "pubmap".into(); + GETMAPU32MYDEF get(fn map_u32_getter_mydef): map u32 => String = "map".into(); + pub PUBGETMAPU32MYDEF get(fn pub_map_u32_getter_mydef): map u32 => String = "pubmap".into(); // linked map LINKEDMAPU32 : linked_map u32 => Option; - pub PUBLINKEDMAPU32MYDEF : linked_map u32 => Option = Some("hello".into()); - 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(); + pub PUBLINKEDMAPU32MYDEF : linked_map u32 => Option; + GETLINKEDMAPU32 get(fn linked_map_u32_getter): linked_map u32 => String; + pub PUBGETLINKEDMAPU32MYDEF get(fn pub_linked_map_u32_getter_mydef): linked_map u32 => String = "pubmap".into(); COMPLEXTYPE1: ::std::vec::Vec<::Origin>; COMPLEXTYPE2: (Vec)>>, u32); 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(|_| {}); } } @@ -779,7 +741,7 @@ mod test3 { } crate::decl_storage! { trait Store for Module as Test { - Foo get(foo) config(initial_foo): u32; + Foo get(fn foo) config(initial_foo): u32; } } @@ -795,18 +757,37 @@ mod test3 { #[cfg(test)] #[allow(dead_code)] -mod test_map_vec_append { +mod test_append_and_len { + use runtime_io::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 +798,108 @@ mod test_map_vec_append { type BlockNumber = u32; } + #[test] + fn default_for_option() { + TestExternalities::default().execute_with(|| { + 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}; + TestExternalities::default().execute_with(|| { + 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]); + }); + } - with_externalities(&mut TestExternalities::default(), || { - let _ = MapVec::append(1, &[1, 2, 3]); - let _ = MapVec::append(1, &[4, 5]); + #[test] + fn append_works_for_default() { + TestExternalities::default().execute_with(|| { + 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() { + TestExternalities::default().execute_with(|| { + 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() { + TestExternalities::default().execute_with(|| { + 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() { + TestExternalities::default().execute_with(|| { + // 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 cca9fd2b10376d92c8fac652aff730a0ea59732c..c58d60ffc9cf9729d5d9f3432739c1fc26bebd7a 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, fmt::Debug}; +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::{MaybeSerializeDeserialize, 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 { @@ -51,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 @@ -153,7 +148,7 @@ pub trait OnUnbalanced { fn on_unbalanced(amount: Imbalance); } -impl OnUnbalanced for () { +impl OnUnbalanced for () { fn on_unbalanced(amount: Imbalance) { drop(amount); } } @@ -161,6 +156,9 @@ impl OnUnbalanced for () { #[derive(Copy, Clone, Eq, PartialEq)] pub enum ExistenceRequirement { /// Operation must not result in the account going out of existence. + /// + /// Note this implies that if the account never existed in the first place, then the operation + /// may legitimately leave the account unchanged and still non-existent. KeepAlive, /// Operation may result in account going out of existence. AllowDeath, @@ -259,7 +257,7 @@ pub enum SignedImbalance>{ impl< P: Imbalance, N: Imbalance, - B: SimpleArithmetic + Codec + Copy + MaybeSerializeDebug + Default, + B: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default, > SignedImbalance { pub fn zero() -> Self { SignedImbalance::Positive(P::zero()) @@ -322,7 +320,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 + MaybeSerializeDeserialize + Debug + 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. @@ -620,13 +618,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); @@ -656,6 +664,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(); @@ -683,8 +701,7 @@ pub trait ChangeMembers { } } } - - Self::change_members_sorted(&incoming[..], &outgoing[..], &new_members); + (incoming, outgoing) } } @@ -703,3 +720,23 @@ pub trait InitializeMembers { impl InitializeMembers for () { fn initialize_members(_: &[T]) {} } + +// A trait that is able to provide randomness. +pub trait Randomness { + /// Get a "random" value + /// + /// Being a deterministic blockchain, real randomness is difficult to come by. This gives you + /// something that approximates it. `subject` is a context identifier and allows you to get a + /// different result to other callers of this function; use it like + /// `random(&b"my context"[..])`. + fn random(subject: &[u8]) -> Output; + + /// Get the basic random seed. + /// + /// In general you won't want to use this, but rather `Self::random` which allows you to give a + /// subject for the random result and whose value will be independently low-influence random + /// from any other such seeds. + fn random_seed() -> Output { + Self::random(&[][..]) + } +} 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..f40fef9eade6040d6297700068b99636a4186789 100644 --- a/srml/support/test/Cargo.toml +++ b/srml/support/test/Cargo.toml @@ -5,13 +5,14 @@ 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 } +sr-primitives = { package = "sr-primitives", path = "../../../core/sr-primitives", 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 +20,9 @@ default = ["std"] std = [ "serde/std", "codec/std", - "runtime_io/std", - "srml-support/std", + "runtime-io/std", + "support/std", "inherents/std", "primitives/std", + "sr-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..44a6b540a7a0e32896dab3aa267c7b2b15b7aeea 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(fn test_generic_value) config(): Option; + pub TestGenericDoubleMap get(fn 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(fn test_generic_value) config(): Option; + pub TestGenericDoubleMap get(fn 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 4a43eb137e35b5b190fd7ea92b5f8841d49ea7f0..e945c774c0d07e97cc5186316fe77425748d2d23 100644 --- a/srml/support/test/tests/genesisconfig.rs +++ b/srml/support/test/tests/genesisconfig.rs @@ -15,15 +15,15 @@ // along with Substrate. If not, see . pub trait Trait { - type BlockNumber: codec::Codec + Default; + type BlockNumber: codec::Codec + codec::EncodeLike + Default; type Origin; } -srml_support::decl_module! { +support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } -srml_support::decl_storage! { +support::decl_storage! { trait Store for Module as Example { pub AppendableDM config(t): double_map u32, blake2_256(T::BlockNumber) => Vec; } diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index 440fb9e779996b5ae5e7ce77bb5cb3787731e2a7..dd05cb1d8c6e301d9482d3bead20f0082f37d1fd 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -15,19 +15,18 @@ // along with Substrate. If not, see . #![recursion_limit="128"] -use runtime_io::{with_externalities, Blake2Hasher}; -use srml_support::{ +use sr_primitives::{generic, BuildStorage, traits::{BlakeTwo256, Block as _, Verify}}; +use support::{ Parameter, traits::Get, parameter_types, - sr_primitives::{generic, BuildStorage, traits::{BlakeTwo256, Block as _, Verify}}, metadata::{ DecodeDifferent, StorageMetadata, StorageEntryModifier, StorageEntryType, DefaultByteGetter, - StorageEntryMetadata, StorageHasher + StorageEntryMetadata, StorageHasher, }, + StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap, }; use inherents::{ ProvideInherent, InherentData, InherentIdentifier, RuntimeString, MakeFatalError }; -use srml_support::{StorageValue, StorageMap, StorageDoubleMap, EnumerableStorageMap}; use primitives::{H256, sr25519}; mod system; @@ -45,17 +44,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 +63,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,21 +74,20 @@ 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), } } - #[derive(PartialEq, Eq, Clone)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] pub enum Origin, I> where T::BlockNumber: From { Members(u32), _Phantom(std::marker::PhantomData<(T, I)>), @@ -128,15 +126,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,14 +143,13 @@ mod module2 { } } - srml_support::decl_event! { + support::decl_event! { pub enum Event where Amount = >::Amount { Variant(Amount), } } - #[derive(PartialEq, Eq, Clone)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] pub enum Origin, I=DefaultInstance> { Members(u32), _Phantom(std::marker::PhantomData<(T, I)>), @@ -185,7 +182,7 @@ mod module3 { type Currency2: Currency; } - srml_support::decl_module! { + support::decl_module! { pub struct Module for enum Call where origin: ::Origin {} } } @@ -244,7 +241,7 @@ impl system::Trait for Runtime { type Event = Event; } -srml_support::construct_runtime!( +support::construct_runtime!( pub enum Runtime where Block = Block, NodeBlock = Block, @@ -275,7 +272,7 @@ pub type Header = generic::Header; pub type Block = generic::Block; pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; -fn new_test_ext() -> runtime_io::TestExternalities { +fn new_test_ext() -> runtime_io::TestExternalities { GenesisConfig{ module1_Instance1: Some(module1::GenesisConfig { value: 3, @@ -304,58 +301,32 @@ 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] fn storage_with_instance_basic_operation() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { type Value = module2::Value; type Map = module2::Map; type LinkedMap = module2::LinkedMap; @@ -403,7 +374,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..72e0bc8caf198f5a4519b09dfc9fc02bb4d55ff6 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,10 +99,10 @@ 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| { + pub Parameters get(fn parameters) build(|config: &GenesisConfig| { if config.enable_storage_role { let storage_params: RoleParameters = Default::default(); vec![(Role::Storage, storage_params)] @@ -112,7 +112,7 @@ mod module { }): map Role => Option>; /// the roles members can enter into - pub AvailableRoles get(available_roles) build(|config: &GenesisConfig| { + pub AvailableRoles get(fn available_roles) build(|config: &GenesisConfig| { if config.enable_storage_role { vec![(Role::Storage)] } else { @@ -121,13 +121,13 @@ mod module { }): Vec; /// Actors list - pub ActorAccountIds get(actor_account_ids) : Vec; + pub ActorAccountIds get(fn actor_account_ids) : Vec; /// actor accounts associated with a role - pub AccountIdsByRole get(account_ids_by_role) : map Role => Vec; + pub AccountIdsByRole get(fn account_ids_by_role) : map Role => Vec; /// tokens locked until given block number - pub Bondage get(bondage) : map T::AccountId => T::BlockNumber; + pub Bondage get(fn bondage) : map T::AccountId => T::BlockNumber; /// First step before enter a role is registering intent with a new account/key. /// This is done by sending a role_entry_request() from the new account. @@ -135,10 +135,10 @@ mod module { /// The account making the request will be bonded and must have /// sufficient balance to cover the minimum stake for the role. /// Bonding only occurs after successful entry into a role. - pub RoleEntryRequests get(role_entry_requests) : Requests; + pub RoleEntryRequests get(fn role_entry_requests) : Requests; /// Entry request expires after this number of blocks - pub RequestLifeTime get(request_life_time) config(request_life_time) : u64 = 0; + pub RequestLifeTime get(fn request_life_time) config(request_life_time) : u64 = 0; } add_extra_genesis { config(enable_storage_role): bool; @@ -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 1934ae5ea1e47f59c90dad617bec191870699650..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!() } } diff --git a/srml/support/test/tests/reserved_keyword/on_initialize.stderr b/srml/support/test/tests/reserved_keyword/on_initialize.stderr index 04adefab3a742f845e5bbec25680c5f99a0e041d..13c2ef8d2c8691b7a6a576612683e9c3f963671a 100644 --- a/srml/support/test/tests/reserved_keyword/on_initialize.stderr +++ b/srml/support/test/tests/reserved_keyword/on_initialize.stderr @@ -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..2996724f625988feab38795dee5d1c046b98b17a 100644 --- a/srml/support/test/tests/system.rs +++ b/srml/support/test/tests/system.rs @@ -1,32 +1,44 @@ -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 { + /// Test error documentation + TestError, + /// Error documentation + /// with multiple lines + AnotherError + } +} + /// Origin for the system module. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] pub enum RawOrigin { Root, Signed(AccountId), @@ -49,4 +61,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 fb2b5296c79887119218ffd846e8fa68d2a0ddc1..a9ce6b3f8c830a7dc7313bad0e6c4fd2342cf78b 100644 --- a/srml/system/Cargo.toml +++ b/srml/system/Cargo.toml @@ -5,18 +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 } sr-version = { path = "../../core/sr-version", default-features = false } -srml-support = { path = "../support", 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"] @@ -26,8 +27,8 @@ std = [ "codec/std", "primitives/std", "rstd/std", - "runtime_io/std", - "srml-support/std", + "runtime-io/std", + "support/std", "sr-primitives/std", "sr-version/std", ] diff --git a/srml/system/benches/bench.rs b/srml/system/benches/bench.rs index 3d10db557c1e5fbd77379d0a68c6bca0a3b01640..6da02cf9c8cea0edb4d48a9d7534e2e4ed797ada 100644 --- a/srml/system/benches/bench.rs +++ b/srml/system/benches/bench.rs @@ -16,8 +16,7 @@ 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 support::{decl_module, decl_event, impl_outer_origin, impl_outer_event}; use primitives::H256; use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; @@ -51,7 +50,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; @@ -69,7 +68,6 @@ impl system::Trait for Runtime { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -82,13 +80,13 @@ impl module::Trait for Runtime { type Event = Event; } -fn new_test_ext() -> runtime_io::TestExternalities { +fn new_test_ext() -> runtime_io::TestExternalities { system::GenesisConfig::default().build_storage::().unwrap().into() } fn deposit_events(n: usize) { let mut t = new_test_ext(); - with_externalities(&mut t, || { + t.execute_with(|| { for _ in 0..n { module::Module::::deposit_event( module::Event::Complex(vec![1, 2, 3], 2, 3, 899) diff --git a/srml/system/rpc/Cargo.toml b/srml/system/rpc/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..04856a817f6814377ab99c975dcc2105357391f3 --- /dev/null +++ b/srml/system/rpc/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "srml-system-rpc" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +client = { package = "substrate-client", path = "../../../core/client" } +codec = { package = "parity-scale-codec", version = "1.0.0" } +jsonrpc-core = "13.2.0" +jsonrpc-core-client = "13.2.0" +jsonrpc-derive = "13.2.0" +log = "0.4.8" +serde = { version = "1.0.101", features = ["derive"] } +sr-primitives = { path = "../../../core/sr-primitives" } +srml-system-rpc-runtime-api = { path = "./runtime-api" } +substrate-primitives = { path = "../../../core/primitives" } +transaction_pool = { package = "substrate-transaction-pool", path = "../../../core/transaction-pool" } + +[dev-dependencies] +test-client = { package = "substrate-test-runtime-client", path = "../../../core/test-runtime/client" } +env_logger = "0.7.0" +futures03 = { package = "futures-preview", version = "=0.3.0-alpha.19" } diff --git a/srml/system/rpc/runtime-api/Cargo.toml b/srml/system/rpc/runtime-api/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..fc525d8fce2adb9fd1d8cd4adc582461613e322a --- /dev/null +++ b/srml/system/rpc/runtime-api/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "srml-system-rpc-runtime-api" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +client = { package = "substrate-client", path = "../../../../core/client", default-features = false } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } + +[features] +default = ["std"] +std = [ + "client/std", + "codec/std", +] diff --git a/srml/system/rpc/runtime-api/src/lib.rs b/srml/system/rpc/runtime-api/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..45af0241e08365f44bfa77e1893d9a3a477e077d --- /dev/null +++ b/srml/system/rpc/runtime-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 . + +//! Runtime API definition required by System RPC extensions. +//! +//! This API should be imported and implemented by the runtime, +//! of a node that wants to use the custom RPC extension +//! adding System access methods. + +#![cfg_attr(not(feature = "std"), no_std)] + +client::decl_runtime_apis! { + /// The API to query account nonce (aka transaction index). + pub trait AccountNonceApi where + AccountId: codec::Codec, + Index: codec::Codec, + { + /// Get current account nonce of given `AccountId`. + fn account_nonce(account: AccountId) -> Index; + } +} diff --git a/node/rpc/src/accounts.rs b/srml/system/rpc/src/lib.rs similarity index 62% rename from node/rpc/src/accounts.rs rename to srml/system/rpc/src/lib.rs index 09d4a5144228cc9ce8011bef77864aa0d71e6d14..c6c0a658fba535bb59bc3aa20de3d382c3d6f3fb 100644 --- a/node/rpc/src/accounts.rs +++ b/srml/system/rpc/src/lib.rs @@ -14,60 +14,66 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Node-specific RPC methods for Accounts. +//! System SRML specific RPC methods. use std::sync::Arc; +use codec::{self, Codec, Encode}; use client::blockchain::HeaderBackend; use jsonrpc_core::{Result, Error, ErrorCode}; use jsonrpc_derive::rpc; -use node_primitives::{ - AccountId, Index, AccountNonceApi, Block, BlockId, +use sr_primitives::{ + generic::BlockId, + traits, }; -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; +pub use srml_system_rpc_runtime_api::AccountNonceApi; +pub use self::gen_client::Client as SystemClient; -const RUNTIME_ERROR: i64 = 1; - -/// Accounts RPC methods. +/// System RPC methods. #[rpc] -pub trait AccountsApi { +pub trait SystemApi { /// 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")] + #[rpc(name = "system_accountNextIndex", alias("account_nextIndex"))] fn nonce(&self, account: AccountId) -> Result; } -/// An implementation of Accounts specific RPC methods. -pub struct Accounts { +const RUNTIME_ERROR: i64 = 1; + +/// An implementation of System-specific RPC methods. +pub struct System { client: Arc, pool: Arc>, + _marker: std::marker::PhantomData, } -impl Accounts { - /// Create new `Accounts` given client and transaction pool. +impl System { + /// Create new `System` given client and transaction pool. pub fn new(client: Arc, pool: Arc>) -> Self { - Accounts { + System { client, - pool + pool, + _marker: Default::default(), } } } -impl AccountsApi for Accounts +impl SystemApi for System where C: traits::ProvideRuntimeApi, C: HeaderBackend, C: Send + Sync + 'static, - C::Api: AccountNonceApi, + C::Api: AccountNonceApi, P: txpool::ChainApi + Sync + Send + 'static, + Block: traits::Block, + AccountId: Clone + std::fmt::Display + Codec, + Index: Clone + std::fmt::Display + Codec + traits::SimpleArithmetic, { fn nonce(&self, account: AccountId) -> Result { let api = self.client.runtime_api(); @@ -87,12 +93,12 @@ where // 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(); + let mut current_nonce = nonce.clone(); + let mut current_tag = (account.clone(), nonce.clone()).encode(); for tx in self.pool.ready() { log::debug!( target: "rpc", - "Current nonce to {:?}, checking {} vs {:?}", + "Current nonce to {}, checking {} vs {:?}", current_nonce, HexDisplay::from(¤t_tag), tx.provides.iter().map(|x| format!("{}", HexDisplay::from(x))).collect::>(), @@ -100,8 +106,8 @@ where // 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(); + current_nonce += traits::One::one(); + current_tag = (account.clone(), current_nonce.clone()).encode(); } } @@ -113,42 +119,38 @@ where mod tests { use super::*; - use node_runtime::{CheckedExtrinsic, Call, TimestampCall}; - use codec::Decode; - use node_testing::{ - client::{ClientExt, TestClientBuilder, TestClientBuilderExt}, - keyring::{self, alice, signed_extra}, + use futures03::executor::block_on; + use test_client::{ + runtime::Transfer, + AccountKeyring, }; - 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::ChainApi::new(client.clone()))); - - let new_transaction = |extra| { - let ex = CheckedExtrinsic { - signed: Some((alice().into(), extra)), - function: Call::Timestamp(TimestampCall::set(5)), + let client = Arc::new(test_client::new()); + let pool = Arc::new(Pool::new(Default::default(), transaction_pool::FullChainApi::new(client.clone()))); + + let new_transaction = |nonce: u64| { + let t = Transfer { + from: AccountKeyring::Alice.into(), + to: AccountKeyring::Bob.into(), + amount: 5, + nonce, }; - let xt = keyring::sign(ex, VERSION, client.genesis_hash().into()); - // Convert to OpaqueExtrinsic - let encoded = xt.encode(); - node_primitives::UncheckedExtrinsic::decode(&mut &*encoded).unwrap() + t.into_signed_tx() }; // Populate the pool - let ext0 = new_transaction(signed_extra(0, 0)); - pool.submit_one(&BlockId::number(0), ext0).unwrap(); - let ext1 = new_transaction(signed_extra(1, 0)); - pool.submit_one(&BlockId::number(0), ext1).unwrap(); + let ext0 = new_transaction(0); + block_on(pool.submit_one(&BlockId::number(0), ext0)).unwrap(); + let ext1 = new_transaction(1); + block_on(pool.submit_one(&BlockId::number(0), ext1)).unwrap(); - let accounts = Accounts::new(client, pool); + let accounts = System::new(client, pool); // when - let nonce = accounts.nonce(alice().into()); + let nonce = accounts.nonce(AccountKeyring::Alice.into()); // then assert_eq!(nonce.unwrap(), 2); diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index d0b36ae14d05d9414de9bfac28b00b99855307be..87c38096ab934ae39aebdbd2e2be0c4ef39970a4 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -48,7 +48,7 @@ //! //! - [`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 +//! - [`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 @@ -65,10 +65,10 @@ //! //! Import the System module and derive your module's configuration trait from the system trait. //! -//! ### Example - Get random seed and extrinsic count for the current block +//! ### Example - Get extrinsic count and parent hash 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,8 +77,8 @@ //! pub struct Module for enum Call where origin: T::Origin { //! pub fn system_module_example(origin) -> Result { //! let _sender = ensure_signed(origin)?; -//! let _random_seed = >::random_seed(); //! let _extrinsic_count = >::extrinsic_count(); +//! let _parent_hash = >::parent_hash(); //! Ok(()) //! } //! } @@ -94,57 +94,45 @@ use rstd::prelude::*; #[cfg(any(feature = "std", test))] use rstd::map; use rstd::marker::PhantomData; +use rstd::fmt::Debug; use sr_version::RuntimeVersion; -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_primitives::{ + RuntimeDebug, + generic::{self, Era}, Perbill, ApplyError, ApplyOutcome, DispatchError, + weights::{Weight, DispatchInfo, DispatchClass, SimpleDispatchInfo}, + transaction_validity::{ + ValidTransaction, TransactionPriority, TransactionLongevity, TransactionValidityError, + InvalidTransaction, TransactionValidity, + }, + traits::{ + self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, Lookup, LookupError, + SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, SaturatedConversion, + MaybeSerialize, MaybeSerializeDeserialize, 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; +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? @@ -164,53 +152,48 @@ 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 { /// The aggregated `Origin` type used by dispatchable calls. - type Origin: Into, Self::Origin>> + From>; + type Origin: + Into, Self::Origin>> + From>; /// The aggregated `Call` type. - type Call; + type Call: Debug; - /// Account index (aka nonce) type. This stores the number of previous transactions associated with a sender - /// account. + /// Account index (aka nonce) type. This stores the number of previous transactions associated + /// with a sender account. type Index: - Parameter + Member + MaybeSerializeDebugButNotDeserialize + Default + MaybeDisplay + SimpleArithmetic + Copy; + Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + SimpleArithmetic + + Copy; /// The block number type used by the runtime. type BlockNumber: - Parameter + Member + MaybeSerializeDebug + MaybeDisplay + SimpleArithmetic + Default + Bounded + Copy - + rstd::hash::Hash; + Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleArithmetic + + Default + Bounded + Copy + rstd::hash::Hash; /// The output of the `Hashing` function. type Hash: - Parameter + Member + MaybeSerializeDebug + MaybeDisplay + SimpleBitOps + Default + Copy + CheckEqual - + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]>; + Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleBitOps + + Default + Copy + CheckEqual + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]>; /// The hashing system (algorithm) being used in the runtime (e.g. Blake2). type Hashing: Hash; /// The user account identifier type for the runtime. - type AccountId: Parameter + Member + MaybeSerializeDebug + MaybeDisplay + Ord + Default; + type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord + + Default; /// Converting trait to take a source type and convert to `AccountId`. /// - /// Used to define the type and conversion mechanism for referencing accounts in transactions. It's perfectly - /// reasonable for this to be an identity conversion (with the source type being `AccountId`), but other modules - /// (e.g. Indices module) may provide more functional/efficient alternatives. + /// Used to define the type and conversion mechanism for referencing accounts in transactions. + /// It's perfectly reasonable for this to be an identity conversion (with the source type being + /// `AccountId`), but other modules (e.g. Indices module) may provide more functional/efficient + /// alternatives. type Lookup: StaticLookup; - /// Handler for updating the weight multiplier at the end of each block. - /// - /// It receives the current block's weight as input and returns the next weight multiplier for next - /// block. - /// - /// Note that passing `()` will keep the value constant. - type WeightMultiplierUpdate: Convert<(Weight, WeightMultiplier), WeightMultiplier>; - /// The block header. type Header: Parameter + traits::Header< Number = Self::BlockNumber, @@ -218,7 +201,7 @@ pub trait Trait: 'static + Eq + Clone { >; /// The aggregated event type of the runtime. - type Event: Parameter + Member + From; + type Event: Parameter + Member + From + Debug; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount: Get; @@ -246,10 +229,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). @@ -295,12 +275,19 @@ 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); + } } } /// A phase of a block's execution. -#[derive(Encode, Decode)] -#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone, Debug))] +#[derive(Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))] pub enum Phase { /// Applying an extrinsic. ApplyExtrinsic(u32), @@ -309,8 +296,8 @@ pub enum Phase { } /// Record of an event happening. -#[derive(Encode, Decode)] -#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone, Debug))] +#[derive(Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))] pub struct EventRecord { /// The phase of the block it happened in. pub phase: Phase, @@ -326,13 +313,23 @@ 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))] +#[derive(PartialEq, Eq, Clone, RuntimeDebug)] pub enum RawOrigin { /// The system itself ordained this dispatch to happen: this is the highest privilege level. Root, @@ -374,35 +371,29 @@ type EventIndex = u32; decl_storage! { trait Store for Module as System { /// Extrinsics nonce for accounts. - pub AccountNonce get(account_nonce): map T::AccountId => T::Index; + pub AccountNonce get(fn account_nonce): map T::AccountId => T::Index; /// Total extrinsics count for the current block. ExtrinsicCount: Option; /// Total weight for all extrinsics put together, for the current block. AllExtrinsicsWeight: Option; /// Total length (in bytes) for all extrinsics put together, for the current block. AllExtrinsicsLen: Option; - /// The next weight multiplier. This should be updated at the end of each block based on the - /// saturation level (weight). - pub NextWeightMultiplier get(next_weight_multiplier): WeightMultiplier = Default::default(); /// Map of block numbers to block hashes. - pub BlockHash get(block_hash) build(|_| vec![(T::BlockNumber::zero(), hash69())]): map T::BlockNumber => T::Hash; + pub BlockHash get(fn block_hash) build(|_| vec![(T::BlockNumber::zero(), hash69())]): map T::BlockNumber => T::Hash; /// Extrinsics data for the current block (maps an extrinsic's index to its data). - ExtrinsicData get(extrinsic_data): map u32 => Vec; - /// Series of block headers from the last 81 blocks that acts as random seed material. This is arranged as a - /// ring buffer with the `i8` prefix being the index into the `Vec` of the oldest hash. - RandomMaterial get(random_material): (i8, Vec); + ExtrinsicData get(fn extrinsic_data): map u32 => Vec; /// The current block number being processed. Set by `execute_block`. - Number get(block_number) build(|_| 1.into()): T::BlockNumber; + Number get(fn block_number) build(|_| 1.into()): T::BlockNumber; /// Hash of the previous block. - ParentHash get(parent_hash) build(|_| hash69()): T::Hash; + ParentHash get(fn parent_hash) build(|_| hash69()): T::Hash; /// Extrinsics root of the current block, also part of the block header. - ExtrinsicsRoot get(extrinsics_root): T::Hash; + ExtrinsicsRoot get(fn extrinsics_root): T::Hash; /// Digest of the current block, also part of the block header. - Digest get(digest): DigestOf; + Digest get(fn digest): DigestOf; /// Events deposited for the current block. - Events get(events): Vec>; + Events get(fn events): Vec>; /// The number of events in the `Events` list. - EventCount get(event_count): EventIndex; + EventCount get(fn event_count): EventIndex; // TODO: https://github.com/paritytech/substrate/issues/2553 // Possibly, we can improve it by using something like: @@ -422,7 +413,7 @@ decl_storage! { /// The value has the type `(T::BlockNumber, EventIndex)` because if we used only just /// the `EventIndex` then in case if the topic has the same contents on the next block /// no notification will be triggered thus the event might be lost. - EventTopics get(event_topics): double_map hasher(blake2_256) (), blake2_256(T::Hash) + EventTopics get(fn event_topics): double_map hasher(blake2_256) (), blake2_256(T::Hash) => Vec<(T::BlockNumber, EventIndex)>; } add_extra_genesis { @@ -430,25 +421,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, @@ -462,7 +451,7 @@ impl< } } -pub struct EnsureSigned(::rstd::marker::PhantomData); +pub struct EnsureSigned(rstd::marker::PhantomData); impl< O: Into, O>> + From>, AccountId, @@ -476,7 +465,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, @@ -491,7 +480,7 @@ impl< } } -pub struct EnsureNone(::rstd::marker::PhantomData); +pub struct EnsureNone(rstd::marker::PhantomData); impl< O: Into, O>> + From>, AccountId, @@ -505,7 +494,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 { @@ -515,36 +504,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. /// @@ -578,7 +572,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].iter()).is_err() { // The most sensible thing to do here is to just ignore this event and wait until the // new block. return; @@ -612,17 +606,6 @@ impl Module { AllExtrinsicsLen::get().unwrap_or_default() } - /// Update the next weight multiplier. - /// - /// This should be called at then end of each block, before `all_extrinsics_weight` is cleared. - pub fn update_weight_multiplier() { - // update the multiplier based on block weight. - let current_weight = Self::all_extrinsics_weight(); - NextWeightMultiplier::mutate(|fm| { - *fm = T::WeightMultiplierUpdate::convert((current_weight, *fm)) - }); - } - /// Start the execution of a particular block. pub fn initialize( number: &T::BlockNumber, @@ -637,12 +620,6 @@ impl Module { >::put(parent_hash); >::insert(*number - One::one(), parent_hash); >::put(txs_root); - >::mutate(|&mut(ref mut index, ref mut values)| if values.len() < 81 { - values.push(parent_hash.clone()) - } else { - values[*index as usize] = parent_hash.clone(); - *index = (*index + 1) % 81; - }); >::kill(); EventCount::kill(); >::remove_prefix(&()); @@ -651,7 +628,6 @@ impl Module { /// Remove temporary "environment" entries in storage. pub fn finalize() -> T::Header { ExtrinsicCount::kill(); - Self::update_weight_multiplier(); AllExtrinsicsWeight::kill(); AllExtrinsicsLen::kill(); @@ -701,11 +677,11 @@ impl Module { /// Get the basic externalities for this module, useful for tests. #[cfg(any(feature = "std", test))] - pub fn externalities() -> TestExternalities { + 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![])) } @@ -729,71 +705,15 @@ 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 - /// allows you to give a subject for the random result and whose value will - /// be independently low-influence random from any other such seeds. - pub fn random_seed() -> T::Hash { - Self::random(&[][..]) + /// Set the current block weight. This should only be used in some integration tests. + #[cfg(any(feature = "std", test))] + pub fn set_block_limits(weight: Weight, len: usize) { + AllExtrinsicsWeight::put(weight); + AllExtrinsicsLen::put(len as u32); } - /// Get a low-influence "random" value. - /// - /// Being a deterministic block chain, real randomness is difficult to come - /// by. This gives you something that approximates it. `subject` is a - /// context identifier and allows you to get a different result to other - /// callers of this function; use it like `random(&b"my context"[..])`. - /// - /// This is initially implemented through a low-influence "triplet mix" - /// convolution of previous block hash values. In the future it will be - /// generated from a secure verifiable random function (VRF). - /// - /// ### Security Notes - /// - /// This randomness uses a low-influence function, drawing upon the block - /// hashes from the previous 81 blocks. Its result for any given subject - /// will be known in advance by the block producer of this block (and, - /// indeed, anyone who knows the block's `parent_hash`). However, it is - /// mostly impossible for the producer of this block *alone* to influence - /// the value of this hash. A sizable minority of dishonest and coordinating - /// block producers would be required in order to affect this value. If that - /// is an insufficient security guarantee then two things can be used to - /// improve this randomness: - /// - /// - Name, in advance, the block number whose random value will be used; - /// ensure your module retains a buffer of previous random values for its - /// subject and then index into these in order to obviate the ability of - /// your user to look up the parent hash and choose when to transact based - /// upon it. - /// - Require your user to first commit to an additional value by first - /// posting its hash. Require them to reveal the value to determine the - /// final result, hashing it with the output of this random function. This - /// reduces the ability of a cabal of block producers from conspiring - /// against individuals. - /// - /// WARNING: Hashing the result of this function will remove any - /// low-influnce properties it has and mean that all bits of the resulting - /// value are entirely manipulatable by the author of the parent block, who - /// can determine the value of `parent_hash`. - pub fn random(subject: &[u8]) -> T::Hash { - let (index, hash_series) = >::get(); - if hash_series.len() > 0 { - // Always the case after block 1 is initialised. - hash_series.iter() - .cycle() - .skip(index as usize) - .take(81) - .enumerate() - .map(|(i, h)| (i as i8, subject, h).using_encoded(T::Hashing::hash)) - .triplet_mix() - } else { - T::Hash::default() - } - } + /// Return the chain's current runtime version. + pub fn runtime_version() -> RuntimeVersion { T::Version::get() } /// Increment a particular account's nonce by 1. pub fn inc_account_nonce(who: &T::AccountId) { @@ -811,11 +731,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; @@ -844,7 +766,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. @@ -859,31 +780,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`. @@ -894,8 +817,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) } @@ -907,7 +829,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, @@ -915,7 +837,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)?; @@ -929,20 +851,31 @@ 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() }) } } -#[cfg(feature = "std")] -impl rstd::fmt::Debug for CheckWeight { +impl Debug for CheckWeight { + #[cfg(feature = "std")] fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { - write!(f, "CheckWeight") + write!(f, "CheckWeight") + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) } } @@ -950,7 +883,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 { @@ -958,11 +890,16 @@ impl CheckNonce { } } -#[cfg(feature = "std")] -impl rstd::fmt::Debug for CheckNonce { +impl Debug for CheckNonce { + #[cfg(feature = "std")] fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { self.0.fmt(f) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } impl SignedExtension for CheckNonce { @@ -971,7 +908,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, @@ -979,13 +916,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(()) } @@ -996,11 +938,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))]; @@ -1020,11 +962,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 { @@ -1032,11 +973,16 @@ impl CheckEra { } } -#[cfg(feature = "std")] -impl rstd::fmt::Debug for CheckEra { +impl Debug for CheckEra { + #[cfg(feature = "std")] fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { self.0.fmt(f) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } impl SignedExtension for CheckEra { @@ -1045,11 +991,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)) + } } } @@ -1057,17 +1021,22 @@ impl SignedExtension for CheckEra { #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct CheckGenesis(rstd::marker::PhantomData); -#[cfg(feature = "std")] -impl rstd::fmt::Debug for CheckGenesis { - fn fmt(&self, _f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { +impl Debug for CheckGenesis { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + write!(f, "CheckGenesis") + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { Ok(()) } } -#[cfg(feature = "std")] impl CheckGenesis { + /// Creates new `SignedExtension` to check genesis hash. pub fn new() -> Self { - Self(std::marker::PhantomData) + Self(rstd::marker::PhantomData) } } @@ -1077,7 +1046,7 @@ 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())) } } @@ -1086,17 +1055,22 @@ impl SignedExtension for CheckGenesis { #[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 { +impl Debug for CheckVersion { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + write!(f, "CheckVersion") + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { Ok(()) } } -#[cfg(feature = "std")] impl CheckVersion { + /// Create new `SignedExtension` to check runtime version. pub fn new() -> Self { - Self(std::marker::PhantomData) + Self(rstd::marker::PhantomData) } } @@ -1106,22 +1080,23 @@ impl SignedExtension for CheckVersion { type AdditionalSigned = u32; type Pre = (); - fn additional_signed(&self) -> Result { + fn additional_signed(&self) -> Result { Ok(>::runtime_version().spec_version) } } -pub struct ChainContext(::rstd::marker::PhantomData); +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) } } @@ -1129,12 +1104,11 @@ impl Lookup for ChainContext { #[cfg(test)] 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 {} } @@ -1158,7 +1132,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = u16; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -1171,7 +1144,7 @@ mod tests { fn from(e: Event) -> u16 { match e { Event::ExtrinsicSuccess => 100, - Event::ExtrinsicFailed => 101, + Event::ExtrinsicFailed(_) => 101, } } } @@ -1180,7 +1153,7 @@ mod tests { const CALL: &::Call = &(); - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { GenesisConfig::default().build_storage::().unwrap().into() } @@ -1201,7 +1174,7 @@ mod tests { #[test] fn deposit_event_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::initialize(&1, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); System::note_finished_extrinsics(); System::deposit_event(1u16); @@ -1220,25 +1193,33 @@ 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![] } + ] + ); }); } #[test] fn deposit_event_topics() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { const BLOCK_NUMBER: u64 = 1; - System::initialize(&BLOCK_NUMBER, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + System::initialize( + &BLOCK_NUMBER, + &[0u8; 32].into(), + &[0u8; 32].into(), + &Default::default(), + ); System::note_finished_extrinsics(); let topics = vec![ @@ -1295,7 +1276,7 @@ mod tests { #[test] fn prunes_block_hash_mappings() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // simulate import of 15 blocks for n in 1..=15 { System::initialize( @@ -1328,7 +1309,7 @@ mod tests { #[test] fn signed_ext_check_nonce_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { >::insert(1, 1); let info = DispatchInfo::default(); let len = 0_usize; @@ -1346,7 +1327,7 @@ mod tests { #[test] fn signed_ext_check_weight_works_normal_tx() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let normal_limit = normal_weight_limit(); let small = DispatchInfo { weight: 100, ..Default::default() }; let medium = DispatchInfo { @@ -1373,7 +1354,7 @@ mod tests { #[test] fn signed_ext_check_weight_fee_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let free = DispatchInfo { weight: 0, ..Default::default() }; let len = 0_usize; @@ -1386,7 +1367,7 @@ mod tests { #[test] fn signed_ext_check_weight_max_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let max = DispatchInfo { weight: Weight::max_value(), ..Default::default() }; let len = 0_usize; let normal_limit = normal_weight_limit(); @@ -1400,7 +1381,7 @@ mod tests { #[test] fn signed_ext_check_weight_works_operational_tx() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let normal = DispatchInfo { weight: 100, ..Default::default() }; let op = DispatchInfo { weight: 100, class: DispatchClass::Operational }; let len = 0_usize; @@ -1423,25 +1404,28 @@ mod tests { #[test] fn signed_ext_check_weight_priority_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal }; 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()); }) } #[test] fn signed_ext_check_weight_block_size_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let normal = DispatchInfo::default(); let normal_limit = normal_weight_limit() as usize; let reset_check_weight = |tx, s, f| { @@ -1465,11 +1449,11 @@ mod tests { #[test] fn signed_ext_check_era_should_work() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // future assert_eq!( CheckEra::::from(Era::mortal(4, 2)).additional_signed().err().unwrap(), - "transaction birth block ancient" + InvalidTransaction::AncientBirthBlock.into(), ); // correct @@ -1478,4 +1462,20 @@ mod tests { assert!(CheckEra::::from(Era::mortal(4, 12)).additional_signed().is_ok()); }) } + + #[test] + fn signed_ext_check_era_should_change_longevity() { + new_test_ext().execute_with(|| { + 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..11f7e234f71977707913b7930a95913aeb6a7522 --- /dev/null +++ b/srml/system/src/offchain.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 . + +//! Module helpers for offchain calls. + +use codec::Encode; +use sr_primitives::app_crypto::{self, RuntimeAppPublic}; +use sr_primitives::traits::{Extrinsic as ExtrinsicT, IdentifyAccount}; + +/// 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(public: Public, payload: &Payload) -> Option; +} + +/// A `Signer` implementation for any `AppPublic` type. +/// +/// This implementation additionaly supports conversion to/from multi-signature/multi-signer +/// wrappers. +/// If the wrapped crypto doesn't match `AppPublic`s crypto `None` is returned. +impl Signer for AppPublic where + AppPublic: RuntimeAppPublic + + app_crypto::AppPublic + + From<::Generic>, + ::Signature: app_crypto::AppSignature, + Signature: From< + <::Signature as app_crypto::AppSignature>::Generic + >, + Public: rstd::convert::TryInto<::Generic> +{ + fn sign(public: Public, raw_payload: &Payload) -> Option { + raw_payload.using_encoded(|payload| { + let public = public.try_into().ok()?; + AppPublic::from(public).sign(&payload) + .map( + <::Signature as app_crypto::AppSignature> + ::Generic::from + ) + .map(Signature::from) + }) + } +} + +/// Creates runtime-specific signed transaction. +pub trait CreateTransaction { + /// A `Public` key representing a particular `AccountId`. + type Public; + /// A `Signature` generated by the `Signer`. + 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, + public: Self::Public, + account: T::AccountId, + nonce: T::Index, + ) -> Option<(Extrinsic::Call, Extrinsic::SignaturePayload)>; +} + +type PublicOf = < + >::CreateTransaction as CreateTransaction< + T, + >::Extrinsic, + > +>::Public; + +/// A trait to sign and submit transactions in offchain calls. +pub trait SubmitSignedTransaction +where + PublicOf: IdentifyAccount + Clone, +{ + /// 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< + PublicOf, + >::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, public: PublicOf) -> Result<(), ()> { + let call = call.into(); + let id = public.clone().into_account(); + let expected = >::account_nonce(&id); + let (call, signature_data) = Self::CreateTransaction + ::create_transaction::(call, public, 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<>::Public, >::Signature>, + E: ExtrinsicT + codec::Encode, + >::Public: IdentifyAccount + Clone, +{ + 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 78a741aff48a5516c6f683058ba832c146073384..2ab751088e8c7ad2a12b82e944cbaa2ba93bb47a 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 }; @@ -111,8 +111,8 @@ pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"timstap0"; pub type InherentType = u64; /// Errors that can occur while checking the timestamp inherent. -#[derive(Encode)] -#[cfg_attr(feature = "std", derive(Debug, Decode))] +#[derive(Encode, sr_primitives::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode))] pub enum InherentError { /// The timestamp is valid in the future. /// This is a non-fatal-error and will not stop checking the inherents. @@ -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); @@ -261,7 +244,7 @@ decl_module! { decl_storage! { trait Store for Module as Timestamp { /// Current time for the current block. - pub Now get(now) build(|_| 0.into()): T::Moment; + pub Now get(fn now) build(|_| 0.into()): T::Moment; /// Did the timestamp get updated in this block? DidUpdate: bool; @@ -338,8 +321,8 @@ impl Time for Module { mod tests { use super::*; - use srml_support::{impl_outer_origin, assert_ok, parameter_types}; - use runtime_io::{with_externalities, TestExternalities}; + use support::{impl_outer_origin, assert_ok, parameter_types}; + use runtime_io::TestExternalities; use primitives::H256; use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; @@ -365,7 +348,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -386,7 +368,7 @@ mod tests { #[test] fn timestamp_works() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + TestExternalities::new(t).execute_with(|| { Timestamp::set_timestamp(42); assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE)); assert_eq!(Timestamp::now(), 69); @@ -397,7 +379,7 @@ mod tests { #[should_panic(expected = "Timestamp must be updated only once in the block")] fn double_timestamp_should_fail() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + TestExternalities::new(t).execute_with(|| { Timestamp::set_timestamp(42); assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE)); let _ = Timestamp::dispatch(Call::set(70), Origin::NONE); @@ -408,7 +390,7 @@ mod tests { #[should_panic(expected = "Timestamp must increment by at least between sequential blocks")] fn block_period_minimum_enforced() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + TestExternalities::new(t).execute_with(|| { Timestamp::set_timestamp(42); let _ = Timestamp::dispatch(Call::set(46), Origin::NONE); }); diff --git a/srml/transaction-payment/Cargo.toml b/srml/transaction-payment/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..7f8eddab19d987b685212a2e4c4b2cb550b4de9b --- /dev/null +++ b/srml/transaction-payment/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "srml-transaction-payment" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +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 } +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" } +primitives = { package = "substrate-primitives", path = "../../core/primitives" } +balances = { package = "srml-balances", path = "../balances" } + +[features] +default = ["std"] +std = [ + "codec/std", + "rstd/std", + "sr-primitives/std", + "support/std", + "system/std", +] diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..5ad5c650af8a04e7e7bd35b2b99f47205801520d --- /dev/null +++ b/srml/transaction-payment/src/lib.rs @@ -0,0 +1,457 @@ +// 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 . + +//! # Transaction Payment Module +//! +//! This module provides the basic logic needed to pay the absolute minimum amount needed for a +//! transaction to be included. This includes: +//! - _weight fee_: A fee proportional to amount of weight a transaction consumes. +//! - _length fee_: A fee proportional to the encoded length of the transaction. +//! - _tip_: An optional tip. Tip increases the priority of the transaction, giving it a higher +//! chance to be included by the transaction queue. +//! +//! Additionally, this module allows one to configure: +//! - The mapping between one unit of weight to one unit of fee via [`WeightToFee`]. +//! - A means of updating the fee for the next block, via defining a multiplier, based on the +//! final state of the chain at the end of the previous block. This can be configured via +//! [`FeeMultiplierUpdate`] + +#![cfg_attr(not(feature = "std"), no_std)] + +use rstd::prelude::*; +use codec::{Encode, Decode}; +use support::{ + decl_storage, decl_module, + traits::{Currency, Get, OnUnbalanced, ExistenceRequirement, WithdrawReason}, +}; +use sr_primitives::{ + Fixed64, + transaction_validity::{ + TransactionPriority, ValidTransaction, InvalidTransaction, TransactionValidityError, + TransactionValidity, + }, + traits::{Zero, Saturating, SignedExtension, SaturatedConversion, Convert}, + weights::{Weight, DispatchInfo}, +}; + +type Multiplier = Fixed64; +type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = + <::Currency as Currency<::AccountId>>::NegativeImbalance; + +pub trait Trait: system::Trait { + /// The currency type in which fees will be paid. + type Currency: Currency; + + /// Handler for the unbalanced reduction when taking transaction fees. + type OnTransactionPayment: OnUnbalanced>; + + /// The fee to be paid for making a transaction; the base. + type TransactionBaseFee: Get>; + + /// The fee to be paid for making a transaction; the per-byte portion. + type TransactionByteFee: Get>; + + /// Convert a weight value into a deductible fee based on the currency type. + type WeightToFee: Convert>; + + /// Update the multiplier of the next block, based on the previous block's weight. + type FeeMultiplierUpdate: Convert; +} + +decl_storage! { + trait Store for Module as Balances { + NextFeeMultiplier get(fn next_fee_multiplier): Multiplier = Multiplier::from_parts(0); + } +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + /// The fee to be paid for making a transaction; the base. + const TransactionBaseFee: BalanceOf = T::TransactionBaseFee::get(); + + /// The fee to be paid for making a transaction; the per-byte portion. + const TransactionByteFee: BalanceOf = T::TransactionByteFee::get(); + + fn on_finalize() { + NextFeeMultiplier::mutate(|fm| { + *fm = T::FeeMultiplierUpdate::convert(*fm) + }); + } + } +} + +impl Module {} + +/// Require the transactor pay for themselves and maybe include a tip to gain additional priority +/// in the queue. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct ChargeTransactionPayment(#[codec(compact)] BalanceOf); + +impl ChargeTransactionPayment { + /// utility constructor. Used only in client/factory code. + pub fn from(fee: BalanceOf) -> Self { + Self(fee) + } + + /// Compute the final fee value for a particular transaction. + /// + /// The final fee is composed of: + /// - _length-fee_: This is the amount paid merely to pay for size of the transaction. + /// - _weight-fee_: This amount is computed based on the weight of the transaction. Unlike + /// size-fee, this is not input dependent and reflects the _complexity_ of the execution + /// and the time it consumes. + /// - (optional) _tip_: if included in the transaction, it will be added on top. Only signed + /// transactions can have a tip. + fn compute_fee(len: usize, info: DispatchInfo, tip: BalanceOf) -> BalanceOf { + let len_fee = if info.pay_length_fee() { + let len = >::from(len as u32); + let base = T::TransactionBaseFee::get(); + let per_byte = T::TransactionByteFee::get(); + base.saturating_add(per_byte.saturating_mul(len)) + } else { + Zero::zero() + }; + + let weight_fee = { + // cap the weight to the maximum defined in runtime, otherwise it will be the `Bounded` + // maximum of its data type, which is not desired. + let capped_weight = info.weight.min(::MaximumBlockWeight::get()); + T::WeightToFee::convert(capped_weight) + }; + + // everything except for tip + let basic_fee = len_fee.saturating_add(weight_fee); + let fee_update = NextFeeMultiplier::get(); + let adjusted_fee = fee_update.saturated_multiply_accumulate(basic_fee); + + adjusted_fee.saturating_add(tip) + } +} + +impl rstd::fmt::Debug for ChargeTransactionPayment { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + write!(f, "ChargeTransactionPayment<{:?}>", self.0) + } + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } +} + +impl SignedExtension for ChargeTransactionPayment + where BalanceOf: Send + Sync +{ + type AccountId = T::AccountId; + type Call = T::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 { + // pay any fees. + let fee = Self::compute_fee(len, info, self.0); + let imbalance = match T::Currency::withdraw( + who, + fee, + WithdrawReason::TransactionPayment, + ExistenceRequirement::KeepAlive, + ) { + Ok(imbalance) => imbalance, + Err(_) => return InvalidTransaction::Payment.into(), + }; + T::OnTransactionPayment::on_unbalanced(imbalance); + + let mut r = ValidTransaction::default(); + // NOTE: we probably want to maximize the _fee (of any type) per weight unit_ here, which + // will be a bit more than setting the priority to tip. For now, this is enough. + r.priority = fee.saturated_into::(); + Ok(r) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use support::{parameter_types, impl_outer_origin}; + use primitives::H256; + use sr_primitives::{ + Perbill, + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, + weights::DispatchClass, + }; + use rstd::cell::RefCell; + + const CALL: &::Call = &(); + + #[derive(Clone, PartialEq, Eq, Debug)] + pub struct Runtime; + + impl_outer_origin!{ + pub enum Origin for 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 Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + } + + parameter_types! { + pub const TransferFee: u64 = 0; + pub const CreationFee: u64 = 0; + pub const ExistentialDeposit: u64 = 0; + } + + impl balances::Trait for Runtime { + type Balance = u64; + type OnFreeBalanceZero = (); + type OnNewAccount = (); + type Event = (); + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + } + + thread_local! { + static TRANSACTION_BASE_FEE: RefCell = RefCell::new(0); + static TRANSACTION_BYTE_FEE: RefCell = RefCell::new(1); + static WEIGHT_TO_FEE: RefCell = RefCell::new(1); + } + + pub struct TransactionBaseFee; + impl Get for TransactionBaseFee { + fn get() -> u64 { TRANSACTION_BASE_FEE.with(|v| *v.borrow()) } + } + + pub struct TransactionByteFee; + impl Get for TransactionByteFee { + fn get() -> u64 { TRANSACTION_BYTE_FEE.with(|v| *v.borrow()) } + } + + pub struct WeightToFee(u64); + impl Convert for WeightToFee { + fn convert(t: Weight) -> u64 { + WEIGHT_TO_FEE.with(|v| *v.borrow() * (t as u64)) + } + } + + impl Trait for Runtime { + type Currency = balances::Module; + type OnTransactionPayment = (); + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = WeightToFee; + type FeeMultiplierUpdate = (); + } + + type Balances = balances::Module; + + pub struct ExtBuilder { + balance_factor: u64, + base_fee: u64, + byte_fee: u64, + weight_to_fee: u64 + } + + impl Default for ExtBuilder { + fn default() -> Self { + Self { + balance_factor: 1, + base_fee: 0, + byte_fee: 1, + weight_to_fee: 1, + } + } + } + + impl ExtBuilder { + pub fn fees(mut self, base: u64, byte: u64, weight: u64) -> Self { + self.base_fee = base; + self.byte_fee = byte; + self.weight_to_fee = weight; + self + } + pub fn balance_factor(mut self, factor: u64) -> Self { + self.balance_factor = factor; + self + } + fn set_constants(&self) { + TRANSACTION_BASE_FEE.with(|v| *v.borrow_mut() = self.base_fee); + TRANSACTION_BYTE_FEE.with(|v| *v.borrow_mut() = self.byte_fee); + WEIGHT_TO_FEE.with(|v| *v.borrow_mut() = self.weight_to_fee); + } + pub fn build(self) -> runtime_io::TestExternalities { + self.set_constants(); + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + 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![], + }.assimilate_storage(&mut t).unwrap(); + t.into() + } + } + + /// create a transaction info struct from weight. Handy to avoid building the whole struct. + pub fn info_from_weight(w: Weight) -> DispatchInfo { + DispatchInfo { weight: w, ..Default::default() } + } + + #[test] + fn signed_extension_transaction_payment_work() { + ExtBuilder::default() + .balance_factor(10) // 100 + .fees(5, 1, 1) // 5 fixed, 1 per byte, 1 per weight + .build() + .execute_with(|| + { + let len = 10; + assert!( + ChargeTransactionPayment::::from(0) + .pre_dispatch(&1, CALL, info_from_weight(5), len) + .is_ok() + ); + assert_eq!(Balances::free_balance(&1), 100 - 5 - 5 - 10); + + assert!( + ChargeTransactionPayment::::from(5 /* tipped */) + .pre_dispatch(&2, CALL, info_from_weight(3), len) + .is_ok() + ); + assert_eq!(Balances::free_balance(&2), 200 - 5 - 10 - 3 - 5); + }); + } + + #[test] + fn signed_extension_transaction_payment_is_bounded() { + ExtBuilder::default() + .balance_factor(1000) + .fees(0, 0, 1) + .build() + .execute_with(|| + { + use sr_primitives::weights::Weight; + + // maximum weight possible + assert!( + ChargeTransactionPayment::::from(0) + .pre_dispatch(&1, CALL, info_from_weight(Weight::max_value()), 10) + .is_ok() + ); + // fee will be proportional to what is the actual maximum weight in the runtime. + assert_eq!( + Balances::free_balance(&1), + (10000 - ::MaximumBlockWeight::get()) as u64 + ); + }); + } + + #[test] + fn signed_extension_allows_free_transactions() { + ExtBuilder::default() + .fees(100, 1, 1) + .balance_factor(0) + .build() + .execute_with(|| + { + // 1 ain't have a penny. + assert_eq!(Balances::free_balance(&1), 0); + + // like a FreeOperational + let operational_transaction = DispatchInfo { + weight: 0, + class: DispatchClass::Operational + }; + let len = 100; + assert!( + ChargeTransactionPayment::::from(0) + .validate(&1, CALL, operational_transaction , len) + .is_ok() + ); + + // like a FreeNormal + let free_transaction = DispatchInfo { + weight: 0, + class: DispatchClass::Normal + }; + assert!( + ChargeTransactionPayment::::from(0) + .validate(&1, CALL, free_transaction , len) + .is_err() + ); + }); + } + + #[test] + fn signed_ext_length_fee_is_also_updated_per_congestion() { + ExtBuilder::default() + .fees(5, 1, 1) + .balance_factor(10) + .build() + .execute_with(|| + { + // all fees should be x1.5 + NextFeeMultiplier::put(Fixed64::from_rational(1, 2)); + let len = 10; + + assert!( + ChargeTransactionPayment::::from(10) // tipped + .pre_dispatch(&1, CALL, info_from_weight(3), len) + .is_ok() + ); + assert_eq!(Balances::free_balance(&1), 100 - 10 - (5 + 10 + 3) * 3 / 2); + }) + } +} + + 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 12ef4fc14e2b137ad493495673663a5dab870011..48b56e438ed42a086d10001727e94ae9e58c60d6 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, Saturating }; 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. @@ -218,8 +213,8 @@ decl_module! { } /// A spending proposal. -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -#[derive(Encode, Decode, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, sr_primitives::RuntimeDebug)] pub struct Proposal { proposer: AccountId, value: Balance, @@ -230,13 +225,22 @@ pub struct Proposal { decl_storage! { trait Store for Module as Treasury { /// Number of proposals that have been made. - ProposalCount get(proposal_count): ProposalIndex; + ProposalCount get(fn proposal_count): ProposalIndex; /// Proposals that have been made. - Proposals get(proposals): map ProposalIndex => Option>>; + Proposals get(fn proposals): map ProposalIndex => Option>>; /// Proposal indices that have been approved but not yet awarded. - Approvals get(approvals): Vec; + Approvals get(fn approvals): Vec; + } + add_extra_genesis { + build(|_config| { + // Create Treasury account + let _ = T::Currency::make_free_balance_be( + &>::account_id(), + T::Currency::minimum_balance(), + ); + }); } } @@ -316,6 +320,10 @@ impl Module { Self::deposit_event(RawEvent::Burnt(burn)) } + // Must never be an error, but better to be safe. + // proof: budget_remaining is account free balance minus ED; + // Thus we can't spend more than account free balance minus ED; + // Thus account is kept alive; qed; if let Err(problem) = T::Currency::settle( &Self::account_id(), imbalance, @@ -330,28 +338,38 @@ impl Module { Self::deposit_event(RawEvent::Rollover(budget_remaining)); } + /// Return the amount of money in the pot. + // The existential deposit is not part of the pot so treasury account never gets deleted. fn pot() -> BalanceOf { T::Currency::free_balance(&Self::account_id()) + // Must never be less than 0 but better be safe. + .saturating_sub(T::Currency::minimum_balance()) } } impl OnUnbalanced> for Module { fn on_unbalanced(amount: NegativeImbalanceOf) { - T::Currency::resolve_creating(&Self::account_id(), amount); + // Must resolve into existing but better to be safe. + let _ = T::Currency::resolve_creating(&Self::account_id(), amount); } } +/// Mint extra funds for the treasury to keep the ratio of portion to total_issuance equal +/// pre dilution and post-dilution. +/// +/// i.e. +/// ```nocompile +/// portion / total_issuance_before_dilution == +/// (portion + minted) / (total_issuance_before_dilution + minted_to_treasury + minted) +/// ``` impl OnDilution> for Module { fn on_dilution(minted: BalanceOf, portion: BalanceOf) { - // Mint extra funds for the treasury to keep the ratio of portion to total_issuance equal - // pre dilution and post-dilution. 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)); } } } @@ -361,10 +379,11 @@ impl OnDilution> for Module { mod tests { use super::*; - use runtime_io::with_externalities; - use srml_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 support::{assert_noop, assert_ok, impl_outer_origin, parameter_types}; + use primitives::H256; + use sr_primitives::{ + traits::{BlakeTwo256, OnFinalize, IdentityLookup}, testing::Header, assert_eq_error_rate, + }; impl_outer_origin! { pub enum Origin for Test {} @@ -388,7 +407,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -397,26 +415,20 @@ mod tests { type Version = (); } parameter_types! { - pub const ExistentialDeposit: u64 = 0; + 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 = (); - 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 ProposalBond: Permill = Permill::from_percent(5); @@ -439,18 +451,20 @@ mod tests { type Balances = balances::Module; type Treasury = Module; - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); balances::GenesisConfig::{ - balances: vec![(0, 100), (1, 99), (2, 1)], + // Total issuance will be 200 with treasury account initialized at ED. + balances: vec![(0, 100), (1, 98), (2, 1)], vesting: vec![], }.assimilate_storage(&mut t).unwrap(); + GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); t.into() } #[test] fn genesis_config_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Treasury::pot(), 0); assert_eq!(Treasury::proposal_count(), 0); }); @@ -458,16 +472,42 @@ mod tests { #[test] fn minting_works() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // Check that accumulate works when we have Some value in Dummy already. Treasury::on_dilution(100, 100); assert_eq!(Treasury::pot(), 100); }); } + #[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 { + new_test_ext().execute_with(|| { + 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(), || { + new_test_ext().execute_with(|| { assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); assert_eq!(Balances::free_balance(&0), 99); assert_eq!(Balances::reserved_balance(&0), 1); @@ -476,7 +516,7 @@ mod tests { #[test] fn spend_proposal_takes_proportional_deposit() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); assert_eq!(Balances::free_balance(&0), 95); assert_eq!(Balances::reserved_balance(&0), 5); @@ -485,14 +525,14 @@ mod tests { #[test] fn spend_proposal_fails_when_proposer_poor() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!(Treasury::propose_spend(Origin::signed(2), 100, 3), "Proposer's balance too low"); }); } #[test] fn accepted_spend_proposal_ignored_outside_spend_period() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { Treasury::on_dilution(100, 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); @@ -506,7 +546,7 @@ mod tests { #[test] fn unused_pot_should_diminish() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let init_total_issuance = Balances::total_issuance(); Treasury::on_dilution(100, 100); assert_eq!(Balances::total_issuance(), init_total_issuance + 100); @@ -519,7 +559,7 @@ mod tests { #[test] fn rejected_spend_proposal_ignored_on_spend_period() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { Treasury::on_dilution(100, 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); @@ -533,7 +573,7 @@ mod tests { #[test] fn reject_already_rejected_spend_proposal_fails() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { Treasury::on_dilution(100, 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); @@ -544,21 +584,21 @@ mod tests { #[test] fn reject_non_existant_spend_proposal_fails() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), "No proposal at that index"); }); } #[test] fn accept_non_existant_spend_proposal_fails() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), "No proposal at that index"); }); } #[test] fn accept_already_rejected_spend_proposal_fails() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { Treasury::on_dilution(100, 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); @@ -569,7 +609,7 @@ mod tests { #[test] fn accepted_spend_proposal_enacted_on_spend_period() { - with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { Treasury::on_dilution(100, 100); assert_eq!(Treasury::pot(), 100); @@ -583,51 +623,80 @@ 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 + fn pot_underflow_should_not_diminish() { + new_test_ext().execute_with(|| { + Treasury::on_dilution(100, 100); + assert_eq!(Treasury::pot(), 100); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 150, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); + + >::on_finalize(2); + assert_eq!(Treasury::pot(), 100); // Pot hasn't changed + + Treasury::on_dilution(100, 100); + >::on_finalize(4); + assert_eq!(Balances::free_balance(&3), 150); // Fund has been spent + assert_eq!(Treasury::pot(), 75); // Pot has finally changed }); } + // Treasury account doesn't get deleted if amount approved to spend is all its free balance. + // i.e. pot should not include existential deposit needed for account survival. #[test] - fn pot_underflow_should_not_diminish() { - with_externalities(&mut new_test_ext(), || { + fn treasury_account_doesnt_get_deleted() { + new_test_ext().execute_with(|| { Treasury::on_dilution(100, 100); + assert_eq!(Treasury::pot(), 100); + let treasury_balance = Balances::free_balance(&Treasury::account_id()); - assert_ok!(Treasury::propose_spend(Origin::signed(0), 150, 3)); + assert_ok!(Treasury::propose_spend(Origin::signed(0), treasury_balance, 3)); assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); >::on_finalize(2); - assert_eq!(Treasury::pot(), 100); + assert_eq!(Treasury::pot(), 100); // Pot hasn't changed + + assert_ok!(Treasury::propose_spend(Origin::signed(0), Treasury::pot(), 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 1)); + + >::on_finalize(4); + assert_eq!(Treasury::pot(), 0); // Pot is emptied + assert_eq!(Balances::free_balance(&Treasury::account_id()), 1); // but the account is still there + }); + } + + // In case treasury account is not existing then it works fine. + // This is usefull for chain that will just update runtime. + #[test] + fn inexisting_account_works() { + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + balances::GenesisConfig::{ + balances: vec![(0, 100), (1, 99), (2, 1)], + vesting: vec![], + }.assimilate_storage(&mut t).unwrap(); + // Treasury genesis config is not build thus treasury account does not exist + let mut t: runtime_io::TestExternalities = t.into(); + + t.execute_with(|| { + assert_eq!(Balances::free_balance(&Treasury::account_id()), 0); // Account does not exist + assert_eq!(Treasury::pot(), 0); // Pot is empty + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 99, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); + assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 1)); + >::on_finalize(2); + assert_eq!(Treasury::pot(), 0); // Pot hasn't changed + assert_eq!(Balances::free_balance(&3), 0); // Balance of `3` hasn't changed Treasury::on_dilution(100, 100); + assert_eq!(Treasury::pot(), 99); // Pot now contains funds + assert_eq!(Balances::free_balance(&Treasury::account_id()), 100); // Account does exist + >::on_finalize(4); - assert_eq!(Balances::free_balance(&3), 150); - assert_eq!(Treasury::pot(), 75); + + assert_eq!(Treasury::pot(), 0); // Pot has changed + assert_eq!(Balances::free_balance(&3), 99); // Balance of `3` has changed }); } } diff --git a/srml/utility/Cargo.toml b/srml/utility/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..5e92bcf88ad4860ce0ddeed6172d05c6aa87f7ac --- /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.101", 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..d69e260ff9aac4f7b25c8b1923ff238e28456c7a --- /dev/null +++ b/srml/utility/src/lib.rs @@ -0,0 +1,158 @@ +// 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 primitives::H256; + 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 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; + } + impl balances::Trait for Test { + type Balance = u64; + type OnFreeBalanceZero = (); + type OnNewAccount = (); + type Event = (); + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + } + 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() { + new_test_ext().execute_with(|| { + 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..e1c3ef64d26d410e12794c03679486735567cb3c 100644 --- a/subkey/Cargo.toml +++ b/subkey/Cargo.toml @@ -9,16 +9,17 @@ 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.33.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" } +transaction-payment = { package = "srml-transaction-payment", path = "../srml/transaction-payment" } [features] bench = [] 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..5d8cd11b1e6f8def2ff8a4dfb3ae877e6f8d6057 100644 --- a/subkey/src/cli.yml +++ b/subkey/src/cli.yml @@ -12,6 +12,11 @@ args: long: sr25519 help: Use Schnorr/Ristretto x25519/BIP39 cryptography takes_value: false + - secp256k1: + short: k + long: secp256k1 + help: Use SECP256k1/ECDSA/BIP39 cryptography + takes_value: false - password: short: p long: password @@ -23,7 +28,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 ba9d1a6cce0591ea0202b994419c0cc317615a69..1b537580f57ff739f41c9a552ebbfd28bac7161c 100644 --- a/subkey/src/main.rs +++ b/subkey/src/main.rs @@ -18,54 +18,86 @@ #[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, AccountId, Signature}; +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, ecdsa, Pair, Public, H256, hexdisplay::HexDisplay, +}; +use sr_primitives::{traits::{IdentifyAccount, Verify}, generic::Era}; +use std::{ + convert::{TryInto, TryFrom}, + io::{stdin, Read}, + str::FromStr, }; -use codec::{Encode, Decode}; -use sr_primitives::generic::Era; -use node_primitives::{Balance, Index, Hash}; -use node_runtime::{Call, UncheckedExtrinsic, BalancesCall, Runtime}; 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 where + ::Public: PublicT, + { + pair.public().into_runtime().into_account().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 \ + Account ID: {}\n \ + SS58 Address: {}", uri, - HexDisplay::from(&seed.as_ref()), - HexDisplay::from(&Self::public_from_pair(&pair)), + format_seed::(seed), + format_public_key::(public_key.clone()), + format_account_id::(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): {}", + } else if let Ok((pair, seed)) = Self::Pair::from_string_with_seed(uri, password) { + let public_key = Self::public_from_pair(&pair); + println!("Secret Key URI `{}` is account:\n \ + Secret seed: {}\n \ + Public key (hex): {}\n \ + Account ID: {}\n \ + SS58 Address: {}", uri, - HexDisplay::from(&Self::public_from_pair(&pair)), + if let Some(seed) = seed { format_seed::(seed) } else { "n/a".into() }, + format_public_key::(public_key.clone()), + format_account_id::(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 \ + Account ID: {}\n \ + SS58 Address: {}", uri, String::from(v), - HexDisplay::from(&public.as_ref()), - public.to_ss58check_with_version(v) + format_public_key::(public_key.clone()), + format_account_id::(public_key.clone()), + public_key.to_ss58check_with_version(v) ); } else { println!("Invalid phrase/URI given"); @@ -91,216 +123,405 @@ 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, +struct Ecdsa; + +impl Crypto for Ecdsa { + type Pair = ecdsa::Pair; + type Public = ecdsa::Public; +} + +type SignatureOf = <::Pair as Pair>::Signature; +type PublicOf = <::Pair as Pair>::Public; +type SeedOf = <::Pair as Pair>::Seed; +type AccountPublic = ::Signer; + +trait SignatureT: AsRef<[u8]> + AsMut<[u8]> + Default { + /// Converts the signature into a runtime account signature, if possible. If not possible, bombs out. + fn into_runtime(self) -> Signature { + panic!("This cryptography isn't supported for this runtime.") + } +} +trait PublicT: Sized + AsRef<[u8]> + Ss58Codec { + /// Converts the public key into a runtime account public key, if possible. If not possible, bombs out. + fn into_runtime(self) -> AccountPublic { + panic!("This cryptography isn't supported for this runtime.") + } +} + +impl SignatureT for sr25519::Signature { fn into_runtime(self) -> Signature { self.into() } } +impl SignatureT for ed25519::Signature { fn into_runtime(self) -> Signature { self.into() } } +impl SignatureT for ecdsa::Signature { fn into_runtime(self) -> Signature { self.into() } } +impl PublicT for sr25519::Public { fn into_runtime(self) -> AccountPublic { self.into() } } +impl PublicT for ed25519::Public { fn into_runtime(self) -> AccountPublic { self.into() } } +impl PublicT for ecdsa::Public { fn into_runtime(self) -> AccountPublic { self.into() } } + +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") { + return execute::(matches) + } + if matches.is_present("secp256k1") { + return execute::(matches) + } + return execute::(matches) +} + +fn execute(matches: ArgMatches) +where + SignatureOf: SignatureT, + PublicOf: PublicT, { - 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), - ) - }; 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); + 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 'index' 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: AccountId = read_account_id(matches.value_of("to")); + 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"), - }; - - println!("Using a genesis hash of {}", HexDisplay::from(&genesis_hash.as_ref())); + let extrinsic = create_extrinsic::(function, index, signer, genesis_hash); - 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 'nonce' 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) -> bool +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let signature = read_signature::(matches); + let pubkey = read_public_key::(matches.value_of("uri")); + <::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>) -> PublicOf where + 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 { + uri + }; + if let Ok(pubkey_vec) = hex::decode(uri) { + ::Public::from_slice(pubkey_vec.as_slice()) + } else { + ::Public::from_string(uri) + .ok() + .expect("Invalid URI; expecting either a secret URI or a public URI.") + } +} + +fn read_account_id(matched_uri: Option<&str>) -> AccountId { + 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 { + uri + }; + if let Ok(data_vec) = hex::decode(uri) { + AccountId::try_from(data_vec.as_slice()) + .expect("Invalid hex length for account ID; should be 32 bytes") } else { - execute::(matches) + AccountId::from_ss58check(uri).ok() + .expect("Invalid SS58-check address given for account ID.") } } -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 format_account_id(public_key: PublicOf) -> String where + PublicOf: PublicT, +{ + format!("0x{}", HexDisplay::from(&public_key.into_runtime().into_account().as_ref())) +} + +fn create_extrinsic( + function: Call, + index: Index, + signer: C::Pair, + genesis_hash: H256, +) -> UncheckedExtrinsic where + PublicOf: PublicT, + SignatureOf: SignatureT, +{ + let extra = |i: Index, f: Balance| { + ( + system::CheckVersion::::new(), + system::CheckGenesis::::new(), + system::CheckEra::::from(Era::Immortal), + system::CheckNonce::::from(i), + system::CheckWeight::::new(), + transaction_payment::ChargeTransactionPayment::::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)).into_runtime(); + let signer = signer.public().into_runtime(); + let (function, extra, _) = raw_payload.deconstruct(); + + UncheckedExtrinsic::new_signed( + function, + signer.into_account().into(), + signature, + 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)); + } + + #[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..835001a0aa9d0d4dd82b7e719a91f907cce4f495 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 super::{PublicOf, PublicT, 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; + } } } } @@ -57,7 +62,9 @@ fn calculate_score(_desired: &str, key: &str) -> usize { 0 } -pub(super) fn generate_key(desired: &str) -> Result, &str> { +pub(super) fn generate_key(desired: &str) -> Result, &str> where + PublicOf: PublicT, +{ if desired.is_empty() { return Err("Pattern must not be empty"); } @@ -71,7 +78,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 +108,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 +132,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..324d33cbf0da73676320d0548d81ea4dd8184179 100644 --- a/test-utils/chain-spec-builder/Cargo.toml +++ b/test-utils/chain-spec-builder/Cargo.toml @@ -5,7 +5,9 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -clap = { version = "~2.32", features = ["yaml"] } +ansi_term = "0.12.1" +keystore = { package = "substrate-keystore", path = "../../core/keystore" } node-cli = { path = "../../node/cli" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } -substrate-service = { path = "../../core/service" } +rand = "0.7.2" +structopt = "0.3.3" diff --git a/test-utils/chain-spec-builder/src/cli.yml b/test-utils/chain-spec-builder/src/cli.yml deleted file mode 100644 index f4b1cb7e2eaaab0e5d2df01a6801d36a3de527b8..0000000000000000000000000000000000000000 --- a/test-utils/chain-spec-builder/src/cli.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: chain-spec-builder -author: "azban " -about: Utility for creating chain specs primarily for testing -args: -- initial_authority_seed: - short: a - value_name: INITIAL_AUTHORITY_SEED - help: Initial authority seed - takes_value: true - multiple: true - required: true -- endowed_account_seed: - short: e - value_name: ENDOWED_ACCOUNT_SEED - help: Endowed account seed - takes_value: true - multiple: true - required: true -- sudo_key_seed: - short: u - value_name: SUDO_KEY_SEED - help: Sudo key seed - takes_value: true - required: true diff --git a/test-utils/chain-spec-builder/src/main.rs b/test-utils/chain-spec-builder/src/main.rs index 13b4cc38a16463f3166f18fef09a482e8ffb52db..8fdd282345bc07fc15132ea25cf85e2b87c9218f 100644 --- a/test-utils/chain-spec-builder/src/main.rs +++ b/test-utils/chain-spec-builder/src/main.rs @@ -1,49 +1,261 @@ -use clap::{App, load_yaml}; +// 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 std::{fs, path::{Path, PathBuf}}; + +use ansi_term::Style; +use rand::{Rng, distributions::Alphanumeric, rngs::OsRng}; +use structopt::StructOpt; + +use keystore::{Store as Keystore}; use node_cli::chain_spec::{self, AccountId}; -use substrate_service::chain_ops::build_spec; +use primitives::{sr25519, crypto::{Public, Ss58Codec}, traits::BareCryptoStore}; -fn genesis_constructor() -> chain_spec::GenesisConfig { - let yaml = load_yaml!("./cli.yml"); - let matches = App::from_yaml(yaml).get_matches(); - let authorities = matches.values_of("initial_authority_seed") - .unwrap() - .map(chain_spec::get_authority_keys_from_seed) - .collect(); +/// A utility to easily create a testnet chain spec definition with a given set +/// of authorities and endowed accounts and/or generate random accounts. +#[derive(StructOpt)] +#[structopt(rename_all = "kebab-case")] +enum ChainSpecBuilder { + /// Create a new chain spec with the given authorities, endowed and sudo + /// accounts. + New { + /// Authority key seed. + #[structopt(long, short, required = true)] + authority_seeds: Vec, + /// Endowed account address (SS58 format). + #[structopt(long, short)] + endowed_accounts: Vec, + /// Sudo account address (SS58 format). + #[structopt(long, short)] + sudo_account: String, + /// The path where the chain spec should be saved. + #[structopt(long, short, default_value = "./chain_spec.json")] + chain_spec_path: PathBuf, + }, + /// Create a new chain spec with the given number of authorities and endowed + /// accounts. Random keys will be generated as required. + Generate { + /// The number of authorities. + #[structopt(long, short)] + authorities: usize, + /// The number of endowed accounts. + #[structopt(long, short, default_value = "0")] + endowed: usize, + /// The path where the chain spec should be saved. + #[structopt(long, short, default_value = "./chain_spec.json")] + chain_spec_path: PathBuf, + /// Path to use when saving generated keystores for each authority. + /// + /// At this path, a new folder will be created for each authority's + /// keystore named `auth-$i` where `i` is the authority index, i.e. + /// `auth-0`, `auth-1`, etc. + #[structopt(long, short)] + keystore_path: Option, + }, +} - let endowed_accounts = matches.values_of("endowed_account_seed") - .unwrap() - .map(chain_spec::get_from_seed::) - .collect(); +impl ChainSpecBuilder { + /// Returns the path where the chain spec should be saved. + fn chain_spec_path(&self) -> &Path { + match self { + ChainSpecBuilder::New { chain_spec_path, .. } => + chain_spec_path.as_path(), + ChainSpecBuilder::Generate { chain_spec_path, .. } => + chain_spec_path.as_path(), + } + } +} - let sudo_key_seed = matches.value_of("sudo_key_seed").unwrap(); - let sudo_key = chain_spec::get_from_seed::(sudo_key_seed); +fn genesis_constructor( + authority_seeds: &[String], + endowed_accounts: &[AccountId], + sudo_account: &AccountId, +) -> chain_spec::GenesisConfig { + let authorities = authority_seeds + .iter() + .map(AsRef::as_ref) + .map(chain_spec::get_authority_keys_from_seed) + .collect::>(); let enable_println = true; chain_spec::testnet_genesis( authorities, - sudo_key.into(), - Some(endowed_accounts), + sudo_account.clone(), + Some(endowed_accounts.to_vec()), enable_println, ) } -fn generate_chain_spec() -> String { +fn generate_chain_spec( + authority_seeds: Vec, + endowed_accounts: Vec, + sudo_account: String, +) -> Result { + let parse_account = |address: &String| { + AccountId::from_string(address) + .map_err(|err| format!("Failed to parse account address: {:?}", err)) + }; + + let endowed_accounts = endowed_accounts + .iter() + .map(parse_account) + .collect::, String>>()?; + + let sudo_account = parse_account(&sudo_account)?; + let chain_spec = chain_spec::ChainSpec::from_genesis( "Custom", "custom", - genesis_constructor, + move || genesis_constructor(&authority_seeds, &endowed_accounts, &sudo_account), vec![], None, None, None, - None, + Default::default(), ); - build_spec(chain_spec, false).unwrap() + + chain_spec.to_json(false).map_err(|err| err.to_string()) } -fn main() { - let json = generate_chain_spec(); - println!("{}", json); +fn generate_authority_keys_and_store( + seeds: &[String], + keystore_path: &Path, +) -> Result<(), String> { + for (n, seed) in seeds.into_iter().enumerate() { + let keystore = Keystore::open( + keystore_path.join(format!("auth-{}", n)), + None, + ).map_err(|err| err.to_string())?; + + let (_, _, grandpa, babe, im_online) = + chain_spec::get_authority_keys_from_seed(seed); + + let insert_key = |key_type, public| { + keystore.write().insert_unknown( + key_type, + &format!("//{}", seed), + public, + ).map_err(|_| format!("Failed to insert key: {}", grandpa)) + }; + + insert_key( + primitives::crypto::key_types::BABE, + babe.as_slice(), + )?; + + insert_key( + primitives::crypto::key_types::GRANDPA, + grandpa.as_slice(), + )?; + + insert_key( + primitives::crypto::key_types::IM_ONLINE, + im_online.as_slice(), + )?; + } + + Ok(()) +} + +fn print_seeds( + authority_seeds: &[String], + endowed_seeds: &[String], + sudo_seed: &str, +) { + let header = Style::new().bold().underline(); + let entry = Style::new().bold(); + + println!("{}", header.paint("Authority seeds")); + + for (n, seed) in authority_seeds.iter().enumerate() { + println!("{} //{}", + entry.paint(format!("auth-{}:", n)), + seed, + ); + } + + println!(); + + if !endowed_seeds.is_empty() { + println!("{}", header.paint("Endowed seeds")); + for (n, seed) in endowed_seeds.iter().enumerate() { + println!("{} //{}", + entry.paint(format!("endowed-{}:", n)), + seed, + ); + } + + println!(); + } + + println!("{}", header.paint("Sudo seed")); + println!("//{}", sudo_seed); +} + +fn main() -> Result<(), String> { + let builder = ChainSpecBuilder::from_args(); + let chain_spec_path = builder.chain_spec_path().to_path_buf(); + + let (authority_seeds, endowed_accounts, sudo_account) = match builder { + ChainSpecBuilder::Generate { authorities, endowed, keystore_path, .. } => { + let authorities = authorities.max(1); + let rand_str = || -> String { + OsRng.sample_iter(&Alphanumeric) + .take(32) + .collect() + }; + + let authority_seeds = (0..authorities).map(|_| rand_str()).collect::>(); + let endowed_seeds = (0..endowed).map(|_| rand_str()).collect::>(); + let sudo_seed = rand_str(); + + print_seeds( + &authority_seeds, + &endowed_seeds, + &sudo_seed, + ); + + if let Some(keystore_path) = keystore_path { + generate_authority_keys_and_store( + &authority_seeds, + &keystore_path, + )?; + } + + let endowed_accounts = endowed_seeds.iter().map(|seed| { + chain_spec::get_account_id_from_seed::(seed) + .to_ss58check() + }).collect(); + + let sudo_account = chain_spec::get_account_id_from_seed::(&sudo_seed) + .to_ss58check(); + + (authority_seeds, endowed_accounts, sudo_account) + }, + ChainSpecBuilder::New { authority_seeds, endowed_accounts, sudo_account, .. } => { + (authority_seeds, endowed_accounts, sudo_account) + }, + }; + + let json = generate_chain_spec( + authority_seeds, + endowed_accounts, + sudo_account, + )?; + + fs::write(chain_spec_path, json).map_err(|err| err.to_string()) } 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 85b12248d80ba636fe0a4a859d1ebb7fd51c9182..ed76a66b09083e72ad9f8a19bdec4a5610db14aa 100644 --- a/test-utils/transaction-factory/src/complex_mode.rs +++ b/test-utils/transaction-factory/src/complex_mode.rs @@ -41,29 +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(); @@ -102,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 16bb08a2b436d154c4377cdbd4b8febd88424f8f..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; @@ -95,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, { @@ -112,20 +113,16 @@ 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, @@ -133,7 +130,7 @@ where best_hash.into(), best_block_id, ), - _ => simple_modes::next::( + _ => simple_modes::next::( &mut factory_state, &client, version, @@ -143,7 +140,8 @@ where ), } { 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()); } @@ -152,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"); @@ -177,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 ec4f484fa98271c8fec20570dd0b22a0481124f0..bcbb91200657f2a0bd33031f9df021cd911299e5 100644 --- a/test-utils/transaction-factory/src/simple_modes.rs +++ b/test-utils/transaction-factory/src/simple_modes.rs @@ -36,29 +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() { @@ -93,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());